From c7e1907ea3325596b510f6398989cdab39d39179 Mon Sep 17 00:00:00 2001 From: uni369 Date: Fri, 21 Nov 2025 14:06:54 -0500 Subject: [PATCH 1/3] I2C test for Ch32v30x. --- examples_v30x/i2c_sensor_test/Makefile | 10 ++ examples_v30x/i2c_sensor_test/README.md | 50 ++++++ examples_v30x/i2c_sensor_test/funconfig.h | 13 ++ .../i2c_sensor_test/i2c_sensor_test.c | 144 ++++++++++++++++++ 4 files changed, 217 insertions(+) create mode 100644 examples_v30x/i2c_sensor_test/Makefile create mode 100644 examples_v30x/i2c_sensor_test/README.md create mode 100644 examples_v30x/i2c_sensor_test/funconfig.h create mode 100644 examples_v30x/i2c_sensor_test/i2c_sensor_test.c diff --git a/examples_v30x/i2c_sensor_test/Makefile b/examples_v30x/i2c_sensor_test/Makefile new file mode 100644 index 00000000..de09109f --- /dev/null +++ b/examples_v30x/i2c_sensor_test/Makefile @@ -0,0 +1,10 @@ +all : flash + +TARGET:=i2c_sensor_test +TARGET_MCU:=CH32V303 +TARGET_MCU_PACKAGE:=CH32V303 + +include ../../ch32fun/ch32fun.mk + +flash : cv_flash +clean : cv_clean \ No newline at end of file diff --git a/examples_v30x/i2c_sensor_test/README.md b/examples_v30x/i2c_sensor_test/README.md new file mode 100644 index 00000000..f7d53ce2 --- /dev/null +++ b/examples_v30x/i2c_sensor_test/README.md @@ -0,0 +1,50 @@ +# I2C Master Communication Example + +This example demonstrates I2C communication with an I2C slave device. +You can use this with (one or the other): +- BH1750 light sensor (actual hardware) +- Another CH32X035 running i2c_slave_test firmware + +if you are connecting a CH32X03X to a BH1750, the default slave address for the sensor is 0x23 +if you are connecting to another CH32X03X, the default slave address for the slave CH32X03X is 0x66 +For the CH32X03X slave, it needs to run the `i2c_slave_test` example + +Setup for BH1750 sensor: +- Connect SCL to PA10 (I2C1 SCL) +- Connect SDA to PA11 (I2C1 SDA) + +Setup for CH32X03X slave: +- Connect both boards to the same I2C bus +- Connect SCL (PA10) of both boards together +- Connect SDA (PA11) of both boards together + +Expected output readings from CH32X03X slave: +Read 1 byte (cmd 0x01): 0x11 +Read 2 bytes (cmd 0x13): 0x5D 0x66 +Read 4 bytes (cmd 0x14): 0x77 0x88 0x99 0xAA +write buffer (cmd 0x31): successful +Read buffer (cmd 0x30): 0xAA 0xBB 0xCC 0xFF 0xFF + +0x3x Slave Command Set: +0x01 - Minick BH1750 Power on command (returns 1 byte) +0x23 - Minmick BH1750 Resolution command (returns 1 byte) +0x13 - Read 2 bytes from slave +0x14 - Read 4 bytes from slave +0x30 - Read from slave's writable buffer (32 bytes) +0x31 - Write to slave's writable buffer (32 bytes) + +Command 0x30: Read from writable buffer +Format: { 0x30, start_index } +- start_index: Position to start reading from (0-31) +Since buffer size is 32 bytes (0-31), reading from index 29: +- Returns bytes 29, 30, 31 (3 valid bytes) +- Remaining requested bytes return 0xFF (buffer boundary exceeded) + +Command 0x31: Write to writable buffer +Format: { 0x31, start_index, data0, data1, ... } +- start_index: Position to start writing to (0-31) +- dataX: Bytes to write (up to buffer boundary) +Since buffer ends at index 31: +- Writes 0xAA to index 29, 0xBB to index 30, 0xCC to index 31 +- 0xDD is not written (buffer full) +- Returns success for written bytes only diff --git a/examples_v30x/i2c_sensor_test/funconfig.h b/examples_v30x/i2c_sensor_test/funconfig.h new file mode 100644 index 00000000..18486fdd --- /dev/null +++ b/examples_v30x/i2c_sensor_test/funconfig.h @@ -0,0 +1,13 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_SYSTICK_USE_HCLK 1 +#define FUNCONF_USE_HSI 1 +#define FUNCONF_USE_PLL 0 +#define FUNCONF_PLL_MULTIPLIER 2 + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_SYSTEM_CORE_CLOCK 8 * 1000 * 1000 + +#endif + diff --git a/examples_v30x/i2c_sensor_test/i2c_sensor_test.c b/examples_v30x/i2c_sensor_test/i2c_sensor_test.c new file mode 100644 index 00000000..44802ea6 --- /dev/null +++ b/examples_v30x/i2c_sensor_test/i2c_sensor_test.c @@ -0,0 +1,144 @@ +#include "ch32fun.h" +#include +#include "lib_i2c.h" + +#define I2C_TARGET I2C1 +#define I2C_ADDRESS 0x23 // use this for BH1750 +// #define I2C_ADDRESS 0x66 // use this for i2c_slave_test + +u8 read_state = 0; + +void print_ch32_readings(I2C_TypeDef* I2Cx, u8 i2_addr) { + u8 rx_buf[8]; + u8 read, err; + + switch (read_state) { + case 0: + // read command 0x01: return 1 byte + err = i2c_readReg_buffer(I2Cx, i2_addr, 0x01, rx_buf, 1); + if (!err) { + printf("\nRead 1 byte (cmd 0x01): 0x%02X", rx_buf[0]); + } else { + printf("\nError 0x%02X", err); + } + break; + + case 1: + // read command 0x10: return 2 bytes + err = i2c_readReg_buffer(I2Cx, i2_addr, 0x13, rx_buf, 2); + if (!err) { + printf("\nRead 2 bytes (cmd 0x13): "); + for (int i = 0; i < 2; i++) { + printf("0x%02X ", rx_buf[i]); + } + } else { + printf("\nError 0x%02X", err); + } + + break; + + case 2: + // read command 0x11: return 4 bytes + err = i2c_readReg_buffer(I2Cx, i2_addr, 0x14, rx_buf, 4); + + if (!err) { + printf("\nRead 4 bytes (cmd 0x14): "); + for (int i = 0; i < 4; i++) { + printf("0x%02X ", rx_buf[i]); + } + } else { + printf("\nError 0x%02X", err); + } + break; + + case 3: + { + // write command 0x31. write buffer + u8 write_request[] = { 0x31, 29, 0xAA, 0xBB, 0xCC, 0xDD }; + err = i2c_sendBytes(I2Cx, i2_addr, &write_request, sizeof(write_request)); + + if (!err) { + printf("\nwrite buffer (cmd 0x%02X): successful", 0x31); + } + if (err) { + printf("\nError 0x%02X", err); + } + break; + } + + case 4: + { + // read command 0x30: read buffer + u8 read_request[] = { 0x30, 29 }; + err = i2c_readRegTx_buffer(I2Cx, i2_addr, &read_request, sizeof(read_request), &rx_buf, 5); + + if (!err) { + printf("\nRead buffer (cmd 0x30): "); + for (int i = 0; i < 5; i++) { + printf("0x%02X ", rx_buf[i]); + } + } else { + printf("\nError 0x%02X", err); + } + printf("\n"); + break; + } + + default: + break; + } + + read_state++; + if (read_state > 4) read_state = 0; +} + +u16 get_bh1750_readings(I2C_TypeDef* I2Cx, u8 i2cAddress) { + u8 data[2]; + i2c_readReg_buffer(I2Cx, i2cAddress, 0x13, data, 2); // get Reading + u16 raw = (data[0] << 8) | data[1]; + return raw * 12 / 10; // Convert to lux +} + +void onHandle_ping(u8 i2cAddress) { + printf("Found device: 0x%02X\n", i2cAddress); +} + +int main() { + SystemInit(); + funGpioInitAll(); // Enable GPIOs + + printf("\n~ I2C sensors Example ~\n"); + printf("Chip ID: %08lX\n", ESIG->UID0); + printf("Chip Capacity: %d KB\n", ESIG->CAP); + + if (I2C_TARGET == I2C1) { + funPinMode(PB6, GPIO_CFGLR_OUT_50Mhz_AF_OD); // I2C1 SCL + funPinMode(PB7, GPIO_CFGLR_OUT_50Mhz_AF_OD); // I2C1 SDA + } else { + funPinMode(PB10, GPIO_CFGLR_OUT_50Mhz_AF_OD); // I2C1 SCL + funPinMode(PB11, GPIO_CFGLR_OUT_50Mhz_AF_OD); // I2C1 SDA + } + + i2c_init(I2C_TARGET, FUNCONF_SYSTEM_CORE_CLOCK, 100000); + printf("Scanning I2C Bus...\n"); + i2c_scan(I2C_TARGET, onHandle_ping); + printf("\nDone.\n\n"); + + i2c_sendByte(I2C_TARGET, I2C_ADDRESS, 0x01); // Power on + i2c_sendByte(I2C_TARGET, I2C_ADDRESS, 0x23); // resolution + + u32 time_ref = 0; + + while(1) { + if (TimeElapsed32(SysTick->CNT, time_ref) > DELAY_SEC_TIME(1)) { + time_ref = SysTick->CNT; + + #if I2C_ADDRESS == 0x23 + u16 lux = get_bh1750_readings(I2C_TARGET, I2C_ADDRESS); + printf("BH1750 Reading: %d lx\n", lux); + #else + print_ch32_readings(I2C_TARGET, I2C_ADDRESS); + #endif + } + } +} From 2c54a59e493139d7740a6d7d4d4667f7cb003936 Mon Sep 17 00:00:00 2001 From: uni369 Date: Fri, 28 Nov 2025 11:06:06 -0500 Subject: [PATCH 2/3] bug fix. --- examples_ch5xx/uart_send_receive/uart_send_receive.c | 4 +--- examples_v30x/i2c_sensor_test/i2c_sensor_test.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples_ch5xx/uart_send_receive/uart_send_receive.c b/examples_ch5xx/uart_send_receive/uart_send_receive.c index 4e1e61b2..6be3be26 100644 --- a/examples_ch5xx/uart_send_receive/uart_send_receive.c +++ b/examples_ch5xx/uart_send_receive/uart_send_receive.c @@ -9,8 +9,6 @@ // R32_UART2_CTRL: RX PA6, TX PA7 // R32_UART3_CTRL: RX PA4, TX PA5 -#define DELAY_SEC_TIME(n) (DELAY_MS_TIME * 1000 * n) - #define TARGET_UART &R32_UART3_CTRL u32 get_tickCount() { return SysTick->CNT; } @@ -41,7 +39,7 @@ int main() { u32 time_ref = get_tickCount(); while(1) { - if (TimeElapsed32(get_tickCount(), time_ref) > DELAY_SEC_TIME(1)) { + if (TimeElapsed32(get_tickCount(), time_ref) > DELAY_SEC_COUNT(1)) { time_ref = get_tickCount(); printf("send: %s\r\n", msg); uart_send_ch5xx(TARGET_UART, msg, sizeof(msg)); diff --git a/examples_v30x/i2c_sensor_test/i2c_sensor_test.c b/examples_v30x/i2c_sensor_test/i2c_sensor_test.c index 44802ea6..6a94af9c 100644 --- a/examples_v30x/i2c_sensor_test/i2c_sensor_test.c +++ b/examples_v30x/i2c_sensor_test/i2c_sensor_test.c @@ -130,7 +130,7 @@ int main() { u32 time_ref = 0; while(1) { - if (TimeElapsed32(SysTick->CNT, time_ref) > DELAY_SEC_TIME(1)) { + if (TimeElapsed32(SysTick->CNT, time_ref) > DELAY_SEC_COUNT(1)) { time_ref = SysTick->CNT; #if I2C_ADDRESS == 0x23 From 763c2814581f44c8e387a66e5b471bbf38a0a5a4 Mon Sep 17 00:00:00 2001 From: uni369 Date: Tue, 9 Dec 2025 12:11:49 -0500 Subject: [PATCH 3/3] update. --- examples_v30x/i2c_sensor_test/i2c_sensor_test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples_v30x/i2c_sensor_test/i2c_sensor_test.c b/examples_v30x/i2c_sensor_test/i2c_sensor_test.c index 6a94af9c..e0e2565c 100644 --- a/examples_v30x/i2c_sensor_test/i2c_sensor_test.c +++ b/examples_v30x/i2c_sensor_test/i2c_sensor_test.c @@ -1,6 +1,7 @@ #include "ch32fun.h" #include -#include "lib_i2c.h" +// #include "lib_i2c.h" +#include "../../examples_x035/i2c_sensor_test/lib_i2c.h" #define I2C_TARGET I2C1 #define I2C_ADDRESS 0x23 // use this for BH1750