Microchip® Advanced Software Framework

Receiving using the FreeRTOS TWI driver in fully

asynchronous mode

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

The example below implements a function that receives a block of data, then processes the received data while another bock is being received.

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_twi has already been set by a successful
// call to freertos_twi_master_init(), and that freertos_twi_master_init()
// configured the FreeRTOS TWI 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 TWI bus. Error checking is
// omitted to simplify the example.
void a_function(freertos_twi_if freertos_twi)
{
// 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 notification_semaphore = NULL;
const max_block_time_500ms = 500 / portTICK_RATE_MS;
twi_packet_t read_parameters;
uint16_t calculated_address;
// Configure the read_parameters structure to define a read operation
// that fills the first receive buffer.
read_parameters.chip = BOARD_AT24C_ADDRESS;
read_parameters.buffer = first_receive_buffer;
read_parameters.length = BUFFER_SIZE;
read_parameters.addr_length = 2;
// The first read is from address 0.
calculated_address = 0;
read_parameters.addr[0] = 0;
read_parameters.addr[1] = 0;
// Create the notification semaphore that will be used by FreeRTOS to
// notify the task that the receive operation is complete.
vSemaphoreCreateBinary(notification_semaphore);
// Nothing has been read over the TWI bus yet, so make sure the
// semaphore starts in the expected empty state.
xSemaphoreTake(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_twi_read_packet_async(freertos_twi, &read_parameters, 0
notification_semaphore);
// Wait until the first buffer is full. Other tasks will run during
// the wait. FreeRTOS will give notification_semaphore when
// the receive is complete.
xSemaphoreTake(notification_semaphore, max_block_time_500ms);
// Move the calculated address by the amount of bytes read so far.
calculated_address += BUFFER_SIZE
read_parameters.addr[0] = (uint8_t) ((calculated_address >> 8) & 0xff);
read_parameters.addr[1] = (uint8_t) (calculated_address & 0xff);
// The first buffer is full. The next read will fill the second buffer.
read_parameters.buffer = second_receive_buffer;
// Start an asynchronous read to fill the second buffer. Assuming no
// other tasks are using the same TWI port, it is known that the port is
// already available because the first read has completed. This means
// the block time can be 0.
freertos_twi_read_packet_async(freertos_twi, &read_parameters, 0
notification_semaphore);
// Process the data in the first receive buffer while the second
// receive buffer is being filled.
process_received_data(first_receive_buffer);
// Wait until the second buffer is full. Other tasks will run
// during the wait. FreeRTOS will give notification_semaphore when
// the receive is complete.
xSemaphoreTake(notification_semaphore, max_block_time_500ms);
// Process the data in the second receive buffer.
process_received_data(second_receive_buffer);
}