GPIO Support on SAM Processors — Details


#include <cyg/hal/hal_io.h>

cyg_uint32 pin = CYGHWR_HAL_SAM_PIN( port , bit , mode , md , pupd , if , int , conf );

cyg_uint32 pin = CYGHWR_HAL_SAM_PIN_OUT( port , bit , md , pupd );

cyg_uint32 pin = CYGHWR_HAL_SAM_PIN_IN( port , bit , md , pupd , if , int );


CYGHWR_HAL_SAM_GPIO_OUT ( pin , val );

CYGHWR_HAL_SAM_GPIO_IN ( pin , val );


The SAM HAL provides a number of macros to support the encoding of the GPIO pin identity and I/O configuration into a single 32-bit descriptor. This is useful to drivers and other packages that need to configure and use different lines for different devices.

A descriptor is created with one of the 3 variants depending on how the pin is to be used. The support is implemented by the CYGHWR_HAL_SAM_PIN macro, with CYGHWR_HAL_SAM_PIN_IN and CYGHWR_HAL_SAM_PIN_OUT being shorthand helpers when direct GPIO control of a pin is required: CYGHWR_HAL_SAM_PIN_IN defines the pin as an input whose value can be accessed by the user using the macro CYGHWR_HAL_SAM_GPIO_IN (see later), CYGHWR_HAL_SAM_PIN_OUT defines the pin as an output where the user can set the pin output value with the macro CYGHWR_HAL_SAM_GPIO_OUT (see later).

The CYGHWR_HAL_SAM_PIN macro can be used when defining a pin that will be controlled by an on-chip peripheral.


The HAL supplied header file var_io.h provides existing configuration definitions for the majority of the on-chip peripherals supported by eCos, thus obviating the need for the developer to provide their own pin definitions.

The macro variants take a subset of arguments from the following list:

This identifies the PIO controller to which the pin is attached. Ports are identified by letters from A to E.
This gives the bit, or pin number, within the controller port. These are numbered from 0 to 31.

This parameter indicates whether the pin is controlled by an on-chip peripheral, or is to be used as a GPIO pin under application control.

Table 293.1. Pin Mode

mode Details
GPIOIN The pin is to be configured as an INPUT, and after configuration the CYGHWR_HAL_SAM_GPIO_IN macro can be used to ascertain the pin state.
GPIOOUT The pin is to be configured as an OUTPUT, and after configuration the CYGHWR_HAL_SAM_GPIO_OUT macro can be used to drive the pin level.
PER_A, PER_B, PER_C, PER_D The required peripheral mapping when the pin is to be assigned to an on-chip peripheral. The multiplexing of peripheral signals is defined by the CPU variant being targeted, and is beyond the scope of this documentation. When creating pin configurations for on-chip peripherals the relevant Atmel datasheet or technical reference manual should be consulted.

This setting indicates whether the pin should be driven in open-drain mode (OPENDRAIN). If the pin is not to be configured as OPENDRAIN this value is unused, but for clarity can be given the setting NA.
If this is an input pin, or an output pin configured in open-drain mode (whether controlled by GPIO or a peripheral), this setting can be used to indicate whether a weak pull-up resistor (PU) is used, or a weak pull-down resistor (PD) is used. If neither are to be used, then a value of NONE can be given.
For input pins (GPIO or peripheral) a glitch (GLITCH) or debouncing (DEBOUNCE) filter can be configured for the pin. When no input filtering is required, or when the field is not relevant due to the other pin configuration fields, the value NONE can be specified.

This parameter indicates whether the pin should have an interrupt configuration defined.

Table 293.2. Interrupt Type

int Details
EDGE_ANY When an interrupt event should be raised on a pin edge event (rising or falling).
EDGE_RISE An interrupt should only be raised on rising (LOW->HIGH) edge transitions.
EDGE_FALL An interrupt should only be raised on falling (HIGH->LOW) edge transitions.
LEVEL_HIGH Interrupts should be asserted when the pin is at a HIGH level.
LEVEL_LOW Interrupts should be asserted when the pin is at a LOW level.
NA This value can be used when an interrupt configuration is not required, or not applicable due to the other pin configuration parameters.

This parameter provides a simple “extension” mechanism; and is treated as a 32-bit binary value that is OR-ed into the pin descriptor. Care must be taken to ensure that existing bit-fields within the binary descriptor are not corrupted.

The following examples show how these macros may be used:

// Define port B pin 28 as being controlled by peripheral multiplex A,
// which for this pin on SAM devices is UART0 RX, without any
// pull-ups/pull-downs:

// Define port D pin 20 as a GPIO output with a pull-down, for an
// active-low LED:

Additionally, the manifest CYGHWR_HAL_SAM_PIN_NONE may be used in place of a pin descriptor and has a value that no valid descriptor can take. It may therefore be used as a placeholder where no GPIO pin is present or to be used. This can be useful when defining pin configurations for a series of instances of a peripheral (e.g. USART ports), but where not all instances support all the same pins (e.g. hardware flow control lines).

The remaining macros all take a suitably constructed GPIO pin descriptor as an argument. The CYGHWR_HAL_SAM_PIN_SET macro configures the pin according to the descriptor and must be called before any other macros. CYGHWR_HAL_SAM_GPIO_OUT sets the output to the value of the least significant bit of the val argument. The val argument of CYGHWR_HAL_SAM_GPIO_IN should be a pointer to an int, which will be set to 0 if the pin input is zero, and 1 otherwise.

Further helper macros are available, and it is recommended to consult the header file <cyg/hal/var_io.h> (also present in the include subdirectory of the SAM variant HAL package within the eCos source repository), for the complete list if needed.