Exercise: Explore the uFerris BSP
~15-20 min
Goal
Redo your earlier exercises using the uFerris BSP instead of raw HAL calls. See how the BSP simplifies the Instantiate → Configure → Control pattern down to Instantiate → Control.
Steps
Step 1: Create a New Project
esp-generate --chip esp32c3 -o unstable-hal -o vscode -o esp-backtrace -o log --headless bsp_blinky
cd bsp_blinky
Step 2: Read the BSP Source
Open the uFerris BSP crate source code. Don't use it yet — just read it.
Answer these questions:
- How does the BSP map pin numbers to named functions?
- What configuration choices has the BSP author made? (Drive strength? Pull resistors? I2C speed?)
- Can you find the Instantiate → Configure → Control pattern inside the BSP code?
The BSP calls Output::new(), which calls into the HAL, which writes to PAC registers, which toggle actual hardware. Every layer you've learned is present — the BSP just wraps them up.
Step 3: Redo Blinky with BSP
Refactor your blinky exercise to use the BSP. You still need to instantiate the board, then get the LED from it. Notice how the pin number and configuration are no longer your concern.
Step 4: Redo Button Input with BSP
Refactor the button exercise. How does the BSP handle:
- Pin assignment?
- Pull-up configuration?
Step 5: Redo I2C with BSP
Refactor the I2C exercise. The BSP should provide a pre-configured I2C bus — no need to specify pins or clock speed.
Step 6: Examine the Adapter Layer
Look at the BSP source code for the ESP32-C3 adapter:
- How are HAL types mapped to board-level names?
- What abstractions does the adapter provide?
- Could you write an adapter for a different Xiao module?
What to Notice
- The BSP skips Configure — that's the whole point
- The pattern becomes simply Instantiate → Control
- Every layer builds on the one below it