Friday, September 9, 2016

Featherboard M0 Basic ~GPIO~

Featherboard M0 Basic ~GPIO~


This is the GPIO test of Featherboard M0 using Arduino IDE. 
I sometimes need to toggle the GPIO as fast as possible, and it is difficult to achieve the requirements using Arduino API, such as digitalWrite function.
In this case, you need to check the necessary source code under the Arduino package like \hardware\samd\1.x.x\cores\arduino and find the functions to optimize the behavior.


digitalWrite Function

digitalWrite function is defined in the wiring_digital.c file.
void digitalWrite( uint32_t ulPin, uint32_t ulVal )
{
  // Handle the case the pin isn't usable as PIO
  if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN )
  {
    return ;
  }

  // Enable pull-up resistor
  PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_PULLEN) ;

  switch ( ulVal )
  {
    case LOW:
      PORT->Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (1ul << g_APinDescription[ulPin].ulPin) ;
    break ;

    default:
      PORT->Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (1ul << g_APinDescription[ulPin].ulPin) ;
    break ;
  }

  return ;
}
As you can see, ulval is used in the switch statement and if it is 0, it clears the port, and if it is 1, it sets the port.
If you are sure which port you access and the pin configuration, the lines before the switch statement would not be needed which saves the time used for those operations.
Also, if you do not need to have the function and directly control the pins from the main code, you can just reuse the lines written in the switch statement.
PORT->Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (1ul << g_APinDescription[ulPin].ulPin) ;
PORT->Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (1ul << g_APinDescription[ulPin].ulPin) ;
When you use those lines in the main function, you need to replace ulPin with the actual values based on the pin you want to use.
You can find the variant.cpp file and WVariant.h.
If you need it to be more faster, you can assign specific bit values instead of the bit shift operation and also assign the right number to the Group[].
For example, using digital pin 13, the set and clear can be done something like below.
PORT->Group[0].OUTCLR.reg = 0x00020000;
PORT->Group[0].OUTSET.reg = 0x00020000;
This will make it much faster than using digitalWrite function.

No comments:

Post a Comment