MPLAB® Harmony v3 Peripheral Libraries on SAM D5x/E5x: Step 5

Last modified by Microchip on 2023/11/09 09:08

Add Application Code to the Project

The application is already developed and is available in the main_e54.c file under <your unzip folder>/same54_getting_started/dev_files/sam_e54_xpro. The main_e54.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 same54_getting_started/dev_files/sam_e54_xpro folder and copy the pre-developed main_e54.c file.
  • Replace (over-write) the main_e54.c file of your project available at <Your project folder>/same54_getting_started/firmware/src with the copied file.
  • Open main_e54.c in MPLAB® X IDE and add application code by following the steps below:

Under the main_e54.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 MHC).

Information

Tip: Press the CTRL key and left click on the SYS_Initialize function. The click will open the implementation for the SYS_Initialize function as shown below.

The implementation for the SYS_Initialize function is displayed

Back to Top


In the main_e54.c function, below SYS_Initialize(), add the following code to register callback event handlers.

SERCOM3_I2C_CallbackRegister(i2cEventHandler, 0);
DMAC_ChannelCallbackRegister(DMAC_CHANNEL_0, usartDmaChannelHandler, 0);
RTC_Timer32CallbackRegister(rtcEventHandler, 0);
EIC_CallbackRegister(EIC_PIN_15,EIC_User_Handler, 0);
Following the addition of the code above, add the function call.
RTC_Timer32Start();

The code for registering callback event handlers is displayed

Information

Note:

a. The function call SERCOM3_I2C_CallbackRegister registers a callback event handler with the I²C Peripheral Library (PLIB). The event handler is called by the I²C PLIB when the I²C transfer is complete.

b. The function call DMAC_ChannelCallbackRegister registers a callback event handler with the Direct Memory Access (DMA) PLIB. The callback event handler is called by the DMA PLIB when the DMA transfer (of temperature sensor data to serial terminal) is complete.

c. The function call RTC_Timer32CallbackRegister registers an Real-Time Clock (RTC) callback event handler with the RTC PLIB. The callback event handler is called by the RTC PLIB when the configured time period has elapsed.

d. The function call EIC_CallbackRegister registers an External Interrupt Controller (EIC) callback event handler with the EIC PLIB. The callback event handler is called by EIC PLIB when the user presses the switch SW0.

Back to Top


Implement the registered callback event handlers for RTC, I²C, USART, and EIC PLIBs by adding the following code before main() function in main_e54.c.

static void EIC_User_Handler(uintptr_t context)
{
   changeTempSamplingRate = true;      
}

static void rtcEventHandler (RTC_TIMER32_INT_MASK intCause, uintptr_t context)
{
   if (intCause & RTC_TIMER32_INT_MASK_CMP0)
    {            
       isRTCTimerExpired = true;                              
    }
}

static void i2cEventHandler(uintptr_t contextHandle)
{
   if (SERCOM3_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;
    }
}

The code for implementing the registered callback event handlers is displayed

Back to Top


Add the code below to submit an I²C transfer to read the 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.

isRTCTimerExpired = false;
SERCOM3_I2C_WriteRead(TEMP_SENSOR_SLAVE_ADDR, &i2cWrData, 1, i2cRdData, 2);

The code to submit an I²C transfer to read temperature sensor value when the configured time period (default 500 milliseconds) has elapsed is displayed

Back to Top


Add the code below to prepare the received temperature value from the sensor to be prepared on the serial terminal.

temperatureVal = getTemperature(i2cRdData);
sprintf((char*)uartTxBuffer, "Temperature = %02d F\r\n", temperatureVal);
LED_Toggle();

The code to prepare the received temperature value from the sensor to be prepared on the serial terminal is displayed

Back to Top


Add the code below 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.

changeTempSamplingRate = false;
if(tempSampleRate == TEMP_SAMPLING_RATE_500MS)
{
   tempSampleRate = TEMP_SAMPLING_RATE_1S;
   sprintf((char*)uartTxBuffer, "Sampling Temperature every 1 second \r\n");
   RTC_Timer32Compare0Set(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_Timer32Compare0Set(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_Timer32Compare0Set(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_Timer32Compare0Set(PERIOD_500MS);
}
else
{
   ;
}

The 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 is displayed

Back to Top


Add code to transfer the buffer containing either:

  • The latest temperature value in the format “Temperature = XX F\r\n”, over or

  • The message mentions the change of sampling rate over USART using DMA.
DMAC_ChannelTransfer(DMAC_CHANNEL_0, uartTxBuffer, (const void *)&(SERCOM2_REGS->USART_INT.SERCOM_DATA), strlen((const char*)uartTxBuffer));

The code to transfer the buffer is displayed

You are now ready to build the code!

Back to Top