Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions examples_ch5xx/uart_send_receive/uart_send_receive.c
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -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));
Expand Down
10 changes: 10 additions & 0 deletions examples_v30x/i2c_sensor_test/Makefile
Original file line number Diff line number Diff line change
@@ -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
50 changes: 50 additions & 0 deletions examples_v30x/i2c_sensor_test/README.md
Original file line number Diff line number Diff line change
@@ -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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct? (This runs on a ch32v30x?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only have the slave example working for Ch32x035, so technically, this code should be able to communicate with a Ch32x035 slave. I haven't test it with v30x.


if you are connecting a CH32X03X to a BH1750, the default slave address for the sensor is 0x23

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would really like a schematic.

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
13 changes: 13 additions & 0 deletions examples_v30x/i2c_sensor_test/funconfig.h
Original file line number Diff line number Diff line change
@@ -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

145 changes: 145 additions & 0 deletions examples_v30x/i2c_sensor_test/i2c_sensor_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include "ch32fun.h"
#include <stdio.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
// #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) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PLEASE stop using tight type specifiers. like u8 when it can just be an int.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XD

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_COUNT(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
}
}
}