#![no_std]
#![no_main]
use cortex_m_rt::entry;
use defmt_rtt as _;
use embedded_hal::i2c::Operation;
use panic_halt as _;
use gd32e2_hal::gpio::Pull;
use gd32e2_hal::i2c::{Error, I2c, I2cMode};
use gd32e2_hal::pac;
use gd32e2_hal::prelude::*;
use gd32e2_hal::rcu::{ClockConfig, PllFreq, SysClk};
const SCL_KHZ: u32 = 50;
const ADDR_FIRST: u8 = 0x08;
const ADDR_LAST: u8 = 0x77;
const REG: u8 = 0x00;
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let mut fmc = dp.fmc.constrain();
let config = ClockConfig::default().sysclk(SysClk::Pll(PllFreq::Mhz48));
let mut rcu = dp.rcu.constrain().freeze(&mut fmc, config);
let clocks = rcu.clocks();
let gpiob = dp.gpiob.split(&mut rcu);
let mut scl = gpiob.pb6.into_alternate_open_drain::<1>();
let mut sda = gpiob.pb7.into_alternate_open_drain::<1>();
scl.set_pull(Pull::Up);
sda.set_pull(Pull::Up);
let mut i2c = I2c::new(
&mut rcu,
dp.i2c0,
sda,
scl,
I2cMode::standard(SCL_KHZ.kHz()),
);
defmt::info!(
"I2C0 scan at {} kHz, pclk1 {} Hz",
SCL_KHZ,
clocks.pclk1().to_Hz()
);
let mut found = None;
for addr in ADDR_FIRST..=ADDR_LAST {
match i2c.write(addr, &[]) {
Ok(()) => {
defmt::info!("{=u8:#04x}: device", addr);
found = found.or(Some(addr));
}
Err(Error::NoAcknowledge(_)) => {}
Err(e) => defmt::error!("{=u8:#04x}: {}", addr, e),
}
}
let Some(addr) = found else {
defmt::warn!("nobody answered — check the pull-ups and the wiring");
loop {
cortex_m::asm::wfi();
}
};
defmt::info!("talking to {=u8:#04x}", addr);
let mut one = [0u8];
match i2c.write_read(addr, &[REG], &mut one) {
Ok(()) => defmt::info!("write_read 1 {=u8:#04x} -> {=u8:#04x}", REG, one[0]),
Err(e) => defmt::error!("write_read 1: {}", e),
}
let mut two = [0u8; 2];
let result = {
let mut ops = [Operation::Write(&[REG]), Operation::Read(&mut two)];
i2c.transaction(addr, &mut ops)
};
match result {
Ok(()) => defmt::info!("transaction 2 {=u8:#04x} -> {=[u8]:#04x}", REG, two),
Err(e) => defmt::error!("transaction 2: {}", e),
}
let mut three = [0u8; 3];
match i2c.read(addr, &mut three) {
Ok(()) => defmt::info!("read 3 -> {=[u8]:#04x}", three),
Err(e) => defmt::error!("read 3: {}", e),
}
let mut four = [0u8; 4];
match i2c.write_read(addr, &[REG], &mut four) {
Ok(()) => defmt::info!("write_read 4 {=u8:#04x} -> {=[u8]:#04x}", REG, four),
Err(e) => defmt::error!("write_read 4: {}", e),
}
defmt::info!("done");
loop {
cortex_m::asm::wfi();
}
}