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
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).
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_outputRun the build command. The Ai-M62 (BL616) and Ai-M61 (BL618) belong to the same series, so both use bl616:
make CHIP=bl616 BOARD=bl616dkConnect 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/ttyUSB0Press 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 handlepin: pin number, e.g.GPIO_PIN_2(GPIO2, the button on Ai-M6x boards)mode: mode flags; input usesGPIO_INPUT, optionally combined withGPIO_PULLUPandGPIO_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 handlepin: 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
#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

