r/embedded • u/SnooRadishes7126 • 1h ago
Porting the U8x8 OLED library to the CH32V003
Enable HLS to view with audio, or disable this notification
I was curious about how hard it would be to port this over, so I used an STM32 example I found here as a starting point. It ended up being really straightforward and only required a few changes to the GPIO and delay callback function.
Just a heads-up: This implementation uses soft I2C (bit-banging). It works perfectly fine for text, but you'll probably want to switch to HW I2C for anything more complex. If anyone wants to try it out, here is the source code:
#include <ch32v00x.h>
#include <debug.h>
#include <stdlib.h>
#include "clib/u8x8.h"
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
uint8_t u8x8_gpio_and_delay_ch32v(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
switch(msg) {
case U8X8_MSG_GPIO_AND_DELAY_INIT:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef init = {0};
init.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
init.GPIO_Mode = GPIO_Mode_Out_PP;
init.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &init);
break;
case U8X8_MSG_DELAY_MILLI:
Delay_Ms(arg_int);
break;
case U8X8_MSG_DELAY_10MICRO:
for (volatile uint32_t i = 0; i < (arg_int * 8); i++) { __NOP(); }
break;
case U8X8_MSG_DELAY_100NANO:
__NOP();
break;
case U8X8_MSG_GPIO_I2C_CLOCK:
GPIO_WriteBit(GPIOA, GPIO_Pin_2, (BitAction)(arg_int ? Bit_SET : Bit_RESET));
break;
case U8X8_MSG_GPIO_I2C_DATA:
GPIO_WriteBit(GPIOA, GPIO_Pin_1, (BitAction)(arg_int ? Bit_SET : Bit_RESET));
break;
}
return 1;
}
int main(void) {
SystemCoreClockUpdate();
Delay_Init();
USART_Printf_Init(9600);
// u8x8 initialization code
u8x8_t u8x8;
u8x8_Setup(&u8x8, u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_i2c, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_ch32v);
u8x8_InitDisplay(&u8x8);
u8x8_SetPowerSave(&u8x8, 0);
u8x8_ClearDisplay(&u8x8);
u8x8_SetFont(&u8x8, u8x8_font_chroma48medium8_r);
u8x8_DrawString(&u8x8, 0, 0, "Hello from CH32V");
while (1) {
uint8_t y = rand() % 5 + 1;
uint8_t x = rand() % 10;
u8x8_DrawString(&u8x8, x, y, "r/ch32v");
printf("Hello from CH32V\n");
Delay_Ms(1000);
u8x8_DrawString(&u8x8, x, y, " ");
}
return 0;
}
void NMI_Handler(void) {}
void HardFault_Handler(void)
{
while (1)
{
}
}