Step 5: Add application code to the project
The application is already developed and is available in the files main_e70.c, app_sensor.c, app_eeprom.c, and usart_common.c under
<your unzip folder>/getting_started_drv/dev_files/sam_e70_xult.
The application files app_sensor.c and app_eeprom.c contain the application logic. They also contain placeholders that you will populate with the necessary code in the next step.
- Go to the getting_started_drv/dev_files/sam_e70_xult folder and copy the pre-developed files main_e70.c, app_sensor.c, app_eeprom.c, usart_common.c, app_sensor.h, app_eeprom.h, and usart_common.h file.
- Paste and replace (over-write) the files of your project available at <Your project folder>/getting_started_drv/firmware/src with the copied files.
- Add the application file usart_common.c to your project.
1
For an Harmony v3 application, MPLAB® Harmony Configurator (MHC) generates the application template files (app_sensor.c, app_sensor.h, app_eeprom.c, app_eeprom.h, and main_e70.c). The main_e70.c file calls the SYS_Tasks() routine which runs the sensor and the EEPROM application tasks (and driver/middleware tasks if added to the project).
4
The APP_SENSOR_Tasks() function in the app_sensor.c file and the APP_EEPROM_Tasks() in app_eeprom.c file implement the application state machine.
5
The sensor application task in app_sensor.c and the EEPROM application task in app_eeprom.c acts as the two clients to the I²C driver instance 0.
6
Open app_sensor.c and add application code by following the below steps.
a
Open the I²C driver instance 0 (which is associated with TWIHS0). The call to DRV_I2C_Open() Application Programming Interface (API) will associate the sensor client with the I²C driver instance 0. The returned handle will be used by the application in all the subsequent calls (related to the sensor client) to the driver.
app_sensorData.i2cHandle = DRV_I2C_Open( DRV_I2C_INDEX_0, DRV_IO_INTENT_READWRITE );
e
Open the Universal Synchronous Asynchronous Receiver Transmitter (USART) driver instance 0 (which is associated with USART1). The call to DRV_USART_Open() API will return a handle to the USART driver instance 0. The returned handle will be used by the application (by sensor task and EEPROM task) in all the subsequent calls to the driver.
usartHandle = DRV_USART_Open(DRV_USART_INDEX_0, DRV_IO_INTENT_READWRITE);
h
When the periodic timer expires, submit an I²C transfer to read the temperature sensor value using the I²C driver write-then-read API. The I²C driver calls back the sensor event handler (registered in the step 6 C above) when the submitted request is complete.
DRV_I2C_WriteReadTransferAdd( app_sensorData.i2cHandle,
APP_SENSOR_I2C_SLAVE_ADDR,
(void*)app_sensorData.i2cTxBuffer, 1,
(void *) app_sensorData.i2cRxBuffer, 2,
&app_sensorData.transferHandle );
j
Print the latest temperature value and notify the EEPROM application task to log the temperature value to EEPROM.
APP_SENSOR_PrintTemperature(app_sensorData.usartTxBuffer,
(int8_t *)"Temperature = %d F\r\n",
app_sensorData.temperature);
APP_EEPROM_SetTempWriteRequest(app_sensorData.temperature);
The implementation of APP_SENSOR_PrintTemperature makes a call to USART driver function DRV_USART_WriteBufferAdd.
- The DRV_USART_WriteBufferAdd function performs transfers for the formatted message with temperature value from data memory to the serial terminal using Direct Memory Access (DMA).
- If the USART driver was not configured (in MHC) to use DMA for TX operation, the same function (DRV_USART_WriteBufferAdd) would be used to transfer the formatted message with temperature value from data memory to serial terminal.
- The above points imply if a Harmony v3 driver is configured to use DMA or not for data transfer operation, the application code remains unchanged. The Harmony data transfer APIs seamlessly handles the data transfer operation through the same API.
7
Open app_eeprom.c and add application code by following the below steps.
a
Associate the second client (the EEPROM client), with the I²C driver instance 0. This is done by opening the I²C driver instance 0 again. The call to DRV_I2C_Open () API will now associate the EEPROM client with the I²C driver instance 0. The returned handle will be used by the application in all the subsequent calls (related to the EEPROM client) to the driver.
app_eepromData.i2cHandle = DRV_I2C_Open( DRV_I2C_INDEX_0, DRV_IO_INTENT_READWRITE );
b
Like the sensor client, setup the transfer parameters for the EEPROM client after a valid handle to the driver is obtained. The transfer parameters sets the I²C clock speed to 400 kHz for this client.
DRV_I2C_TransferSetup(app_eepromData.i2cHandle, &app_eepromData.i2cSetup);
- The call to DRV_I2C_TransferSetup overrides the baud rate set in the I²C driver configuration using MHC.
- I²C was configured to run at 400 kHz using MHC. While in the application, the sensor task has reconfigured it to run at 100 kHz and the EEPROM task configured it to run at 400 kHz. This illustrates how the Harmony I²C driver handles the peripheral module-specific configuration depending on the client accessing the peripheral.
c
Like the sensor client, register an event handler (callback) with the I²C driver for the EEPROM client. The event handler would be called by the I²C driver when any request submitted by the EEPROM application client is completed.
DRV_I2C_TransferEventHandlerSet(app_eepromData.i2cHandle, APP_EEPROM_I2CEventHandler, 0);
d
Submit a USART read request to receive a character on the serial terminal. When the user enters a character, a USART interrupt occurs. In the USART event handler the application sets the usartReadRequest flag to true.
DRV_USART_ReadBufferAdd(usartHandle, (void*)app_eepromData.usartRxBuffer, 1, &usartReadBufferHandle);
The DRV_USART_ReadBufferAdd API submits a read request to read a character from the serial terminal. The USART driver responds to a character read by interrupting the CPU and calling back the registered event handler (APP_USARTBufferEventHandler).
e
When the user enters a character on the serial terminal, submit an I²C transfer to read back the written temperature sensor values from the EEPROM, using the write-then-read API. The I²C driver calls back the EEPROM event handler (APP_EEPROM_I2CEventHandler) when the submitted request is complete.
DRV_I2C_WriteReadTransferAdd(app_eepromData.i2cHandle,
APP_EEPROM_I2C_SLAVE_ADDR, app_eepromData.i2cTxBuffer,
1, app_eepromData.i2cRxBuffer, 5, &app_eepromData.transferHandle);
g
Print the temperature values read from the EEPROM and submit a USART read request to receive subsequent character on the serial terminal.
APP_EEPROM_PrintTemperature(app_eepromData.i2cRxBuffer, app_eepromData.wrIndex);
DRV_USART_ReadBufferAdd(usartHandle, (void*)app_eepromData.usartRxBuffer, 1, &usartReadBufferHandle);
Similar to the implementation APP_SENSOR_PrintTemperature, the implementation of APP_EEPROM_PrintTemperature makes a call to USART driver function DRV_USART_WriteBufferAdd.
The DRV_USART_WriteBufferAdd function performs transfer for the formatted message with the last five temperature values from data memory (read from EEPROM) to the serial terminal using DMA.
You are now ready to build the code!
Next Step >