Skip to content
Merged
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
3 changes: 3 additions & 0 deletions ch32fun/ch32fun.h
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,9 @@ extern "C" {
#define DELAY_MS_TIME ((FUNCONF_SYSTEM_CORE_CLOCK)/8000)
#endif

#define DELAY_MSEC_COUNT(n) (DELAY_MS_TIME * n)
#define DELAY_SEC_COUNT(n) (DELAY_MS_TIME * 1000 * n)

#define Delay_Us(n) DelaySysTick( (n) * DELAY_US_TIME )
#define Delay_Ms(n) DelaySysTick( (n) * DELAY_MS_TIME )

Expand Down
11 changes: 11 additions & 0 deletions examples_x035/i2c_sensor_test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
all : flash

TARGET:=i2c_sensor_test
TARGET_MCU:=CH32X033

include ../../ch32fun/ch32fun.mk

flash : cv_flash
clean : cv_clean


50 changes: 50 additions & 0 deletions examples_x035/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

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
7 changes: 7 additions & 0 deletions examples_x035/i2c_sensor_test/funconfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef _FUNCONFIG_H
#define _FUNCONFIG_H

#define FUNCONF_USE_DEBUGPRINTF 1

#endif

143 changes: 143 additions & 0 deletions examples_x035/i2c_sensor_test/i2c_sensor_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#define FUNCONF_SYSTICK_USE_HCLK 1

#include "ch32fun.h"
#include <stdio.h>
#include "lib_i2c.h"

#define I2C_TARGET I2C1
#define SYSTEM_CLOCK_HZ 48000000

// #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);

funPinMode(PA10, GPIO_CFGLR_OUT_50Mhz_AF_PP); // I2C1 SCL
funPinMode(PA11, GPIO_CFGLR_OUT_50Mhz_AF_PP); // 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");

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_MSEC_COUNT(200)) {
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
}
}
}
11 changes: 11 additions & 0 deletions examples_x035/i2c_slave_test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
all : flash

TARGET:=i2c_slave_test
TARGET_MCU:=CH32X033

include ../../ch32fun/ch32fun.mk

flash : cv_flash
clean : cv_clean


7 changes: 7 additions & 0 deletions examples_x035/i2c_slave_test/funconfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef _FUNCONFIG_H
#define _FUNCONFIG_H

#define FUNCONF_USE_DEBUGPRINTF 1

#endif

Loading