diff --git a/src/main.rs b/src/main.rs index 36f91b3..0eca4ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use core::ptr::read_volatile; +use cortex_m::peripheral; // pick a panicking behavior use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics // use panic_abort as _; // requires nightly @@ -13,9 +14,9 @@ use cortex_m_rt::{entry, exception}; use cortex_m_semihosting::hprintln; use stm32f1::stm32f103; -static mut SYS_TICK: u64 = 0; +static mut SYS_TICK: u32 = 0; -fn get_sys_tick() -> u64 { +fn get_sys_tick() -> u32 { unsafe { read_volatile(&raw const SYS_TICK) } } @@ -33,13 +34,34 @@ fn toggle_mcu_led(peripherals: &mut stm32f103::Peripherals) { }); } +fn i2c1_write(i2c: &stm32f103::I2C1, addr: &u8, data: &[u8]) { + i2c.cr1.modify(|_,w| w.start().set_bit()); + while i2c.sr1.read().sb().bit_is_clear() {} + + i2c.dr.write(|w| w.dr().bits(*addr)); + + while i2c.sr1.read().addr().bit_is_clear() {} + + // 5. Clear the ADDR flag by reading SR2. + let _ = i2c.sr2.read(); + + for byte in data { + i2c.dr.write(|w| w.dr().bits(*byte)); + while i2c.sr1.read().tx_e().bit_is_clear() {} + } + + while i2c.sr1.read().btf().bit_is_clear() {} + + i2c.cr1.modify(|_,w| w.stop().set_bit()); +} #[entry] fn main() -> ! { let mut peripherals = stm32f103::Peripherals::take().unwrap(); let mut core_peripherals = cortex_m::Peripherals::take().unwrap(); + // Enable Cortex-M SysTick peripherals.STK.ctrl.modify(|_,w| w.tickint().set_bit()); // Enable Systick Interrupt core_peripherals.SYST.set_reload(1_000 - 1); // Set period to 1ms @@ -54,11 +76,25 @@ fn main() -> ! { peripherals.GPIOA.odr.modify(|_, w| w.odr3().high()); // Init i2c - // 8MHz SYSCLOCK / 16 = 500khz i2c bus - peripherals.RCC.cfgr.modify(|_, w| w.ppre1().div16()); + // Configure i2c clock + peripherals.RCC.apb2enr.modify(|_,w| w.iopben().enabled()); + peripherals.RCC.cfgr.modify(|_, w| w.ppre1().div4()); peripherals.RCC.apb1enr.modify(|_, w| w.i2c1en().enabled()); - peripherals.RCC.apb1enr.modify(|_, w| w.i2c2en().enabled()); + + // Set GPIO pin configurations + peripherals.GPIOB.crl.modify(|_,w| w.mode6().output50()); + peripherals.GPIOB.crl.modify(|_,w| w.mode7().output50()); + + peripherals.GPIOB.crl.modify(|_,w| w.cnf6().alt_open_drain()); + peripherals.GPIOB.crl.modify(|_,w| w.cnf7().alt_open_drain()); + + // Configure peripheral + peripherals.I2C1.cr2.modify(|_,w| unsafe { w.freq().bits(0x02) }); + peripherals.I2C1.trise.write(|w| w.trise().bits(0x09)); peripherals.I2C1.cr1.modify(|_,w| w.pe().enabled()); + peripherals.I2C1.ccr.modify(|_,w| w.f_s().standard()); + peripherals.I2C1.ccr.modify(|_,w| unsafe { w.ccr().bits(0x04) }); + let mut timer_ms = 500; @@ -69,6 +105,10 @@ fn main() -> ! { { toggle_mcu_led(&mut peripherals); timer_ms = current_value + 500; + let addr: u8 = 0x0a; + let data: [u8;4] = [0x01, 0x02, 0x03, 0x04]; + + i2c1_write(&peripherals.I2C1, &addr, &data); } } }