WIP
This commit is contained in:
116
src/main.rs
116
src/main.rs
@@ -1,20 +1,19 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
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
|
||||
// use panic_itm as _; // logs messages over ITM; requires ITM support
|
||||
// use panic_semihosting as _; // logs messages to the host stderr; requires a debugger
|
||||
use cortex_m::interrupt::Mutex;
|
||||
use panic_halt as _;
|
||||
|
||||
use cortex_m_rt::{entry, exception};
|
||||
use cortex_m_semihosting::hprintln;
|
||||
use stm32f1::stm32f103;
|
||||
use stm32f1::stm32f103::interrupt;
|
||||
|
||||
static mut SYS_TICK: u32 = 0;
|
||||
static I2C1: Mutex<RefCell<Option<stm32f103::I2C1>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
fn get_sys_tick() -> u32 {
|
||||
unsafe { read_volatile(&raw const SYS_TICK) }
|
||||
@@ -25,8 +24,8 @@ fn SysTick() {
|
||||
unsafe { SYS_TICK += 1; }
|
||||
}
|
||||
|
||||
fn toggle_mcu_led(peripherals: &mut stm32f103::Peripherals) {
|
||||
peripherals.GPIOA.odr.modify(|r, w| {
|
||||
fn toggle_mcu_led(gpioa: &mut stm32f103::GPIOA) {
|
||||
gpioa.odr.modify(|r, w| {
|
||||
match r.odr3().bit() {
|
||||
true => w.odr3().clear_bit(),
|
||||
false => w.odr3().set_bit(),
|
||||
@@ -34,52 +33,70 @@ 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());
|
||||
fn i2c1_write(addr: &u8, data: &[u8]) {
|
||||
cortex_m::interrupt::free(|cs| {
|
||||
if let Some(ref mut i2c1) = *I2C1.borrow(cs).borrow_mut() {
|
||||
i2c1.cr1.modify(|_,w| w.start().set_bit());
|
||||
|
||||
while i2c1.sr1.read().sb().bit_is_clear() {}
|
||||
|
||||
i2c1.dr.write(|w| w.dr().bits(*addr));
|
||||
|
||||
while i2c1.sr1.read().addr().bit_is_clear() {}
|
||||
let _ = i2c1.sr2.read();
|
||||
|
||||
for byte in data {
|
||||
i2c1.dr.write(|w| w.dr().bits(*byte));
|
||||
while i2c1.sr1.read().tx_e().bit_is_clear() {}
|
||||
}
|
||||
|
||||
while i2c1.sr1.read().btf().bit_is_clear() {}
|
||||
|
||||
i2c1.cr1.modify(|_,w| w.stop().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());
|
||||
#[interrupt]
|
||||
fn I2C1_EV() {
|
||||
cortex_m::interrupt::free(|cs| {
|
||||
if let Some(ref mut i2c1) = *I2C1.borrow(cs).borrow_mut() {
|
||||
if i2c1.sr1.read().addr().bit_is_set() {
|
||||
let _ = i2c1.sr2.read();
|
||||
i2c1.dr.write(|w| w.dr().bits(0xAA));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut peripherals = stm32f103::Peripherals::take().unwrap();
|
||||
let mut core_peripherals = cortex_m::Peripherals::take().unwrap();
|
||||
let peripherals = stm32f103::Peripherals::take().unwrap();
|
||||
let core_peripherals = cortex_m::Peripherals::take().unwrap();
|
||||
|
||||
let mut syst = core_peripherals.SYST;
|
||||
let i2c1 = peripherals.I2C1;
|
||||
let mut gpioa = peripherals.GPIOA;
|
||||
|
||||
// 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
|
||||
core_peripherals.SYST.clear_current(); // Clear the current value register
|
||||
core_peripherals.SYST.enable_counter(); // Enable SysTick
|
||||
syst.set_reload(1_000 - 1); // Set period to 1ms
|
||||
syst.clear_current(); // Clear the current value register
|
||||
syst.enable_counter(); // Enable SysTick
|
||||
|
||||
|
||||
// Enable clock for GPIOA by setting IOPAEN in RCC APB2ENR
|
||||
peripherals.RCC.apb2enr.modify(|_, w| w.iopaen().set_bit());
|
||||
peripherals.GPIOA.crl.modify(|_, w| w.mode3().output());
|
||||
peripherals.GPIOA.crl.modify(|_, w| w.cnf3().push_pull());
|
||||
peripherals.GPIOA.odr.modify(|_, w| w.odr3().high());
|
||||
gpioa.crl.modify(|_, w| w.mode3().output());
|
||||
gpioa.crl.modify(|_, w| w.cnf3().push_pull());
|
||||
gpioa.odr.modify(|_, w| w.odr3().high());
|
||||
|
||||
// Init i2c
|
||||
// Configure i2c clock
|
||||
peripherals.RCC.apb2enr.modify(|_,w| w.iopben().enabled());
|
||||
peripherals.RCC.cfgr.modify(|_, w| w.ppre1().div4());
|
||||
peripherals.RCC.cfgr.modify(|_, w| w.ppre1().div2());
|
||||
peripherals.RCC.apb1enr.modify(|_, w| w.i2c1en().enabled());
|
||||
// Enable i2c clock
|
||||
peripherals.RCC.apb2enr.modify(|_,w| w.iopben().enabled());
|
||||
|
||||
// Set GPIO pin configurations
|
||||
peripherals.GPIOB.crl.modify(|_,w| w.mode6().output50());
|
||||
@@ -89,26 +106,29 @@ fn main() -> ! {
|
||||
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) });
|
||||
i2c1.cr1.modify(|_,w| w.pe().enabled());
|
||||
i2c1.cr1.modify(|_,w| w.smbus().i2c());
|
||||
i2c1.oar1.modify(|_,w| w.add().bits(0x32));
|
||||
i2c1.oar1.modify(|_,w| w.addmode().add7());
|
||||
|
||||
// Pass peripheral reference to global static
|
||||
cortex_m::interrupt::free(|cs| {
|
||||
i2c1.cr2.modify(|_,w| w.itevten().enabled());
|
||||
i2c1.cr2.modify(|_,w| w.itbufen().enabled());
|
||||
*I2C1.borrow(cs).borrow_mut() = Some(i2c1);
|
||||
|
||||
// I don't understand why this is unsafe or how I could make it safe.
|
||||
unsafe { cortex_m::peripheral::NVIC::unmask(stm32f1::stm32f103::interrupt::I2C1_EV); }
|
||||
});
|
||||
|
||||
let mut timer_ms = 500;
|
||||
|
||||
loop {
|
||||
// your code goes here
|
||||
let current_value = get_sys_tick();
|
||||
if current_value >= timer_ms
|
||||
{
|
||||
toggle_mcu_led(&mut peripherals);
|
||||
toggle_mcu_led(&mut gpioa);
|
||||
timer_ms = current_value + 500;
|
||||
let addr: u8 = 0x0a;
|
||||
let data: [u8;4] = [0x01, 0x02, 0x03, 0x04];
|
||||
|
||||
i2c1_write(&peripherals.I2C1, &addr, &data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user