From b932379982fc3acc68a623a579d697f89a00a247 Mon Sep 17 00:00:00 2001 From: ju6ge Date: Wed, 20 Aug 2025 19:39:51 +0200 Subject: [PATCH 1/7] testing i2c slave impl --- Cargo.lock | 1 - Cargo.toml | 3 ++- src/main.rs | 43 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81f6882..15b43b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,7 +65,6 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "ch32-hal" version = "0.1.0" -source = "git+https://github.com/ch32-rs/ch32-hal#2b8e1c864ba5545ee65b1c77dcb17c86a471b70c" dependencies = [ "ch32-metapac 0.1.0", "critical-section", diff --git a/Cargo.toml b/Cargo.toml index ce4fc45..619d9b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,8 @@ version = "0.1.0" edition = "2021" [dependencies] -ch32-hal = { git = "https://github.com/ch32-rs/ch32-hal", features = [ +#ch32-hal = { git = "https://github.com/ch32-rs/ch32-hal", features = [ +ch32-hal = { path = "/home/judge/dev/github.com/ju6ge/ch32-hal", features = [ "ch32v203c8t6", "memory-x", "embassy", diff --git a/src/main.rs b/src/main.rs index 3b2a650..00727b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,12 +3,13 @@ #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_assoc_type)] -mod i2c_slave; - +use ch32_hal::i2c::Duty; +use ch32_hal::time::Hertz; use embassy_executor::Spawner; -use embassy_time::Timer; +use embassy_time::{Duration, Timer}; use hal::bind_interrupts; use hal::gpio::{Level, Output}; +use hal::i2c::{Config, I2c, SlaveAddress, SlaveConfig}; use hal::peripherals::USBD; use hal::usbd::InterruptHandler; use {ch32_hal as hal, panic_halt as _}; @@ -23,11 +24,41 @@ async fn main(_spawner: Spawner) -> ! { let mut led = Output::new(p.PB2, Level::Low, Default::default()); + let mut config = Config::default(); + config.duty = Duty::Duty16_9; + let mut i2c_slave = I2c::new_blocking(p.I2C1, p.PB6, p.PB7, Hertz::khz(400), config) + .into_slave(SlaveConfig { + address: SlaveAddress::SevenBit(0x55), + general_call: false, + }); + + let mut blinks: u8 = 8; loop { Timer::after_millis(1000).await; - //class.write_packet(b"hello world from embassy main\r\n").await; - - led.toggle(); + if blinks > 0 { + led.toggle(); + if led.is_set_low() { + blinks -= 1; + } + } else { + if let Ok(command) = i2c_slave.listen_blocking() { + blinks = 1; + match command { + ch32_hal::i2c::SlaveCommand::GeneralCall => { /* will not be triggered because we disabled it */ }, + ch32_hal::i2c::SlaveCommand::ReadCommand => { + // send empty response + i2c_slave.blocking_write_timeout(&[0x01]); + }, + ch32_hal::i2c::SlaveCommand::WriteCommand => { + let mut buf: [u8; 1] = [0x0]; + i2c_slave.blocking_read_timeout(&mut buf); + blinks = buf[0]; + }, + } + } else { + blinks = 2; + } + } } } From 334b2d94e19841bc77c2e1e4de18e3847387124d Mon Sep 17 00:00:00 2001 From: ju6ge Date: Sun, 28 Dec 2025 13:42:33 +0100 Subject: [PATCH 2/7] enable i2c interrupts --- src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.rs b/src/main.rs index 00727b8..40df2c6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,8 @@ use {ch32_hal as hal, panic_halt as _}; bind_interrupts!(struct Irqs { USB_LP_CAN1_RX0 => InterruptHandler; + I2C1_EV => ch32_hal::i2c::EventInterruptHandler; + I2C1_ER => ch32_hal::i2c::ErrorInterruptHandler; }); #[embassy_executor::main(entry = "qingke_rt::entry")] From e4b62bc4b4265bb3d66652dca5f816f458bd1e7f Mon Sep 17 00:00:00 2001 From: ju6ge Date: Sun, 28 Dec 2025 13:43:03 +0100 Subject: [PATCH 3/7] i2c config adjustments during testing --- src/main.rs | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index 40df2c6..55d111b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,17 +3,21 @@ #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_assoc_type)] -use ch32_hal::i2c::Duty; +use ch32_hal::i2c::{self, Duty}; +use ch32_hal::pac::{self, I2C1}; +use ch32_hal::println; use ch32_hal::time::Hertz; use embassy_executor::Spawner; use embassy_time::{Duration, Timer}; use hal::bind_interrupts; use hal::gpio::{Level, Output}; use hal::i2c::{Config, I2c, SlaveAddress, SlaveConfig}; +use hal::debug::SDIPrint; use hal::peripherals::USBD; use hal::usbd::InterruptHandler; use {ch32_hal as hal, panic_halt as _}; + bind_interrupts!(struct Irqs { USB_LP_CAN1_RX0 => InterruptHandler; I2C1_EV => ch32_hal::i2c::EventInterruptHandler; @@ -23,43 +27,35 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(_spawner: Spawner) -> ! { let p = hal::init(Default::default()); + SDIPrint::enable(); - let mut led = Output::new(p.PB2, Level::Low, Default::default()); - - let mut config = Config::default(); - config.duty = Duty::Duty16_9; - let mut i2c_slave = I2c::new_blocking(p.I2C1, p.PB6, p.PB7, Hertz::khz(400), config) + let config = Config::default(); + let mut i2c_slave = I2c::new_blocking(p.I2C1, p.PB6, p.PB7, Hertz::khz(100), config) .into_slave(SlaveConfig { address: SlaveAddress::SevenBit(0x55), general_call: false, }); - let mut blinks: u8 = 8; loop { - Timer::after_millis(1000).await; + Timer::after_millis(10).await; - if blinks > 0 { - led.toggle(); - if led.is_set_low() { - blinks -= 1; - } - } else { - if let Ok(command) = i2c_slave.listen_blocking() { - blinks = 1; + match i2c_slave.listen_blocking() { + Ok(command) => { match command { - ch32_hal::i2c::SlaveCommand::GeneralCall => { /* will not be triggered because we disabled it */ }, + ch32_hal::i2c::SlaveCommand::GeneralCall => { /* will not be triggered because we disabled it */ + } ch32_hal::i2c::SlaveCommand::ReadCommand => { // send empty response - i2c_slave.blocking_write_timeout(&[0x01]); - }, + let _ = i2c_slave.blocking_write_timeout(&[0x01]); + } ch32_hal::i2c::SlaveCommand::WriteCommand => { let mut buf: [u8; 1] = [0x0]; - i2c_slave.blocking_read_timeout(&mut buf); - blinks = buf[0]; - }, + let _ = i2c_slave.blocking_read_timeout(&mut buf); + } } - } else { - blinks = 2; + }, + Err(err) => { + println!("{:?}", err) } } } From 9e95573553a85b48a1d94a45153a1a47bd41e00e Mon Sep 17 00:00:00 2001 From: ju6ge Date: Sun, 28 Dec 2025 13:43:32 +0100 Subject: [PATCH 4/7] fix openocd cfg --- openocd.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openocd.cfg b/openocd.cfg index fd3d973..9708747 100644 --- a/openocd.cfg +++ b/openocd.cfg @@ -12,6 +12,6 @@ target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME $_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME wch_rsicv 0x00000000 0 0 0 $_TARGETNAME.0 +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 init From d2636108b2408f223f2bcfb04264e39d735154d7 Mon Sep 17 00:00:00 2001 From: ju6ge Date: Mon, 29 Dec 2025 14:29:33 +0100 Subject: [PATCH 5/7] minimal i2c slave example --- src/main.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index 55d111b..c699b99 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,23 +3,16 @@ #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_assoc_type)] -use ch32_hal::i2c::{self, Duty}; -use ch32_hal::pac::{self, I2C1}; use ch32_hal::println; use ch32_hal::time::Hertz; use embassy_executor::Spawner; -use embassy_time::{Duration, Timer}; +//use embassy_time::{Duration, Timer}; use hal::bind_interrupts; -use hal::gpio::{Level, Output}; use hal::i2c::{Config, I2c, SlaveAddress, SlaveConfig}; -use hal::debug::SDIPrint; -use hal::peripherals::USBD; -use hal::usbd::InterruptHandler; use {ch32_hal as hal, panic_halt as _}; bind_interrupts!(struct Irqs { - USB_LP_CAN1_RX0 => InterruptHandler; I2C1_EV => ch32_hal::i2c::EventInterruptHandler; I2C1_ER => ch32_hal::i2c::ErrorInterruptHandler; }); @@ -27,7 +20,6 @@ bind_interrupts!(struct Irqs { #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(_spawner: Spawner) -> ! { let p = hal::init(Default::default()); - SDIPrint::enable(); let config = Config::default(); let mut i2c_slave = I2c::new_blocking(p.I2C1, p.PB6, p.PB7, Hertz::khz(100), config) @@ -37,8 +29,6 @@ async fn main(_spawner: Spawner) -> ! { }); loop { - Timer::after_millis(10).await; - match i2c_slave.listen_blocking() { Ok(command) => { match command { @@ -46,11 +36,12 @@ async fn main(_spawner: Spawner) -> ! { } ch32_hal::i2c::SlaveCommand::ReadCommand => { // send empty response - let _ = i2c_slave.blocking_write_timeout(&[0x01]); + let _ = i2c_slave.blocking_write_timeout(&[0x05, 0x01]); } ch32_hal::i2c::SlaveCommand::WriteCommand => { - let mut buf: [u8; 1] = [0x0]; + let mut buf: [u8; 3] = [0x0, 0x0, 0x0]; let _ = i2c_slave.blocking_read_timeout(&mut buf); + println!("received byte 0x{buf:x?}"); } } }, From a1c1e8ca9f9b72e31e9a5f9f69be6bdfa6f5804e Mon Sep 17 00:00:00 2001 From: ju6ge Date: Mon, 29 Dec 2025 14:31:33 +0100 Subject: [PATCH 6/7] use public fork branch in Cargo.toml instead of local dev path --- Cargo.lock | 165 ++++++++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 2 +- 2 files changed, 144 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15b43b6..ec35180 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" +[[package]] +name = "bitmaps" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d084b0137aaa901caf9f1e8b21daa6aa24d41cd806e111335541eff9683bd6" + [[package]] name = "bms" version = "0.1.0" @@ -40,14 +46,14 @@ dependencies = [ "ch32-metapac 0.0.6", "embassy-executor", "embassy-futures", - "embassy-time", + "embassy-time 0.4.0", "embassy-usb", "embedded-hal 1.0.0", "heapless", "micromath", "panic-halt", - "qingke", - "qingke-rt", + "qingke 0.5.0", + "qingke-rt 0.5.0", ] [[package]] @@ -65,16 +71,19 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "ch32-hal" version = "0.1.0" +source = "git+https://github.com/ju6ge/ch32-hal?branch=feature%2Fi2c-slave-api#9b1df89f5e8de21c7daad0f22fa7186dcfcbecdf" dependencies = [ + "bitmaps", "ch32-metapac 0.1.0", "critical-section", "embassy-futures", "embassy-hal-internal", - "embassy-sync", - "embassy-time", + "embassy-sync 0.7.2", + "embassy-time 0.5.0", "embassy-time-driver", "embassy-time-queue-utils", - "embassy-usb-driver", + "embassy-usb-driver 0.2.0", + "embedded-can", "embedded-hal 0.2.7", "embedded-hal 1.0.0", "embedded-hal-async", @@ -82,8 +91,8 @@ dependencies = [ "futures", "nb 1.1.0", "proc-macro2", - "qingke", - "qingke-rt", + "qingke 0.6.1", + "qingke-rt 0.6.1", "quote", "rand_core", "sdio-host", @@ -181,6 +190,12 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "embassy-executor-timer-queue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c" + [[package]] name = "embassy-futures" version = "0.1.1" @@ -189,9 +204,9 @@ checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" [[package]] name = "embassy-hal-internal" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef3bac31ec146321248a169e9c7b5799f1e0b3829c7a9b324cb4600a7438f59" +checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a" dependencies = [ "num-traits", ] @@ -210,7 +225,7 @@ checksum = "4818c32afec43e3cae234f324bad9a976c9aa7501022d26ff60a4017a1a006b7" dependencies = [ "embassy-futures", "embassy-net-driver", - "embassy-sync", + "embassy-sync 0.6.2", ] [[package]] @@ -227,6 +242,20 @@ dependencies = [ "heapless", ] +[[package]] +name = "embassy-sync" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-core", + "futures-sink", + "heapless", +] + [[package]] name = "embassy-time" version = "0.4.0" @@ -244,21 +273,37 @@ dependencies = [ ] [[package]] -name = "embassy-time-driver" -version = "0.2.0" +name = "embassy-time" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d45f5d833b6d98bd2aab0c2de70b18bfaa10faf661a1578fd8e5dfb15eb7eba" +checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" +dependencies = [ + "cfg-if", + "critical-section", + "document-features", + "embassy-time-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-core", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" dependencies = [ "document-features", ] [[package]] name = "embassy-time-queue-utils" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc55c748d16908a65b166d09ce976575fb8852cf60ccd06174092b41064d8f83" +checksum = "80e2ee86063bd028a420a5fb5898c18c87a8898026da1d4c852af2c443d0a454" dependencies = [ - "embassy-executor", + "embassy-executor-timer-queue", "heapless", ] @@ -270,8 +315,8 @@ checksum = "8d0b882133fa684b9d4652351cd7aac5afe8a2c2bf4a7da59f442ff61087cda2" dependencies = [ "embassy-futures", "embassy-net-driver-channel", - "embassy-sync", - "embassy-usb-driver", + "embassy-sync 0.6.2", + "embassy-usb-driver 0.1.0", "heapless", "ssmarshal", "usbd-hid", @@ -283,6 +328,24 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970" +[[package]] +name = "embassy-usb-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" +dependencies = [ + "embedded-io-async", +] + +[[package]] +name = "embedded-can" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" +dependencies = [ + "nb 1.1.0", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -577,14 +640,36 @@ dependencies = [ "riscv 0.12.1", ] +[[package]] +name = "qingke" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10318bf64fc0befbcd09d7a9a62d8b99972ba3dfdd4a94695f63fd892f47e14e" +dependencies = [ + "bit_field", + "cfg-if", + "critical-section", + "riscv 0.15.0", +] + [[package]] name = "qingke-rt" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b955c60adac70c6d40205b1dbe9f57e1151d06aa842069cdbaef7bc07ad283fd" dependencies = [ - "qingke", - "qingke-rt-macros", + "qingke 0.5.0", + "qingke-rt-macros 0.5.0", +] + +[[package]] +name = "qingke-rt" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ba56c91dd9a044bd519778bcf70644d1d936fee4ea20fdc2d0e3bac8f75fb9" +dependencies = [ + "qingke 0.6.1", + "qingke-rt-macros 0.6.1", ] [[package]] @@ -599,6 +684,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "qingke-rt-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54edcd0e9b8b5c3c83d313c93869325bfcd969d30d9cef1a1015b0970b21be81" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "quote" version = "1.0.40" @@ -633,7 +730,20 @@ dependencies = [ "critical-section", "embedded-hal 1.0.0", "paste", - "riscv-macros", + "riscv-macros 0.1.0", + "riscv-pac", +] + +[[package]] +name = "riscv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05cfa3f7b30c84536a9025150d44d26b8e1cc20ddf436448d74cd9591eefb25" +dependencies = [ + "critical-section", + "embedded-hal 1.0.0", + "paste", + "riscv-macros 0.3.0", "riscv-pac", ] @@ -648,6 +758,17 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "riscv-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d323d13972c1b104aa036bc692cd08b822c8bbf23d79a27c526095856499799" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "riscv-pac" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 619d9b0..2804a16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] #ch32-hal = { git = "https://github.com/ch32-rs/ch32-hal", features = [ -ch32-hal = { path = "/home/judge/dev/github.com/ju6ge/ch32-hal", features = [ +ch32-hal = { git = "https://github.com/ju6ge/ch32-hal", branch = "feature/i2c-slave-api", features = [ "ch32v203c8t6", "memory-x", "embassy", From 51dfc7da8f3bcaadd7d60832fe681f7b15cfa78a Mon Sep 17 00:00:00 2001 From: ju6ge Date: Mon, 29 Dec 2025 14:32:01 +0100 Subject: [PATCH 7/7] use debug binary for loading symbols --- .gdbinit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gdbinit b/.gdbinit index 3263f19..6953b41 100644 --- a/.gdbinit +++ b/.gdbinit @@ -2,6 +2,6 @@ target extended-remote :3333 set remotetimeout 2000 #symbol-file target/riscv32imc-unknown-none-elf/release/ch32v203-examples -file target/riscv32imc-unknown-none-elf/release/bms +file target/riscv32imc-unknown-none-elf/debug/bms monitor reset halt