GPIO

Basic I/O

The functions listed below are applicable to operating one or many input/output pins in a manual configuration; that is, the code directly reads or controls the pin values.

For each of these functions, the value for the first argument, GPIO_Regs* gpio, is the predefined variable used to identify the GPIO Port Registers; either GPIOA or GPIOB. The second argument, uint32_t pins, should use the predefined symbols GPIO_PINn, where n is the pin number. These functions will not work correctly if the pin number is directly given to the function.

  • void GPIO_initDigitalOutput(GPIO_Regs* gpio,uint32_t pins): Configure one or multiple pins on a port to be outputs.

  • void GPIO_initDigitalInput(GPIO_Regs* gpio,uint32_t pins): Configure one or multiple pins on a port to be inputs.

  • void GPIO_setInternalResistor(GPIO_Regs* gpio,uint32_t pins,gpio_pull_t pull): Configure the internal pull-up/pull-down behavior of one or multiple pins on a port. This function must be called after any other initialization functions for the associated pin(s). The functionality is selected via pull, which can be either

    • GPIO_PULL_NONE: Disable internal pull-up and pull-down resistors (default state)

    • GPIO_PULL_DOWN: Enable internal pull-down resistors (pull-up resistors disabled)

    • GPIO_PULL_UP: Enable internal pull-up resistors (pull-down resistors disabled)

  • void GPIO_setOpenDrain(GPIO_Regs* gpio,uint32_t pins): Sets an output pin to open-drain mode (floating when high, grounded when low). This mode is useful for I2C operation, for example.

  • void GPIO_setPushPull(GPIO_Regs* gpio,uint32_t pins): Sets an output pin to push-pull mode (connected to VDD when high, grounded when low). This is the default state of an output. This function is only necessary if reverting a change to open-drain.

  • uint32_t GPIO_readPins(GPIO_Regs* gpio,uint32_t pins): Reads the value of the selected pins. Returns a uint32_t value with bits corresponding to each requested pin having said pin’s value. All other bits are set to 0.

  • void GPIO_writePins(GPIO_Regs* gpio,uint32_t pins): Write all pins on a port to a given value. Any pins specified by pins will be set High with all others being set low.

  • void GPIO_setPins(GPIO_Regs* gpio,uint32_t pins): Set one or multiple pins on a port to output High if configured as outputs.

  • void GPIO_clearPins(GPIO_Regs* gpio,uint32_t pins): Set one or multiple pins on a port to output Low if configured as outputs.

  • void GPIO_togglePins(GPIO_Regs* gpio,uint32_t pins): Invert the output level of one or multiple pins on a port if configured as outputs.

All these functions can operate using multiple pins at once. To use multiple pins, all desired pin symbols (GPIO_PINm) should be ‘bitwise or’ed together, for example: GPIO_PIN15|GPIO_PIN20.

Examples:

  • Configure PA1 as an output and set it’s value High:

    GPIO_initDigitalOutput( GPIOA , GPIO_PIN1 ); // Set PA1 as an output
    ...
    GPIO_setPins( GPIOA , GPIO_PIN1 ); // Set PA1 high
    
  • Configure PB1 and PB3 as inputs and read both values:

    uint8_t val1,val2;
    GPIO_initDigitalInput( GPIOB , GPIO_PIN1 | GPIO_PIN3 ); // Set PB1,3 to inputs
    ...
    val1 = GPIO_readPins( GPIOB , GPIO_PIN1 ); // Read and store the value of PB1. value will be 0b00...000X0 (bit 1 high or low)
    val2 = GPIO_readPins( GPIOB , GPIO_PIN3 ); // Read and store the value of PB3. value will be 0b00...0X000 (bit 3 high or low)
    // OR
    val1 = GPIO_readPins( GPIOB , GPIO_PIN1 ) > 0; // Read and store the value of PB1. value will be either 0 (false) or 1 (true)
    val2 = GPIO_readPins( GPIOB , GPIO_PIN3 ) != 0; // Read and store the value of PB3. value will be either 0 (false) or 1 (true)
    

Interrupts

A GPIO pin can trigger an interrupt when its value changes: either transitions from low-to-high or high-to-low. These events are known as a rising edge and falling edge, respectively. A pin can be configured to trigger an interrupt on either or both edges.

../_images/edges.svg

GPIO Signal Edges

