ch32-rs/ch32-hal

V003: is i2c ready?

Closed this issue · 4 comments

Hi,
Thank you for this nice work, I understand that this is a work in progress.
But is the i2c supposed to work on the CH32V003?
I have tried a simple program but the system hangs in the I2c::new() part (I can see the println logs)):

#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]

use hal::dma::NoDma;
use hal::i2c::I2c;
use hal::println;
use hal::time::Hertz;
use qingke::riscv;
use {ch32_hal as hal, panic_halt as _};

#[qingke_rt::entry]
fn main() -> ! {
    let mut config = hal::Config::default();
    config.clock = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSE;
    let p = hal::init(config);
    hal::debug::SDIPrint::enable();

    println!("i2c test");

    // I2C pins
    let i2c_sda = p.PC1;
    let i2c_scl = p.PC2;

    println!("init i2c...");
    // Initialize i2c peripheral
    let i2c = I2c::new(
        p.I2C1,
        i2c_scl,
        i2c_sda,
        NoDma,
        NoDma,
        Hertz::khz(100),
        Default::default(),
    );
    println!("Done");
    loop {}
}

I have noticed that there is no example with i2c for the v003 so it might not be ready yet?
I have tried to debug with minichlink -G and gdb but without success, my breakpoint in main is never reached. How do you debug the ch32 ?

config.clock = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSE;

Remove this. Use the default 24MHz HSI clock. The datasheet says I2C's input clock should not be > 36MHz.

Thanks a lot, it works now!

#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]

use hal::dma::NoDma;
use hal::i2c::I2c;
use hal::time::Hertz;
use {ch32_hal as hal, panic_halt as _};

use embedded_graphics::{
    mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
    pixelcolor::BinaryColor,
    prelude::*,
    text::{Baseline, Text},
};
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};

#[qingke_rt::entry]
fn main() -> ! {
    let p = hal::init(Default::default());

    // I2C pins
    let i2c_sda = p.PC1;
    let i2c_scl = p.PC2;

    // Initialize i2c peripheral
    let i2c = I2c::new(
        p.I2C1,
        i2c_scl,
        i2c_sda,
        NoDma,
        NoDma,
        Hertz::khz(100),
        Default::default(),
    );

    let interface = I2CDisplayInterface::new(i2c);
    let mut display =
        Ssd1306::new(interface, DisplaySize128x32, DisplayRotation::Rotate0).into_buffered_graphics_mode();
    display.init().unwrap();

    let text_style = MonoTextStyleBuilder::new()
        .font(&FONT_6X10)
        .text_color(BinaryColor::On)
        .build();

    Text::with_baseline("Hello Rust!", Point::zero(), text_style, Baseline::Top)
        .draw(&mut display)
        .unwrap();

    Text::with_baseline("From CH32V003", Point::new(0, 16), text_style, Baseline::Top)
        .draw(&mut display)
        .unwrap();

    display.flush().unwrap();

    loop {}
}

IMG_20240410_231006

Feel free to add your demo code to the examples directory.
Any kind of contribution is welcomed.

And I made a mistake, the default clock is 8MHz, HSI div 3.
The old RM datasheet is wrong. I should use the newest one.