Skip to content

Commit b7c9d03

Browse files
authored
Merge pull request #750 from unicab369/ch32x03x_i2c_sensor_example
Ch32x03x i2c sensor example
2 parents 4679e07 + cc0ac1a commit b7c9d03

File tree

9 files changed

+672
-0
lines changed

9 files changed

+672
-0
lines changed

ch32fun/ch32fun.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,9 @@ extern "C" {
875875
#define DELAY_MS_TIME ((FUNCONF_SYSTEM_CORE_CLOCK)/8000)
876876
#endif
877877

878+
#define DELAY_MSEC_COUNT(n) (DELAY_MS_TIME * n)
879+
#define DELAY_SEC_COUNT(n) (DELAY_MS_TIME * 1000 * n)
880+
878881
#define Delay_Us(n) DelaySysTick( (n) * DELAY_US_TIME )
879882
#define Delay_Ms(n) DelaySysTick( (n) * DELAY_MS_TIME )
880883

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
all : flash
2+
3+
TARGET:=i2c_sensor_test
4+
TARGET_MCU:=CH32X033
5+
6+
include ../../ch32fun/ch32fun.mk
7+
8+
flash : cv_flash
9+
clean : cv_clean
10+
11+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# I2C Master Communication Example
2+
3+
This example demonstrates I2C communication with an I2C slave device.
4+
You can use this with (one or the other):
5+
- BH1750 light sensor (actual hardware)
6+
- Another CH32X035 running i2c_slave_test firmware
7+
8+
if you are connecting a CH32X03X to a BH1750, the default slave address for the sensor is 0x23
9+
if you are connecting to another CH32X03X, the default slave address for the slave CH32X03X is 0x66
10+
For the CH32X03X slave, it needs to run the `i2c_slave_test` example
11+
12+
Setup for BH1750 sensor:
13+
- Connect SCL to PA10 (I2C1 SCL)
14+
- Connect SDA to PA11 (I2C1 SDA)
15+
16+
Setup for CH32X03X slave:
17+
- Connect both boards to the same I2C bus
18+
- Connect SCL (PA10) of both boards together
19+
- Connect SDA (PA11) of both boards together
20+
21+
Expected output readings from CH32X03X slave:
22+
Read 1 byte (cmd 0x01): 0x11
23+
Read 2 bytes (cmd 0x13): 0x5D 0x66
24+
Read 4 bytes (cmd 0x14): 0x77 0x88 0x99 0xAA
25+
write buffer (cmd 0x31): successful
26+
Read buffer (cmd 0x30): 0xAA 0xBB 0xCC 0xFF 0xFF
27+
28+
0x3x Slave Command Set:
29+
0x01 - Minick BH1750 Power on command (returns 1 byte)
30+
0x23 - Minmick BH1750 Resolution command (returns 1 byte)
31+
0x13 - Read 2 bytes from slave
32+
0x14 - Read 4 bytes from slave
33+
0x30 - Read from slave's writable buffer (32 bytes)
34+
0x31 - Write to slave's writable buffer (32 bytes)
35+
36+
Command 0x30: Read from writable buffer
37+
Format: { 0x30, start_index }
38+
- start_index: Position to start reading from (0-31)
39+
Since buffer size is 32 bytes (0-31), reading from index 29:
40+
- Returns bytes 29, 30, 31 (3 valid bytes)
41+
- Remaining requested bytes return 0xFF (buffer boundary exceeded)
42+
43+
Command 0x31: Write to writable buffer
44+
Format: { 0x31, start_index, data0, data1, ... }
45+
- start_index: Position to start writing to (0-31)
46+
- dataX: Bytes to write (up to buffer boundary)
47+
Since buffer ends at index 31:
48+
- Writes 0xAA to index 29, 0xBB to index 30, 0xCC to index 31
49+
- 0xDD is not written (buffer full)
50+
- Returns success for written bytes only
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef _FUNCONFIG_H
2+
#define _FUNCONFIG_H
3+
4+
#define FUNCONF_USE_DEBUGPRINTF 1
5+
6+
#endif
7+
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#define FUNCONF_SYSTICK_USE_HCLK 1
2+
3+
#include "ch32fun.h"
4+
#include <stdio.h>
5+
#include "lib_i2c.h"
6+
7+
#define I2C_TARGET I2C1
8+
#define SYSTEM_CLOCK_HZ 48000000
9+
10+
// #define I2C_ADDRESS 0x23 // use this for BH1750
11+
#define I2C_ADDRESS 0x66 // use this for i2c_slave_test
12+
13+
u8 read_state = 0;
14+
15+
void print_ch32_readings(I2C_TypeDef* I2Cx, u8 i2_addr) {
16+
u8 rx_buf[8];
17+
u8 read, err;
18+
19+
switch (read_state) {
20+
case 0:
21+
// read command 0x01: return 1 byte
22+
err = i2c_readReg_buffer(I2Cx, i2_addr, 0x01, rx_buf, 1);
23+
if (!err) {
24+
printf("\nRead 1 byte (cmd 0x01): 0x%02X", rx_buf[0]);
25+
} else {
26+
printf("\nError 0x%02X", err);
27+
}
28+
break;
29+
30+
case 1:
31+
// read command 0x10: return 2 bytes
32+
err = i2c_readReg_buffer(I2Cx, i2_addr, 0x13, rx_buf, 2);
33+
if (!err) {
34+
printf("\nRead 2 bytes (cmd 0x13): ");
35+
for (int i = 0; i < 2; i++) {
36+
printf("0x%02X ", rx_buf[i]);
37+
}
38+
} else {
39+
printf("\nError 0x%02X", err);
40+
}
41+
42+
break;
43+
44+
case 2:
45+
// read command 0x11: return 4 bytes
46+
err = i2c_readReg_buffer(I2Cx, i2_addr, 0x14, rx_buf, 4);
47+
48+
if (!err) {
49+
printf("\nRead 4 bytes (cmd 0x14): ");
50+
for (int i = 0; i < 4; i++) {
51+
printf("0x%02X ", rx_buf[i]);
52+
}
53+
} else {
54+
printf("\nError 0x%02X", err);
55+
}
56+
break;
57+
58+
case 3:
59+
{
60+
// write command 0x31. write buffer
61+
u8 write_request[] = { 0x31, 29, 0xAA, 0xBB, 0xCC, 0xDD };
62+
err = i2c_sendBytes(I2Cx, i2_addr, &write_request, sizeof(write_request));
63+
64+
if (!err) {
65+
printf("\nwrite buffer (cmd 0x%02X): successful", 0x31);
66+
}
67+
if (err) {
68+
printf("\nError 0x%02X", err);
69+
}
70+
break;
71+
}
72+
73+
case 4:
74+
{
75+
// read command 0x30: read buffer
76+
u8 read_request[] = { 0x30, 29 };
77+
err = i2c_readRegTx_buffer(I2Cx, i2_addr, &read_request, sizeof(read_request), &rx_buf, 5);
78+
79+
if (!err) {
80+
printf("\nRead buffer (cmd 0x30): ");
81+
for (int i = 0; i < 5; i++) {
82+
printf("0x%02X ", rx_buf[i]);
83+
}
84+
} else {
85+
printf("\nError 0x%02X", err);
86+
}
87+
printf("\n");
88+
break;
89+
}
90+
91+
default:
92+
break;
93+
}
94+
95+
read_state++;
96+
if (read_state > 4) read_state = 0;
97+
}
98+
99+
u16 get_bh1750_readings(I2C_TypeDef* I2Cx, u8 i2cAddress) {
100+
u8 data[2];
101+
i2c_readReg_buffer(I2Cx, i2cAddress, 0x13, data, 2); // get Reading
102+
u16 raw = (data[0] << 8) | data[1];
103+
return raw * 12 / 10; // Convert to lux
104+
}
105+
106+
void onHandle_ping(u8 i2cAddress) {
107+
printf("Found device: 0x%02X\n", i2cAddress);
108+
}
109+
110+
int main() {
111+
SystemInit();
112+
funGpioInitAll(); // Enable GPIOs
113+
114+
printf("\n~ I2C sensors Example ~\n");
115+
printf("Chip ID: %08lX\n", ESIG->UID0);
116+
printf("Chip Capacity: %d KB\n", ESIG->CAP);
117+
118+
funPinMode(PA10, GPIO_CFGLR_OUT_50Mhz_AF_PP); // I2C1 SCL
119+
funPinMode(PA11, GPIO_CFGLR_OUT_50Mhz_AF_PP); // I2C1 SDA
120+
121+
i2c_init(I2C_TARGET, FUNCONF_SYSTEM_CORE_CLOCK, 100000);
122+
printf("Scanning I2C Bus...\n");
123+
i2c_scan(I2C_TARGET, onHandle_ping);
124+
printf("\nDone.\n");
125+
126+
i2c_sendByte(I2C_TARGET, I2C_ADDRESS, 0x01); // Power on
127+
i2c_sendByte(I2C_TARGET, I2C_ADDRESS, 0x23); // resolution
128+
129+
u32 time_ref = 0;
130+
131+
while(1) {
132+
if (TimeElapsed32(SysTick->CNT, time_ref) > DELAY_MSEC_COUNT(200)) {
133+
time_ref = SysTick->CNT;
134+
135+
#if I2C_ADDRESS == 0x23
136+
u16 lux = get_bh1750_readings(I2C_TARGET, I2C_ADDRESS);
137+
printf("BH1750 Reading: %d lx\n", lux);
138+
#else
139+
print_ch32_readings(I2C_TARGET, I2C_ADDRESS);
140+
#endif
141+
}
142+
}
143+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
all : flash
2+
3+
TARGET:=i2c_slave_test
4+
TARGET_MCU:=CH32X033
5+
6+
include ../../ch32fun/ch32fun.mk
7+
8+
flash : cv_flash
9+
clean : cv_clean
10+
11+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef _FUNCONFIG_H
2+
#define _FUNCONFIG_H
3+
4+
#define FUNCONF_USE_DEBUGPRINTF 1
5+
6+
#endif
7+

0 commit comments

Comments
 (0)