All pin interrupt triggers, or interrupt requests (IRQs), will invoke a single interrupt service routine, or ISR, for the microcontroller (at least for the MSPM0G3507). This implies that if multiple pins are configured to generate interrupts, there must be code to support determining what pin triggered the interrupt, regardless of port.

An ISR is also referred to as an interrupt request handler, or IRQ Handler.

Enabling Interrupts

Each GPIO pin may have its interrupt capability enabled and disabled using the functions:

  • void GPIO_enableInterrupt( GPIO_Regs* gpio, uint32_t pins)

  • void GPIO_disableInterrupt( GPIO_Regs* gpio, uint32_t pins)

Further, selection of the rising or falling edge as the interrupt event may be done through the function:

void GPIO_setInterruptPolarity( GPIO_Regs* gpio , uint32_t pins , gpio_int_polarity_t polarity )

where gpio_int_polarity_t edgeSelect is either GPIO_INT_EDGE_RISE, GPIO_INT_EDGE_FALL, or GPIO_INT_EDGE_RISE_FALL.

The code may check if a pin(s) has interrupt capability enabled by using:

  • uint32_t GPIO_getEnabledInterrupts( GPIO_Regs* gpio , uint32_t pins )

Finally, the single interrupt for all GPIO pins must be enabled within the CPU with

NVIC_EnableIRQ( IRQn_Type IRQn )

where IRQn_Type IRQn is set as GPIO_INT_IRQn.

Interrupt Handling

The ISR or IRQ Handler associated with the GPIO interrupts will be automatically called when the selected edge is detected on any of the enabled pins. Within this function, the code must acknowledge the interrupt by clearing the associated flag, or register bit that indicates the interrupt was triggered. If the flag is not cleared, the interrupt will continuously trigger; that is, the function will be immediately called again once it completes.

The IRQ Handler for the purposes of this class must be named void GPIO_IRQHandler().

Within void GPIO_IRQHandler(), The interrupt source must be acknowledged using:

void GPIO_clearInterrupt( GPIO_Regs* gpio , uint32_t pins )

If multiple pins are enabled as trigger sources, it is necessary to determine which pin triggered the interrupt. This may be done through the function:

uint32_t GPIO_getPendingInterrupts( GPIO_Regs* gpio )

where this function returns a value that is a bitwise-or, |, of all pins within the specified port that have triggered the interrupt. For example, if pushbuttons on PA1 and PA3 were pressed simultaneously, this function would return the value GPIO_PIN1 | GPIO_PIN3. This function will only return triggers that are currently enabled. Alternatively, the function:

uint32_t GPIO_getAllPendingInterrupts( GPIO_Regs* gpio )

will return the interrupt trigger status for all pins in the port, regardless of if they are enabled or not.

Peripheral Functions

Each GPIO pin is capable of being internally connected to other module signals. When a peripheral function, or “alternate” function, is used, the GPIO pin is controlled directly from module it is connected to. There are up to 8 total digital signals that may be selected as an alternative function to basic inputs and outputs, though most pins have less. Further, many pins pay also take on analog functionality (e.g., connection to the ADC or DAC). These peripheral modes are selected via the two functions:

GPIO_initPeripheralFunction( GPIO_Regs* gpio , uint32_t pins , uint32_t function ) GPIO_initPeripheralAnalogFunction( GPIO_Regs* gpio , uint32_t pins )

where uint32_t function is the number code for the desired peripheral function, specific to each pin. Issuing one of the above functions will override any previous configuration of the selected pin(s). Likewise, the GPIO pin can be converted back to a normal input or output pin by issuing the corresponding function(s).

The values for uint32_t function have constants defined in the EmCon HAL for easier use. These constants are of the format GPIO_P[A/B]#_PF_[altfunc], where the possible values for altfunc (the alternate function) for each pin are listed in the table below for the MSPM0G3507. For example, the third alternative function for PA2 (SPI0_CS0) is defined as GPIO_PA2_PF_SP01_CS0. Alternatively, the value 3 could also be used instead.

Note that the listed function numbers are 2-9. Functions 0 and 1 are:

  • Function 0: UNCONNECTED

    • Pin is unconnected and cannot be used. The pin is in a “Hi-Z” state.

    • All pins default to this mode.

    • Defined constants of the form GPIO_P[A/B]#_PF_UNCONNECTED exist for this mode.

  • Function 1: DIO

    • Pin is set to be used as a digital input or output.

    • This function value is automatically set when configuring pins as digital inputs or outputs using the functions defined in Basic I/O.

    • Defined constants of the form GPIO_P[A/B]#_PF_DIO exist for this mode.

