I have an adc that reads values on an interrupt and stores them in a FIFO.
In the main programm I wanted to read the whole FIFO just like a regular array and do FFT and stuff. After a little bit of thinking I realized that the interrupt could occur during the reading process and that the data wouldn't be accurate anymore.
Can this be done without disabling the interrupt ?
I only found examples for push,pop FIFOs and although I could use one, I guess, I wanted to know if this is possible.
Here is my code:
#define SP_FIFO_SIZE 4096
#define SP_BITMASK_SIZE (SP_FIFO_SIZE - 1)
struct sp_fifo_struct{
uint16_t array[SP_FIFO_SIZE];
uint16_t pointer;
};
typedef volatile struct sp_fifo_struct sp_fifo;
void sp_fifo_push(sp_fifo * fifo, uint16_t value){
fifo->array[fifo->pointer] = value;
fifo->pointer = ((fifo->pointer + 1) & SP_BITMASK_SIZE);
}
void sp_fifo_read(sp_fifo * fifo, float32_t array[]){
for(uint16_t i = 0; i < SP_FIFO_SIZE; i++){
array[i] = (float32_t) fifo->array[((fifo->pointer + i) & SP_BITMASK_SIZE)];
}
}
You certainly need to mutex lock your fifo in this instance. This isn't the case only when you can guarantee atomic reads/writes of the data into the queue. Additionally, incrementing/decrementing your indexing variable may or may not be atomic depending on your hardware platform and datatype.
As far as the data processing, I don't know the format of your data, so it's hard to say. I assume you have fixed length data. If that's the case, your fifo could be a queue of structs (definition of your fixed length data) instead of individual bytes. This would ensure that read/writes of the queue are "atomic" in the sense that you are always grabbing one "data point" (however you define that).