-
Notifications
You must be signed in to change notification settings - Fork 267
Ch32v30x i2c test #793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Ch32v30x i2c test #793
Changes from all commits
c7e1907
eea64c5
5620cc2
df7576e
2c54a59
6eadc02
901b6f2
763c281
36ba457
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 |
| 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 | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
| 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 | ||
|
|
| 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) { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
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?)
There was a problem hiding this comment.
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.