Writing Bare-Metal RISC-V Libraries for CH32V003
The $0.10 Computer
The CH32V003 by WCH is a RISC-V microcontroller that costs about 10 cents. At that price point, it's cheaper than most passive components. But don't let the price fool you — it's a fully capable 32-bit processor running at 48MHz with GPIO, UART, SPI, I2C, ADC, and timers.
Why Bare Metal?
When you have 16KB of flash and 2KB of RAM, every byte counts. There's no room for an RTOS or HAL abstraction layer. Bare-metal programming means talking directly to hardware registers — and that's where the real learning happens.
Writing an I2C Driver
The CH32V003's I2C peripheral is straightforward but requires careful timing. Here's the approach I took:
- Configure GPIO pins for alternate function (I2C SDA/SCL)
- Set up I2C clock prescaler for desired speed (100kHz/400kHz)
- Implement start condition, address phase, data transfer, and stop condition
- Add timeout handling for bus errors
Sensor Libraries
With the I2C driver in place, writing sensor libraries becomes a matter of implementing the sensor's register protocol:
- ADXL345: 3-axis accelerometer with configurable range and data rate
- BMP280: Barometric pressure and temperature with compensation algorithms
- SSD1306: 128x64 OLED display with framebuffer
Lessons Learned
- Always check the errata — the CH32V003 has some undocumented quirks in its I2C peripheral
- Use a logic analyzer — you can't debug I2C with printf when you only have 2KB of RAM
- Keep libraries minimal — each driver should be a single .c/.h pair with no dependencies
- Document register addresses — future you will thank present you
Open Source
All libraries are published on GitHub with MIT license. The goal is to make the CH32V003 as accessible as the Arduino ecosystem, but without the overhead.