Interrupt Handling and a Task

Assuming you have a steady stream of data coming in via DMA, and you want to process it in chunks. The DMA’s half-transfer-complete interrupt is perfect for this.

I am a big fan of task notifications, especially using eSetBits. It would look something like this (starting from your pseudocode just to illustrate eSetBits):

#define BUF_ITEM_COUNT 10
uint16_t Dbuf[BUF_ITEM_COUNT * 2];

#define BUFFER_A  (Dbuf)
#define BUFFER_B  (Dbuf + BUF_ITEM_COUNT)

#define NOTIFICATION_FLAG_BUFFER_A_READY (1UL << 0)
#define NOTIFICATION_FLAG_BUFFER_B_READY (1UL << 1)

static TaskHandle_t consumerThreadHandle;

void DMAz_StreamX_IRQHandler(void)
{
	uint32_t notificationFlags = 0UL;
	
	if (DMA_IsActiveFlag_TCy(DMAz)) {
		DMA_ClearFlag_TCy(DMAz);

		// We know here that the second half of the
		// DMA transfer has been complete
		
		notificationFlags |= NOTIFICATION_FLAG_BUFFER_B_READY;
	}
	if (DMA_IsActiveFlag_HTy(DMAz)) {
		DMA_ClearFlag_HTy(DMAz);

		// We know here that the first half of the 
		// DMA transfer has been complete

		notificationFlags |= NOTIFICATION_FLAG_BUFFER_A_READY;
	}
	
	BaseType_t wasHigherPriorityTaskWoken = pdFALSE;
	xTaskNotifyFromISR(consumerThreadHandle, notificationFlags, eSetBits, &wasHigherPriorityTaskWoken);
	portYIELD_FROM_ISR(wasHigherPriorityTaskWoken);
}

void consumer_thread()
{
	uint32_t notificationValue;

	while (1) {
		// access buf1 or buf2,
		// depending on buf_flag, choose access to the relevant buffer
		//
		// Just that we should not Read the buffer to which DMA is writing
		// We will need to sleep, in case the buffer is not yet ready
		//
		// The idea is that the consumption rate is higher
		// than the producer rate. Which is easy with additional sleep
		// for the consumer.
		
		xTaskNotifyWait(0, ULONG_MAX, &notificationValue, portMAX_DELAY);
		if (notificationValue & NOTIFICATION_FLAG_BUFFER_A_READY) {
			consumeBuffer(BUFFER_A);
		}
		if (notificationValue & NOTIFICATION_FLAG_BUFFER_B_READY) {
			consumeBuffer(BUFFER_B);
		}
	}
}

As others suggested you would still want to add code to verify you are meeting your real-time deadlines. If you get behind, you might end up processing buffer ‘A’ while the DMA is filling buffer ‘A’, which of course is no good.

1 Like