Microchip® Advanced Software Framework

Receiving using the FreeRTOS SPI driver in fully

asynchronous mode

This example demonstrates using the FreeRTOS SPI driver to receive data using the fully asynchronous operation mode. See Initializing the FreeRTOS SPI driver

The example below implements a function that continuously processes previously received data while more data is being received.

This is a comprehensive quick start example and is intended for advanced users. It demonstrates the power and efficiency of the fully asynchronous API.

Refer to the FreeRTOS peripheral control projects in the Atmel ASF distribution for complete working examples, and the FreeRTOS web site for information on getting started with FreeRTOS.

// This examples assumes freertos_spi has already been set by a successful
// call to freertos_spi_master_init(), and that freertos_spi_master_init()
// configured the FreeRTOS SPI driver to use the fully asynchronous operation
// mode.
// This example demonstrates how a single task can process data while
// additional data is being received on the SPI bus. Error checking is
// omitted to simplify the example.
void a_function(freertos_spi_if freertos_spi)
{
// The buffers into which the data is placed are too large to be declared on
// the task stack, so are instead declared static (making this function
// non-reentrant meaning it can only be called by a single task at a time,
// otherwise multiple tasks would use the same buffers).
static uint8_t first_receive_buffer[BUFFER_SIZE], second_receive_buffer[BUFFER_SIZE];
xSemaphoreHandle first_notification_semaphore = NULL, second_notification_semaphore = NULL;
const max_block_time_500ms = 500 / portTICK_RATE_MS;
// Create the notification semaphores, one per buffer.
// vSemaphoreCreateBinary() is a FreeRTOS API function.
vSemaphoreCreateBinary(first_notification_semaphore);
vSemaphoreCreateBinary(second_notification_semaphore);
// Nothing has been read over the SPI bus yet, so make sure both
// semaphores are empty.
xSemaphoreTake(first_notification_semaphore, 0);
xSemaphoreTake(second_notification_semaphore, 0);
// Start an asynchronous read to fill the first buffer. The function
// will be able to access the port immediately because nothing else has
// accessed it yet - allowing the block_time_ticks value to be set to 0.
freertos_spi_read_packet_async(freertos_spi, first_receive_buffer,
BUFFER_SIZE, 0, first_notification_semaphore);
for(;;)
{
// Wait until the first buffer is full. Other tasks will run during
// the wait. FreeRTOS will give first_notification_semaphore when
// the receive is complete.
xSemaphoreTake(first_notification_semaphore, max_block_time_500ms);
// Start an asynchronous read to fill the second buffer. Again
// block_time_ticks is set to zero as it is known that the read
// operation that was filling the first buffer has completed -
// leaving the SPI port available.
freertos_spi_read_packet_async(freertos_spi, second_receive_buffer,
BUFFER_SIZE, 0, second_notification_semaphore);
// Process the data in the first receive buffer while the second
// receive buffer is being refreshed.
process_received_data(first_receive_buffer);
// Wait until the second buffer is full. Other tasks will run
// during the wait. FreeRTOS will give second_notification_semaphore
// when the receive is complete.
xSemaphoreTake(second_notification_semaphore, max_block_time_500ms);
// Start an asynchronous read to fill the first buffer again.
freertos_spi_read_packet_async(freertos_spi, second_receive_buffer,
BUFFER_SIZE, 0, second_notification_semaphore);
// Process the data in the second receive buffer while the first
// receive buffer is being refreshed.
process_received_data(second_receive_buffer);
}
}