|
@@ -2,33 +2,37 @@
|
|
|
#![cfg_attr(not(test), no_std)]
|
|
|
#![cfg_attr(not(test), no_main)]
|
|
|
|
|
|
-// pick a panicking behavior
|
|
|
+// custom panic handler
|
|
|
#[cfg(not(test))]
|
|
|
-use core::panic::PanicInfo; // custom panic handler
|
|
|
+use core::panic::PanicInfo;
|
|
|
|
|
|
-// use cortex_m::asm;
|
|
|
use core::{cell::RefCell, ops::DerefMut};
|
|
|
+// use cortex_m::asm;
|
|
|
use cortex_m::{interrupt::free, interrupt::Mutex, peripheral::NVIC};
|
|
|
use cortex_m_rt::entry;
|
|
|
-use cortex_m_semihosting::hprintln;
|
|
|
-// use stm32l4::stm32l4x2::interrupt;
|
|
|
+// use cortex_m_semihosting::hprintln;
|
|
|
use stm32l4xx_hal::{
|
|
|
delay::Delay,
|
|
|
gpio::State,
|
|
|
gpio::{Edge, Input, Output, PullUp, PushPull, PA3, PC15},
|
|
|
+ i2c::I2c,
|
|
|
interrupt, pac,
|
|
|
prelude::*,
|
|
|
rcc,
|
|
|
stm32::Interrupt,
|
|
|
};
|
|
|
|
|
|
+mod tusb322;
|
|
|
+
|
|
|
static FAULT_INT: Mutex<RefCell<Option<PA3<Input<PullUp>>>>> = Mutex::new(RefCell::new(None));
|
|
|
static FAULT_LED: Mutex<RefCell<Option<PC15<Output<PushPull>>>>> = Mutex::new(RefCell::new(None));
|
|
|
|
|
|
#[cfg(not(test))]
|
|
|
#[entry]
|
|
|
fn main() -> ! {
|
|
|
- hprintln!("Hello, world!").unwrap();
|
|
|
+ // Semihosting only works if debugger is connected.
|
|
|
+ // See https://github.com/rust-embedded/cortex-m/issues/289
|
|
|
+ // hprintln!("Hello, world!").unwrap();
|
|
|
|
|
|
// Acquire a singleton instance for the chip's peripherals
|
|
|
let mut dp = pac::Peripherals::take().unwrap();
|
|
@@ -46,8 +50,8 @@ fn main() -> ! {
|
|
|
.pll_source(rcc::PllSource::HSI16)
|
|
|
.sysclk(80.mhz())
|
|
|
.hclk(80.mhz())
|
|
|
- .pclk1(80.mhz())
|
|
|
- .pclk2(80.mhz())
|
|
|
+ .pclk1(40.mhz())
|
|
|
+ .pclk2(40.mhz())
|
|
|
.freeze(&mut flash.acr, &mut pwr);
|
|
|
|
|
|
// Split GPIO peripheral into independent pins and registers
|
|
@@ -75,15 +79,20 @@ fn main() -> ! {
|
|
|
fault_int.enable_interrupt(&mut dp.EXTI);
|
|
|
fault_int.trigger_on_edge(&mut dp.EXTI, Edge::FALLING);
|
|
|
|
|
|
- // Configure NVIC mask to enable interrupt source
|
|
|
- unsafe {
|
|
|
- NVIC::unmask(Interrupt::EXTI3);
|
|
|
- }
|
|
|
+ // Sanity check that fault pin isn't already set (active low) before enabling interrupt
|
|
|
+ if fault_int.is_high().unwrap() {
|
|
|
+ // Configure NVIC mask to enable interrupt source
|
|
|
+ unsafe {
|
|
|
+ NVIC::unmask(Interrupt::EXTI3);
|
|
|
+ }
|
|
|
|
|
|
- // Store fault input in global static variable as it is accessed in interrupt
|
|
|
- free(|cs| {
|
|
|
- FAULT_INT.borrow(cs).replace(Some(fault_int));
|
|
|
- });
|
|
|
+ // Store fault input in global static variable as it is accessed in interrupt
|
|
|
+ free(|cs| {
|
|
|
+ FAULT_INT.borrow(cs).replace(Some(fault_int));
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ panic!();
|
|
|
+ }
|
|
|
|
|
|
// Start with HV PSU disabled (enable pin on PA2)
|
|
|
let mut _hv_en =
|
|
@@ -91,6 +100,23 @@ fn main() -> ! {
|
|
|
.pa2
|
|
|
.into_push_pull_output_with_state(&mut gpioa.moder, &mut gpioa.otyper, State::Low);
|
|
|
|
|
|
+ // Configure I2C SCL
|
|
|
+ let scl = gpioa
|
|
|
+ .pa9
|
|
|
+ .into_open_drain_output(&mut gpioa.moder, &mut gpioa.otyper);
|
|
|
+ let scl = scl.into_af4(&mut gpioa.moder, &mut gpioa.afrh);
|
|
|
+
|
|
|
+ // Configure I2C SDA
|
|
|
+ let sda = gpioa
|
|
|
+ .pa10
|
|
|
+ .into_open_drain_output(&mut gpioa.moder, &mut gpioa.otyper);
|
|
|
+ let sda = sda.into_af4(&mut gpioa.moder, &mut gpioa.afrh);
|
|
|
+
|
|
|
+ // Initialize I2C
|
|
|
+ let mut i2c = I2c::i2c1(dp.I2C1, (scl, sda), 100.khz(), clocks, &mut rcc.apb1r1);
|
|
|
+
|
|
|
+ tusb322::init(&mut i2c);
|
|
|
+
|
|
|
// Configure abstract timer that operates off systick timer
|
|
|
let mut timer = Delay::new(cp.SYST, clocks);
|
|
|
|
|
@@ -102,11 +128,11 @@ fn main() -> ! {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-fn set_fault_led(on: State) {
|
|
|
+fn set_fault_led(state: State) {
|
|
|
free(|cs| {
|
|
|
let mut led_ref = FAULT_LED.borrow(cs).borrow_mut();
|
|
|
if let Some(ref mut led) = led_ref.deref_mut() {
|
|
|
- match on {
|
|
|
+ match state {
|
|
|
State::High => led.set_high().unwrap(),
|
|
|
State::Low => led.set_low().unwrap(),
|
|
|
};
|
|
@@ -120,7 +146,7 @@ fn EXTI3() {
|
|
|
let mut nfault_ref = FAULT_INT.borrow(cs).borrow_mut();
|
|
|
if let Some(ref mut nfault) = nfault_ref.deref_mut() {
|
|
|
if nfault.check_interrupt() {
|
|
|
- hprintln!("Fault pin interrupt triggered!").unwrap();
|
|
|
+ // hprintln!("Fault pin interrupt triggered!").unwrap();
|
|
|
// nfault.clear_interrupt_pending_bit();
|
|
|
panic!();
|
|
|
}
|
|
@@ -131,17 +157,18 @@ fn EXTI3() {
|
|
|
#[panic_handler]
|
|
|
#[cfg(not(test))]
|
|
|
/// Custom panic handler
|
|
|
-fn panic(info: &PanicInfo) -> ! {
|
|
|
- if let Some(location) = info.location() {
|
|
|
- hprintln!(
|
|
|
- "Panic in file '{}' at line {}",
|
|
|
- location.file(),
|
|
|
- location.line()
|
|
|
- )
|
|
|
- .unwrap();
|
|
|
- } else {
|
|
|
- hprintln!("Panic'd!").unwrap();
|
|
|
- }
|
|
|
+fn panic(_info: &PanicInfo) -> ! {
|
|
|
+ // if let Some(location) = info.location() {
|
|
|
+ // hprintln!(
|
|
|
+ // "Panic in file '{}' at line {}",
|
|
|
+ // location.file(),
|
|
|
+ // location.line()
|
|
|
+ // )
|
|
|
+ // .unwrap();
|
|
|
+ // } else {
|
|
|
+ // hprintln!("Panic'd!").unwrap();
|
|
|
+ // }
|
|
|
+ set_fault_led(State::High);
|
|
|
loop {
|
|
|
continue;
|
|
|
}
|