Skip to content
Snippets Groups Projects
Commit a604a98e authored by Samuel Tardieu's avatar Samuel Tardieu
Browse files

Show reset cause on led

parent f076b0fd
No related branches found
No related tags found
No related merge requests found
Pipeline #97519 passed
......@@ -44,6 +44,15 @@ the TB6612FNG motor driver.
- [[https://wiki.dfrobot.com/Micro_DC_Motor_with_Encoder-SJ01_SKU__FIT0450][Wiki]]
* Led pattern
The led pattern is in Morse code.
| Code | Meaning | Pattern |
|------+------------------------------+---------|
| I | Regular reset | .. |
| WW | Reset due to window watchdog | .-- .-- |
* Command set
Multibyte values are exchanged in little endian format.
......
......@@ -7,7 +7,8 @@ use embassy_executor::Spawner;
use embassy_stm32::{
gpio::{Level, Output, Speed},
interrupt::Priority,
peripherals::PB15,
pac,
peripherals::{PB15, RCC},
rcc::{APBPrescaler, Hse, HseMode, Pll, PllMul, PllPreDiv, PllSource, Sysclk},
time::{khz, mhz},
Config,
......@@ -19,6 +20,45 @@ mod encoders;
mod logic;
mod tb6612fng;
#[derive(Clone, Copy, Debug)]
enum ResetCause {
ExternalReset,
WindowWatchdogReset,
IndependentWatchdogReset,
SoftwareReset,
LowPowerManagementReset,
PowerReset,
Unknown,
}
fn reset_cause(_rcc: &mut RCC) -> ResetCause {
// Read reset cause, and reset it
let csr = pac::RCC.csr().read();
pac::RCC.csr().modify(|w| w.set_rmvf(true));
if csr.lpwrrstf() {
ResetCause::LowPowerManagementReset
} else if csr.wwdgrstf() {
ResetCause::WindowWatchdogReset
} else if csr.iwdgrstf() {
ResetCause::IndependentWatchdogReset
} else if csr.sftrstf() {
ResetCause::SoftwareReset
} else if csr.porrstf() {
ResetCause::PowerReset
} else if csr.pinrstf() {
ResetCause::ExternalReset
} else {
ResetCause::Unknown
}
}
fn blink_pattern(reset_cause: ResetCause) -> &'static str {
match reset_cause {
ResetCause::WindowWatchdogReset => ".-- .--", // WW
_ => "..", // I
}
}
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let mut config = Config::default();
......@@ -36,16 +76,20 @@ async fn main(spawner: Spawner) {
});
// APB1 speed (PCLK1) is max 36MHz (SysClk/2), use that
config.rcc.apb1_pre = APBPrescaler::DIV2;
let p = embassy_stm32::init(config);
let mut p = embassy_stm32::init(config);
let reset_cause = reset_cause(&mut p.RCC);
defmt::info!(
"Firmware {}.{}.{} starting",
"Firmware {}.{}.{} starting – reset cause: {}",
logic::PKG_VERSION[0],
logic::PKG_VERSION[1],
logic::PKG_VERSION[2]
logic::PKG_VERSION[2],
defmt::Debug2Format(&reset_cause),
);
spawner.spawn(blink(p.PB15)).unwrap();
spawner
.spawn(blink(p.PB15, blink_pattern(reset_cause)))
.unwrap();
let motors = Tb6612fng::new(
p.PA4,
......@@ -69,12 +113,33 @@ async fn main(spawner: Spawner) {
}
#[embassy_executor::task]
async fn blink(pin: PB15) {
async fn blink(pin: PB15, pattern: &'static str) {
let mut led = Output::new(pin, Level::High, Speed::Low);
loop {
for _ in 0..6 {
led.toggle();
Timer::after_millis(200).await;
for b in pattern.chars() {
match b {
' ' => {
Timer::after_millis(200).await;
}
'.' => {
led.toggle();
Timer::after_millis(150).await;
led.toggle();
Timer::after_millis(200).await;
}
'-' => {
led.toggle();
Timer::after_millis(300).await;
led.toggle();
Timer::after_millis(200).await;
}
_ => {
defmt::error!("unknown pattern letter {}", b);
led.toggle();
Timer::after_secs(5).await;
led.toggle();
}
}
}
Timer::after_secs(1).await;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment