Skip to content

Working with GPIO

Dave Glover edited this page Sep 4, 2021 · 2 revisions

Working with GPIO


Examples

Code example, working with GPIO


Enums

typedef enum
{
	DX_DIRECTION_UNKNOWN,
	DX_INPUT,
	DX_OUTPUT
} DX_GPIO_DIRECTION;
typedef enum {
	DX_GPIO_DETECT_LOW,
	DX_GPIO_DETECT_HIGH,
	DX_GPIO_DETECT_BOTH
} DX_GPIO_INPUT_DETECT;

Functions

bool dx_gpioOpen(DX_GPIO* gpio);
bool dx_gpioStateGet(DX_GPIO* gpio, GPIO_Value_Type* oldState);
void dx_gpioClose(DX_GPIO* gpio);
void dx_gpioOff(DX_GPIO* gpio);
void dx_gpioOn(DX_GPIO* gpio);
void dx_gpioSetClose(DX_GPIO** gpioSet, size_t gpioSetCount);
void dx_gpioSetOpen(DX_GPIO** gpioSet, size_t gpioSetCount);
void dx_gpioStateSet(DX_GPIO* gpio, bool state);

Structures

GPIO context structure.

typedef struct
{
	int fd;
	int pin;
	GPIO_Value initialState;
	bool invertPin;
	DX_GPIO_INPUT_DETECT detect;
	char* name;
	DX_GPIO_DIRECTION direction;
	bool opened;
} DX_GPIO_BINDING;

Usage

Developer boards with onboard buttons

Press button A and the user LED will blink for 1 second

Developer boards without onboard buttons

The user LED will blink every 500ms

General Purpose Input and Output (GPIO) peripherals

Variables of type DX_GPIO declare a GPIO model for input and output of single pin peripherals, such as LEDs, buttons, reed switches, and relays.

A GPIO peripheral variable holds the GPIO pin number, the initial state of the pin when the program starts, and whether the pin logic needs to be inverted.

The following example declares two GPIOs, a button input peripheral, and an LED output peripheral.

// GPIO Input Peripherals
static DX_GPIO buttonA = {.pin = BUTTON_A, .name = "buttonA",.direction = DX_INPUT, .detect = DX_GPIO_DETECT_LOW };
static DX_GPIO led = {.pin = LED2, .name = "led",.direction = DX_OUTPUT, .initialState = GPIO_Value_Low, .invertPin = true };

Initializing a set of GPIO peripherals

For convenance you can declare a set of GPIO peripherals and use the set based functions to open. Add each GPIO peripheral by reference to the set (array) of GPIO peripherals.

Note, setting .invertPin = true is useful if you are using the GPIO pins on the developer board as their logic is inverted. Setting a pin high in software, turns the pin off, setting low, turns the pin on. Setting .invertPin = true fixes this, so your code behaves more as you'd expect. Setting GPIO high turns the pin on etc.

DX_GPIO* gpioSet[] = { &buttonA, &led };

and open the set using the dx_gpioSetOpen function.

/// <summary>
///  Initialize peripherals, device twins, direct methods, timers.
/// </summary>
static void InitPeripheralsAndHandlers(void)
{
    dx_gpioSetOpen(gpioSet, NELEMS(gpioSet));
    dx_timerSetStart(timerSet, NELEMS(timerSet));
}

Blinking an LED with a periodic timer event

/// <summary>
/// Handler to check for Button Presses
/// </summary>
static void ButtonPressCheckHandler(EventLoopTimer* eventLoopTimer)
{
    static bool led_state = false;

    if (ConsumeEventLoopTimerEvent(eventLoopTimer) != 0) {
        dx_terminate(DX_ExitCode_ConsumeEventLoopTimeEvent);
        return;
    }

    led_state = !led_state;    // toggle the led_state bool
    void dx_gpioStateSet(&led, led_state);
}

Useful terms

  • Hardware: Most IoT solutions are designed to interface with hardware and interact with the real world. The most common interfaces on a device are GPIO, PWM, I2C, SPI, ADC, and UART.
  • GPIO: Any GPIO pin can be designated (in software) as an input or output pin and can be used for a wide range of purposes. These labs use single-pin GPIO peripherals for input and output, so the following is an introduction to GPIO pins.
  • GPIO output: If a GPIO pin is designated as an output pin, then the software running on the Azure Sphere can set a pin to be either on or off. This equates to 3.3 volts for a pin that has been turned on, and zero volts when a pin is turned off. It's important to check that a peripheral connected to the pin can tolerate 3.3 volts. Otherwise you may destroy the peripheral. Lots of peripherals use single pins, such as LEDs, relays, and reed switches.
  • GPIO input: If a GPIO pin is designated as an input pin, then the software running on Azure Sphere can read a pin to determine if the voltage has been set to 3.3 volts, or zero volts/ground. It's essential to check that a peripheral won't set a voltage on a pin to anything higher than 3.3 volts before you connect it. Be warned, if you set a pin to a voltage higher than 3.3 volts you'll destroy Azure Sphere. An example of a GPIO peripheral that uses a single pin is a push button.
  • Other peripheral interface types: The following list is of common peripheral interfaces found on devices, including Azure Sphere. To learn more about each interface type, right mouse click and open the link in a new browser window.
  • ISU: You'll see references to ISU in the Azure Sphere and MediaTek documentation. An ISU is a serial interface block and is an acronym for "I2C, SPI, UART." For more information, see the MT3620 Support Status page.

Developer board reference

Avnet Azure Sphere MT3620 Starter Kit Revision 1

This is the default Azure Sphere device for the examples.

Avnet Azure Sphere kit Revision 1.

The Avnet Azure Sphere kit can be found here.

Avnet Azure Sphere MT3620 Starter Kit Revision 2

Avnet Azure Sphere kit Revision 2.

The Avnet Azure Sphere kit can be found here.

Seeed Studio Azure Sphere MT3620 Development Kit

Seeed Studio Azure Sphere kit.

The Seeed Studio Azure Sphere kit can be found here.

Seeed Studio Azure Sphere MT3620 Mini Dev Board

Seeed Studio Mini Azure Sphere kit.

The Seeed Studio Mini Azure Sphere kit can be found here.

Clone this wiki locally