Good afternoon,
I have a new small, but I think important, question. I did not find a concrete answer on this forum.
The question concerns the correct switching of buffers in the continuous reception mode with EasyDMA Array List mode.
For example.
I have data reception from the sensor via the I2C bus. The data comes with a frequency of 250 Hz. For processing it is convenient for me to use a frame of 25 samples.
For this I do the following:
1. I initialize the modules: I2C, PPI, GPIOTE, TIMER (Counter);
2. I configure the short-circuits and PPIs so that the readiness of the data starts the process of reading the sensor (I2C_WRITE -> I2C_READ -> I2C_STOP);
3. After each STOP event, the timer is incremented (PPI->Task = Timer Task Count);
4. When the value reaches 25, the interrupt of the timer starts (Timer Channel compare) , in which I switch to the next buffer.
So, now i do next:
void EventCounter_IRQHandler(void)
{
BaseType_t xHigherPriorityTaskWoken;
static TaskNotification_t NotifyEvent;
static uint8_t used_buffer_num = 0;
// Clear event
EventCounter->EVENTS_COMPARE[0] = 0;
volatile uint32_t dummy = EventCounter->EVENTS_COMPARE[0];
(void)dummy;
// Save fully buffer num
NotifyEvent.flags.ArrayNum = used_buffer_num&(PGG_IN_FRAME_MAX_NUM-1);
// Switch to next
used_buffer_num++;
used_buffer_num &= (PGG_IN_FRAME_MAX_NUM-1);
// Set next buffer
PPG_TWIM->RXD.PTR = (uint32_t)&PpgDataFrame[used_buffer_num];
NotifyEvent.flags.fFrameReady = true;
// Send Task Notification
xTaskNotifyFromISR(hPpgControl, NotifyEvent.Value, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
But I think that this is not entirely correct. Because the interrupt can be delayed for some reason and I just do not have time to switch the buffer. In this case, the new count will be written to the next memory location. Which will lead to fatal consequences.
How to properly protect yourself in this case?