For analog signal connections, see the ADC Channel Pin Map.

GPIO Digital Alternate Functions

Pin

Function 2

Function 3

Function 4

Function 5

Function 6

Function 7

Function 8

Function 9

PA0

UART0_TX

I2C0_SDA

TIMA0_C0

TIMA_FAULT1

TIMG8_C1

SYSCTL_FCC_IN

PA1

UART0_RX

I2C0_SCL

TIMA0_C1

TIMA_FAULT2

TIMG8_IDX

TIMG8_C0

PA2

TIMG8_C1

SPI0_CS0

TIMG7_C1

SPI1_CS0

PA3

TIMG8_C0

SPI0_CS1_POCI1

UART2_CTS

TIMA0_C2

COMP1_OUT

TIMG7_C0

TIMA0_C1

I2C1_SDA

PA4

TIMG8_C1

SPI0_POCI

UART2_RTS

TIMA0_C3

SYSCTL_LFCLKIN

TIMG7_C1

TIMA0_C1_CMPL

I2C1_SCL

PA5

TIMG8_C0

SPI0_PICO

TIMA_FAULT1

TIMG0_C0

TIMG6_C0

SYSCTL_FCC_IN

PA6

TIMG8_C1

SPI0_SCLK

TIMA_FAULT0

TIMG0_C1

SYSCTL_HFCLKIN

TIMG6_C1

TIMA0_C2_CMPL

PA7

COMP0_OUT

SYSCTL_CLK_OUT

TIMG8_C0

TIMA0_C2

TIMG8_IDX

TIMG7_C1

TIMA0_C1

PA8

UART1_TX

SPI0_CS0

UART0_RTS

TIMA0_C0

TIMA1_C0_CMPL

PA9

UART1_RX

SPI0_PICO

UART0_CTS

TIMA0_C1

RTC_RTC_OUT

TIMA0_C0_CMPL

TIMA1_C1_CMPL

PA10

UART0_TX

SPI0_POCI

I2C0_SDA

TIMA1_C0

TIMG12_C0

TIMA0_C2

I2C1_SDA

SYSCTL_CLK_OUT

PA11

UART0_RX

SPI0_SCLK

I2C0_SCL

TIMA1_C1

COMP0_OUT

TIMA0_C2_CMPL

PA12

UART3_CTS

SPI0_SCLK

TIMG0_C0

CANFD0_CANTX

TIMA0_C3

SYSCTL_FCC_IN

PA13

UART3_RTS

SPI0_POCI

UART3_RX

TIMG0_C1

CANFD0_CANRX

TIMA0_C3_CMPL

PA14

UART0_CTS

SPI0_PICO

UART3_TX

TIMG12_C0

SYSCTL_CLK_OUT

PA15

UART0_RTS

SPI1_CS2_POCI2

I2C1_SCL

TIMA1_C0

TIMG8_IDX

TIMA1_C0_CMPL

TIMA0_C2

PA16

COMP2_OUT

SPI1_POCI

I2C1_SDA

TIMA1_C1

TIMA1_C1_CMPL

TIMA0_C2_CMPL

SYSCTL_FCC_IN

PA17

UART1_TX

SPI1_SCLK

I2C1_SCL

TIMA0_C3

TIMG7_C0

TIMA1_C0

PA18

UART1_RX

SPI1_PICO

I2C1_SDA

TIMA0_C3_CMPL

TIMG7_CCO1

TIMA1_C1

PA19

DEBUGSS_SWDIO

PA20

DEBUGSS_SWCLK

PA21

UART2_TX

TIMG8_C0

UART1_CTS

TIMA0_C0

TIMG6_C0

PA22

UART2_RX

TIMG8_C1

UART1_RTS

TIMA0_C1

SYSCTL_CLK_OUT

TIMA0_C0_CMPL

TIMG6_C1

PA23

UART2_TX

SPI0_CS3_CD_POCI3

TIMA0_C3

TIMG0_C0

UART3_CTS

TIMG7_C0

TIMG8_C0

PA24

UART2_RX

SPI0_CS2_POCI2

TIMA0_C3_CMPL

TIMG0_C1

UART3_RTS

TIMG7_C1

TIMA1_C1

PA25

UART3_RX

SPI1_CS3_CD_POCI3

TIMG12_C1

TIMA0_C3

TIMA0_C1_CMPL

PA26

UART3_TX

SPI1_CS0

TIMG8_C0

