#![no_std]
#![no_main]
use panic_semihosting as _;
use stm32f3xx_hal as hal;
use cortex_m::asm;
use cortex_m_rt::entry;
use hal::pac;
use hal::prelude::*;
use hal::watchdog::IndependentWatchDog;
use bxcan::filter::Mask32;
use bxcan::{Frame, StandardId};
use hal::can::Can;
use nb::block;
const ID: u16 = 0b100;
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
let mut gpiob = dp.GPIOB.split(&mut rcc.ahb);
let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);
let _clocks = rcc
.cfgr
.use_hse(32.MHz())
.hclk(64.MHz())
.sysclk(64.MHz())
.pclk1(32.MHz())
.pclk2(64.MHz())
.freeze(&mut flash.acr);
let rx = gpioa
.pa11
.into_af_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh);
let tx = gpioa
.pa12
.into_af_push_pull(&mut gpioa.moder, &mut gpioa.otyper, &mut gpioa.afrh);
let mut can = bxcan::Can::builder(Can::new(dp.CAN, tx, rx, &mut rcc.apb1))
.set_bit_timing(0x001c_0003)
.set_loopback(false)
.set_silent(false)
.leave_disabled();
let mut filters = can.modify_filters();
filters.enable_bank(0, Mask32::accept_all());
drop(filters);
block!(can.enable_non_blocking()).ok();
let mut led0 = gpiob
.pb15
.into_push_pull_output(&mut gpiob.moder, &mut gpiob.otyper);
led0.set_high().unwrap();
let mut iwdg = IndependentWatchDog::new(dp.IWDG);
iwdg.stop_on_debug(&dp.DBGMCU, true);
iwdg.start(100.milliseconds());
asm::delay(100_000);
let data: [u8; 1] = [1];
let frame = Frame::new_data(StandardId::new(ID).unwrap(), data);
block!(can.transmit(&frame)).expect("Cannot send first CAN frame");
loop {
let rcv_frame = block!(can.receive()).expect("Cannot receive CAN frame");
if let Some(d) = rcv_frame.data() {
let counter = d[0].wrapping_add(1);
if counter % 3 == 0 {
led0.toggle().unwrap();
}
let data: [u8; 1] = [counter];
let frame = Frame::new_data(StandardId::new(ID).unwrap(), data);
block!(can.transmit(&frame)).expect("Cannot send CAN frame");
}
iwdg.feed();
asm::delay(1_000_000);
}
}