Lab: GPIO and Peripherals on Real Hardware
Course 1 · Module 3 Type: Hands-on lab (block-by-block, then short integration) Suggested time: 2.5–3 hours
Read first: Lesson · API map · ← Table of Contents · ← M02 · M04 →
Note: the snippets in this lab use the API of the TESAIoT Bitstream firmware, which is not yet open source. See detail and equivalent examples in the public SDK in the note at the top of the lesson GPIO and Peripherals through a Driver API
Useful references during the lab
Section titled “Useful references during the lab”| Document | Use when |
|---|---|
| TESAIoT Developer Hub | GPIO / Sensors / Embedded examples |
| Snippets in the Lesson | The TESA Firmware SDK’s real function names |
| TESAIoT_Hackathon | HEX / Flasher, if using the ready-made pack |
| Bitstream Studio | Watching telemetry (extra) |
Lab Goals
Section titled “Lab Goals”- Control an LED with
led_controller_*(orCy_GPIO_*) - Receive button events with
cm55_button_* - Send a UART log (
printf/LOG_INFO/cm55_uart_send) - Get at least one of: PWM (
bitstream_led_pwm_*) · ADC (cm55_adc_*) · I²C (sensor_sht40_*, or another sensor on your board) working - Fill in the real API names in peripheral-api-map.md
Prerequisites
Section titled “Prerequisites”- Have met the M02 bar
- An example project already linked to the TESA Firmware SDK
- A USB cable + a serial terminal
- Know the kit in hand (AI vs Eval — affects the second button and the POT)
Lab A — GPIO: LED + Button (required)
Section titled “Lab A — GPIO: LED + Button (required)”- Call
led_controller_init(if the project hasn’t already) and tryled_controller_set/led_controller_toggle - Call
cm55_button_init, then bindcm55_button_on_pressed(BUTTON_ID_0, …)to toggle the LED - Flash it and demonstrate it on the board
Pass when: pressing the button reliably changes the LED’s state
/* A short approach — see detail in Lesson §2 */(void)led_controller_init();(void)cm55_button_init();(void)cm55_button_on_pressed(BUTTON_ID_0, on_btn_pressed);Lab B — UART log (required)
Section titled “Lab B — UART log (required)”- In the button callback (or a loop), print a message, such as
btn toggled - Open a terminal on the KitProg3 port at the project’s baud rate
- Confirm the message matches the button event
printf("btn toggled\r\n");/* or */ LOG_INFO("LAB", "btn toggled");Pass when: you see the message matching the button event
Lab C — Choose at least one (required)
Section titled “Lab C — Choose at least one (required)”C1 PWM
Section titled “C1 PWM”(void)bitstream_led_pwm_init();(void)bitstream_led_pwm_set_brightness(0, 20);(void)bitstream_led_pwm_set_brightness(0, 80);Pass when: you can clearly see at least 2 different brightness levels
C2 ADC (Eval kit with POT)
Section titled “C2 ADC (Eval kit with POT)”(void)cm55_adc_init();int16_t mv = cm55_adc_read_pot_mv();printf("POT mV=%d\r\n", (int)mv);Pass when: the value changes when you turn the POT, and can be printed over UART
C3 I²C sensor
Section titled “C3 I²C sensor”(void)sensor_sht40_startup();sht40_sample_t s;if (sensor_sht40_read(&s)) { printf("T=%.2f RH=%.2f\r\n", (double)s.temperature, (double)s.humidity);}(or another sensor on your board — sensor_bmi270_*, etc.)
Pass when: you can read a value and print it over UART
Lab D — Mini integration (recommended)
Section titled “Lab D — Mini integration (recommended)”Combine A+B with the result from C, for example ADC → PWM duty, or a button → switching a mode + a UART log
Delay inside a task:
vTaskDelay(pdMS_TO_TICKS(50));Optional: open Bitstream Studio if the firmware sends telemetry
Short report (5–10 lines)
Section titled “Short report (5–10 lines)”- The BSP / board name
- A table of tasks → the real API name (from the API map)
- The results of Lab A/B/C
Troubleshooting
Section titled “Troubleshooting”| Symptom | How to fix it |
|---|---|
| The LED doesn’t light | The wrong led_id_t · the active level · the BSP not yet initialised |
| The button gives no event | Haven’t called cm55_button_init / bound the callback · used the wrong BUTTON_ID_* |
| UART is silent | The COM port / baud rate · retarget not ready yet · cm55_uart_out_* still locked |
| I²C fails | The sensor isn’t ready · forgot to lock the bus when writing a low-level driver · the wrong address |
| ADC always reads 0 | The kit has no POT · haven’t called cm55_adc_init |
| PWM doesn’t change | Haven’t called bitstream_led_pwm_init · led_id out of range |
Submit checklist
Section titled “Submit checklist”- Lab A passed
- Lab B passed
- Lab C: ≥ 1 item passed
- peripheral-api-map.md filled in
- (Recommended) Lab D
Lesson · API map · Table of Contents · M04 →
Cite this lesson
If you teach from this lesson or reuse it in slides or documents, credit it with the text below. If you changed it, add (adapted) after the title.
"Lab: GPIO and Peripherals on Real Hardware" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0
Thai attribution: "แล็บ: GPIO และอุปกรณ์ต่อพ่วงบนฮาร์ดแวร์จริง" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
Lesson link: https://tesaiot.github.io/tesa-qualification-program/en/courses/firmware-sdk-edge-ai/m03-gpio-peripherals/l02-lab/
This lesson adapts the source below; keep its credit too.
https://github.com/drsanti/TESAIoT-Courses/blob/287c21814ba8c75f693136616dcd270349a15966/C1/M03/lab.md · Original content by Asst. Prof. Dr. Santi Nuratch (ผศ.ดร.สันติ นุราช), KMUTT. Course 1 (C1/) of drsanti/TESAIoT-Courses. TESA funded the work and holds the rights; published here under CC BY-NC 4.0. The upstream repository carries no licence file. Text kept faithful; structure, front matter, quizzes and notes added by TESA Open Knowledge.
TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0
Content is licensed CC BY-NC 4.0. Reuse it non-commercially and credit the Thai Embedded Systems Association (TESA) every time. · How to cite TESA