TIMA_FAULT0

CANFD0_CANTX

TIMG7_C0

PA27

RTC_RTC_OUT

SPI1_CS1_POCI1

TIMG8_C1

TIMA_FAULT2

CANFD0_CANRX

TIMG7_C1

PA28

UART0_TX

I2C0_SDA

TIMA0_C3

TIMA_FAULT0

TIMG7_C0

TIMA1_C0

PA29

I2C1_SCL

UART2_RTS

TIMG8_C0

TIMG6_C0

PA30

I2C1_SDA

UART2_CTS

TIMG8_C1

TIMG6_C1

PA31

UART0_RX

I2C0_SCL

TIMA0_C3_CMPL

TIMG12_C1

SYSCTL_CLK_OUT

TIMG7_C1

TIMA1_C1

PB0

UART0_TX

SPI1_CS2_POCI2

TIMA1_C0

TIMA0_C2

PB1

UART0_RX

SPI1_CS3_CD_POCI3

TIMA1_C1

TIMA0_C2_CMPL

PB2

UART3_TX

UART2_CTS

I2C1_SCL

TIMA0_C3

UART1_CTS

TIMG6_C0

TIMA1_C0

PB3

UART3_RX

UART2_RTS

I2C1_SDA

TIMA0_C3_CMPL

UART1_RTS

TIMG6_C1

TIMA1_C1

PB4

UART1_TX

UART3_CTS

TIMA1_C0

TIMA0_C2

TIMA1_C0_CMPL

PB5

UART1_RX

UART3_RTS

TIMA1_C1

TIMA0_C2_CMPL

TIMA1_C1_CMPL

PB6

UART1_TX

SPI1_CS0

SPI0_CS1_POCI1

TIMG8_C0

UART2_CTS

TIMG6_C0

TIMA1_C0_CMPL

PB7

UART1_RX

SPI1_POCI

SPI0_CS2_POCI2

TIMG8_C1

UART2_RTS

TIMG6_C1

TIMA1_C1_CMPL

PB8

UART1_CTS

SPI1_PICO

TIMA0_C0

COMP1_OUT

PB9

UART1_RTS

SPI1_SCLK

TIMA0_C1

TIMA0_C0_CMPL

PB10

TIMG0_C0

TIMG8_C0

COMP1_OUT

TIMG6_C0

PB11

TIMG0_C1

TIMG8_C1

SYSCTL_CLK_OUT

TIMG6_C1

PB12

UART3_TX

TIMA0_C2

TIMA_FAULT1

TIMA0_C1

PB13

UART3_RX

TIMA0_C3

TIMG12_C0

TIMA0_C1_CMPL

PB14

SPI1_CS3_CD_POCI3

PI1_POCI

SPI0_CS3_CD_POCI3

TIMG12_C1

TIMG8_IDX

PB15

UART2_TX

SPOI1_PICO

UART3_CTS

TIMG8_C0

TIMG7_C0

PB16

UART2_RX

SPI1_SCLK

UART3_RTS

TIMG8_C1

TIMG7_C1

PB17

UART2_TX

SPI0_PICO

SPI1_CS1_POCI1

TIMA1_C0

TIMA0_C2

PB18

UART2_RX

SPI0_SCLK

SPI1_CS2_POCI2

TIMA1_C1

TIMA1_C1

TIMA0_C2_CMPL

PB19

COMP2_OUT

SPI0_POCI

TIMG8_C1

UART0_CTS

TIMG7_C1

PB20

SPI0_CS2_POCI2

SPI1_CS0

TIMA0_C2

TIMG12_C0

TIMA_FAULT1

TIMA0_C1

TIMA1_C1_CMPL

PB21

SPI1_POCI

TIMG8_C0

PB22

SPI1_PICO

TIMG8_C1

PB23

SPI1_SCLK

COMP0_OUT

TIMA_FAULT0

PB24

SPI0_CS3_CD_POCI3

SPI0_CS1

POCI1

TIMA0_C3

TIMG12_C1

TIMA0_C1_CMPL

PB25

UART0_CTS

SPI0_CS0

TIMA_FAULT2

PB26

UART0_RTS

SPI0_CS1_POCI1

TIMA0_C3

TIMG6_C0

TIMA1_C0

PB27

COMP2_OUT

SPI1_CS1_POCI1

TIMA0_C3_CMPL

TIMG6_C1

TIMA1_C1

These pins are not available to use on the Launchpad Board or RSLK as they are not routed to connections headers.