Skip to content

Concepts First

  • Pull-up input: an internal resistor pulls the pin high by default; pressing the button grounds it, so the pin reads low (0).
  • Level: a pin has two states — high (1, ~3.3V) and low (0, ~0V); button press/release is detected by the level change.
  • Switch bounce: mechanical buttons bounce when pressed/released. This example polls the level; real projects should add debounce.

Example Overview

This page is based on the gpio_input_output example in the official Bouffalo SDK (examples/peripherals/gpio/gpio_input_output), focusing on the input part:

  • GPIO2 is configured as a pull-up input (the button on all Ai-M6x boards is on GPIO2), read every 2 seconds;
  • The result is printed to the serial port: GPIO_PIN_2=0 (low level, button pressed) / GPIO_PIN_2=1 (high level, button released).
  • Sibling examples (examples/peripherals/gpio/): gpio_interrupt (external interrupt), gpio_output_with_input (output with input), gpio_validation_cli (CLI validation).

The example also toggles GPIO0 as output; see GPIO Output (LED).

Operation Steps

1
Prepare the Hardware

On all Ai-M6x boards the button is wired to GPIO2, so just use the onboard button (for an external button: one end to GPIO2, the other end to GND). The example configures GPIO2 as an internal pull-up input, so pressing the button pulls the pin low (reads 0) and releasing it returns high (reads 1).

2
Enter the Example Directory

Open a terminal and enter the GPIO example directory (prerequisite: set up the environment as in Quick Start (Linux) or Windows):

cd examples/peripherals/gpio/gpio_input_output
3
Build the Project

Run the build command. The Ai-M62 (BL616) and Ai-M61 (BL618) belong to the same series, so both use bl616:

make CHIP=bl616 BOARD=bl616dk
4
Flash the Firmware

Connect the board with a USB cable, hold the BOOT button (IO2 on the Ai-M61-32S-Kit), briefly press EN/RST to enter download mode, then flash (replace the serial port with the one on your computer):

make flash CHIP=bl616 COMX=/dev/ttyUSB0
5
Run and Verify

Press the reset button and open a serial tool (baud rate 2000000). The example reads GPIO2 every 2 seconds: GPIO_PIN_2=0 means the button is pressed, GPIO_PIN_2=1 means released.

Code Execution Flow

The complete execution flow from startup to running is shown below (loop arrows mean repeated execution):

APIs Used by the Example

bflb_device_get_by_name("gpio")

Gets the GPIO device handle used by all GPIO operations.

Parameters:

  • name: device name string, always "gpio" for GPIO

Return: struct bflb_device_s * device handle

bflb_gpio_init(gpio, pin, mode)

Configures a pin as input. For button detection the example uses GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0: the internal pull-up keeps the pin high when released, and the Schmitt trigger improves noise immunity.

Parameters:

  • gpio: GPIO device handle
  • pin: pin number, e.g. GPIO_PIN_2 (GPIO2, the button on Ai-M6x boards)
  • mode: mode flags; input uses GPIO_INPUT, optionally combined with GPIO_PULLUP and GPIO_SMT_EN

Return: 0 on success; negative error code on failure

bflb_gpio_read(gpio, pin)

Reads the current input level of a pin to detect whether the button is pressed.

Parameters:

  • gpio: GPIO device handle
  • pin: pin number already configured as input

Return: 0 low level (pressed); 1 high level (released)

bflb_mtimer_delay_ms(ms)

Delays for the given number of milliseconds to control the polling period.

Parameters:

  • ms: delay in milliseconds, 2000 (2 s) in the example

Return: none

Complete Code

The complete source below matches the effect described on this page. It is based on the official example (examples/peripherals/gpio/gpio_input_output); the LED pins are adapted to the Ai-M61/62-32S-Kit onboard RGB LED. Collapsed by default, click to expand:

📜 Click to expand gpio_input_output/main.c full code
c
#include "bflb_gpio.h"
#include "board.h"

struct bflb_device_s *gpio;

int main(void)
{
    board_init();

    gpio = bflb_device_get_by_name("gpio");
    printf("gpio output\r\n");
    bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);
    /* The button on all Ai-M6x boards is wired to GPIO2; configure it as pull-up input */
    bflb_gpio_init(gpio, GPIO_PIN_2, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);

    while (1) {
        bflb_gpio_set(gpio, GPIO_PIN_0);
        printf("GPIO_PIN_2=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_2));
        bflb_mtimer_delay_ms(2000);

        bflb_gpio_reset(gpio, GPIO_PIN_0);
        printf("GPIO_PIN_2=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_2));
        bflb_mtimer_delay_ms(2000);
    }
}

FAQ

The serial port always prints GPIO_PIN_2=1 and the button does nothing

Check the wiring: one end of the button to GPIO2, the other end to GND; verify the pin matches the code (default GPIO_PIN_2).

The button reads 1 when pressed instead of 0

The button is probably wired to VCC or the module is active-high. Connect the other end to GND instead, or switch the input to an internal pull-down and invert the logic.

The polling period is too slow/fast

The example reads every 2 seconds for demonstration. In a real project, reduce bflb_mtimer_delay_ms(2000) (e.g. to 20) and add debounce logic.

Have questions?

For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23