MPLAB® Harmony v3 Peripheral Libraries on SAMC2x: Step 5
Add Application Code to the Project
The application is already developed and available in the main_c21n.c file under <your unzip folder>/samc21n_getting_started/dev_files/sam_c21n_xpro. The main_c21n.c file contains the application logic. It also contains placeholders that you will populate with the necessary code in the next step.
- Go to the samc21n_getting_started/dev_files/sam_c21n_xpro folder and copy the pre-developed main_c21n.c file.
- Replace the main_c21n.c file of your project available at <Your project folder>/samc21n_getting_started/firmware/src by overwriting it with the copied file.
- Open main_c21n.c in MPLAB® X IDE and add the application code by following the steps below:
Under the main_c21n.c file, in function main, notice the call to function SYS_Initialize. The generated function SYS_Initialize initializes all the peripheral modules used in the application (configured through MPLAB Harmony Configurator (MHC)).
In the main_c21n.c function, below SYS_Initialize(), add the following code to register callback event handlers.
DMAC_ChannelCallbackRegister(DMAC_CHANNEL_0, usartDmaChannelHandler, 0);
RTC_Timer32CallbackRegister(rtcEventHandler, 0);
EIC_CallbackRegister(EIC_PIN_3,EIC_User_Handler, 0);
Following the addition of the code above, add the function call.
Implement the registered callback event handlers for RTC, I²C, Universal Synchronous Asynchronous Receiver Transmitter (USART), and EIC PLIBs by adding the following code before the main() function in main_c21n.c.
{
changeTempSamplingRate = true;
}
static void rtcEventHandler (RTC_TIMER32_INT_MASK intCause, uintptr_t context)
{
if (intCause & RTC_MODE0_INTENSET_CMP0_Msk)
{
isRTCTimerExpired = true;
}
}
static void i2cEventHandler(uintptr_t contextHandle)
{
if (SERCOM5_I2C_ErrorGet() == SERCOM_I2C_ERROR_NONE)
{
isTemperatureRead = true;
}
}
static void usartDmaChannelHandler(DMAC_TRANSFER_EVENT event, uintptr_t contextHandle)
{
if (event == DMAC_TRANSFER_EVENT_COMPLETE)
{
isUSARTTxComplete = true;
}
}
Add the following code to submit an I²C transfer to read temperature sensor value when the configured time period (default 500 milliseconds) has elapsed. The I²C PLIB calls back the callback event handler (registered in Step 2 above) when the submitted request is complete.
SERCOM5_I2C_WriteRead(TEMP_SENSOR_SLAVE_ADDR, &i2cWrData, 1, i2cRdData, 2);
Add the following code to prepare the received temperature value from the sensor to be prepared on the serial terminal.
sprintf((char*)uartTxBuffer, "Temperature = %02d F\r\n", temperatureVal);
LED_Toggle();
Add the following code to implement the change of sampling rate and prepare a message for the same on the serial terminal when the user presses the switch SW0.
if(tempSampleRate == TEMP_SAMPLING_RATE_500MS)
{
tempSampleRate = TEMP_SAMPLING_RATE_1S;
sprintf((char*)uartTxBuffer, "Sampling Temperature every 1 second \r\n");
RTC_Timer32CompareSet(PERIOD_1S);
}
else if(tempSampleRate == TEMP_SAMPLING_RATE_1S)
{
tempSampleRate = TEMP_SAMPLING_RATE_2S;
sprintf((char*)uartTxBuffer, "Sampling Temperature every 2 seconds \r\n");
RTC_Timer32CompareSet(PERIOD_2S);
}
else if(tempSampleRate == TEMP_SAMPLING_RATE_2S)
{
tempSampleRate = TEMP_SAMPLING_RATE_4S;
sprintf((char*)uartTxBuffer, "Sampling Temperature every 4 seconds \r\n");
RTC_Timer32CompareSet(PERIOD_4S);
}
else if(tempSampleRate == TEMP_SAMPLING_RATE_4S)
{
tempSampleRate = TEMP_SAMPLING_RATE_500MS;
sprintf((char*)uartTxBuffer, "Sampling Temperature every 500 ms \r\n");
RTC_Timer32CompareSet(PERIOD_500MS);
}
else
{
;
}
Add code to transfer the buffer containing either:
- The latest temperature value in the format “Temperature = XX F\r\n”, over or
- The message mentioning the change of sampling rate over USART using DMA.
You are now ready to build the code!