From 726ba905278a0440a1ccb801f28757570d8eb1c4 Mon Sep 17 00:00:00 2001 From: Cristian Eigel Date: Thu, 9 Sep 2021 13:08:41 +0200 Subject: [PATCH] Apply changes suggested by rust-analyzer --- Cargo.toml | 28 ++++++------ src/cycles_computer.rs | 2 +- src/data_reader.rs | 12 +++--- src/main.rs | 98 ++++++++++++++++++++---------------------- src/mp3_player.rs | 11 ++--- src/playlist.rs | 12 ++++-- src/sleep_manager.rs | 1 - src/sound_device.rs | 2 +- src/state.rs | 25 ++++++++--- 9 files changed, 101 insertions(+), 90 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6a3a4d6..7c46597 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -authors = ["Raphael Nestler "] +authors = ["Cristian Eigel "] edition = "2018" readme = "README.md" name = "rfid-audio" @@ -7,34 +7,34 @@ version = "0.1.0" resolver="2" [dependencies] -cortex-m = "0.6.1" -cortex-m-semihosting = "0.3.3" -cortex-m-rtic = "0.5.3" -panic-itm = "0.4.1" -log = {"version"="0.4.8", features=["max_level_info", "release_max_level_info"]} -cortex-m-log = {"version"="0.6.1", features=["itm", "log-integration"]} +cortex-m = "0.7.3" +cortex-m-semihosting = "0.3.7" +cortex-m-rtic = "0.5.7" +panic-itm = "0.4.2" +log = { "version" = "0.4.14", features = ["max_level_info", "release_max_level_info"] } +cortex-m-log = { "version" = "0.7.0", features = ["itm", "log-integration"] } mfrc522 = "0.2.0" -nb = "0.1.1" +nb = "1.0.0" [dependencies.embedded-mp3] version = "0.1.0" -#git = "https://github.com/ceigel/embedded-mp3-rust.git" -path="../embedded-mp3/" +git = "https://github.com/ceigel/embedded-mp3-rust.git" +#path="../embedded-mp3/" [dependencies.stm32l4xx-hal] features = ["stm32l4x1", "rt"] version = "0.6.0" -#git = "https://github.com/stm32-rs/stm32l4xx-hal.git" -path="../stm32l4xx-hal/" +git = "https://github.com/stm32-rs/stm32l4xx-hal.git" +#path="../stm32l4xx-hal/" [dependencies.embedded-sdmmc] -version = "0.3.0" git = "https://github.com/rust-embedded-community/embedded-sdmmc-rs.git" +#path="../embedded-sdmmc-rs/" branch = "develop" [dependencies.cast] default-features = false -version = "0.2" +version = "0.2.7" # this lets you use `cargo fix`! [[bin]] diff --git a/src/cycles_computer.rs b/src/cycles_computer.rs index 1cde771..3e72564 100644 --- a/src/cycles_computer.rs +++ b/src/cycles_computer.rs @@ -14,7 +14,7 @@ impl CyclesComputer { pub fn to_cycles(&self, duration: time::Duration) -> cyccnt::Duration { use rtic::cyccnt::U32Ext; let s_part = (duration.as_secs() as u32) * self.frequency.0; - let mms_part = (duration.subsec_micros() / 1000) * (self.frequency.0 / 1000); + let mms_part = (duration.subsec_millis()) * (self.frequency.0 / 1000); (s_part + mms_part).cycles() } diff --git a/src/data_reader.rs b/src/data_reader.rs index 1b264a7..5b952a4 100644 --- a/src/data_reader.rs +++ b/src/data_reader.rs @@ -93,7 +93,7 @@ where controller .device() .init() - .map_err(|e| sdmmc::Error::DeviceError(e))?; + .map_err(sdmmc::Error::DeviceError)?; controller.device().spi().reclock(freq, clocks); let volume = controller.get_volume(sdmmc::VolumeIdx(0))?; let root_dir = controller.open_root_dir(&volume)?; @@ -124,7 +124,7 @@ where .controller .open_dir(&self.volume, &self.root_dir, directory_name)?; let dir_name = sdmmc::ShortFileName::create_from_str(directory_name) - .map_err(|e| FileError::FilenameError(e))?; + .map_err(FileError::FilenameError)?; Ok(Playlist::new(dir, dir_name)) } @@ -165,15 +165,15 @@ where let mut write_buf: [u8; WRITE_BUF_LEN] = [0; WRITE_BUF_LEN]; let directory_name_bytes = directory_name.as_bytes(); - let mut cards = buf[..sz_read] - .rsplit(|c| *c == '\r' as u8 || *c == '\n' as u8) - .filter(|s| s.len() != 0) + let cards = buf[..sz_read] + .rsplit(|c| *c == b'\r' || *c == b'\n') + .filter(|s| !s.is_empty()) .take(MAX_UNKNOWN) .filter(|n| *n != directory_name_bytes) .chain(core::iter::once(directory_name_bytes)); write_buf[0..BOM.len()].copy_from_slice(&BOM); let mut write_idx = BOM.len(); - while let Some(card) = cards.next() { + for card in cards { write_buf[write_idx..(write_idx + PLAYLIST_NAME_LEN)].copy_from_slice(card); write_idx += PLAYLIST_NAME_LEN; write_buf[write_idx..(write_idx + END_LINE.len())].copy_from_slice(END_LINE.as_bytes()); diff --git a/src/main.rs b/src/main.rs index dbe4294..0f90ace 100644 --- a/src/main.rs +++ b/src/main.rs @@ -115,50 +115,38 @@ pub(crate) type Spi2Type = Spi; fn init_spi1( spi1: hal::stm32::SPI1, - sck: gpioa::PA5>, - miso: gpioa::PA6>, - mosi: gpioa::PA7>, - moder: &mut gpioa::MODER, - afrl: &mut gpioa::AFRL, + sck: gpioa::PA5>>, + miso: gpioa::PA6>>, + mosi: gpioa::PA7>>, apb2: &mut hal::rcc::APB2, clocks: &hal::rcc::Clocks, freq: impl Into, ) -> Spi1Type { - let sck = sck.into_af5(moder, afrl); - let miso = miso.into_af5(moder, afrl); - let mosi = mosi.into_af5(moder, afrl); let spi_mode = embedded_hal::spi::Mode { polarity: embedded_hal::spi::Polarity::IdleLow, phase: embedded_hal::spi::Phase::CaptureOnFirstTransition, }; - let spi = Spi::spi1(spi1, (sck, miso, mosi), spi_mode, freq, *clocks, apb2); - spi + Spi::spi1(spi1, (sck, miso, mosi), spi_mode, freq, *clocks, apb2) } type RFIDReaderType = Mfrc522>>>; fn init_spi2( spi2: hal::stm32::SPI2, - sck: gpiob::PB13>, - miso: gpiob::PB14>, - mosi: gpiob::PB15>, - moder: &mut gpiob::MODER, - afrh: &mut gpiob::AFRH, + sck: gpiob::PB13>>, + miso: gpiob::PB14>>, + mosi: gpiob::PB15>>, apb1: &mut hal::rcc::APB1R1, clocks: &hal::rcc::Clocks, freq: impl Into, ) -> Spi2Type { - let sck = sck.into_af5(moder, afrh); - let miso = miso.into_af5(moder, afrh); - let mosi = mosi.into_af5(moder, afrh); let spi_mode = embedded_hal::spi::Mode { polarity: embedded_hal::spi::Polarity::IdleLow, phase: embedded_hal::spi::Phase::CaptureOnFirstTransition, }; - let spi = Spi::spi2(spi2, (sck, miso, mosi), spi_mode, freq, *clocks, apb1); - spi + Spi::spi2(spi2, (sck, miso, mosi), spi_mode, freq, *clocks, apb1) } fn init_rfid_reader(spi2: Spi2Type, cs2: gpioa::PA8>) -> RFIDReaderType { @@ -223,6 +211,7 @@ const APP: () = { btn_click_debase: rtic::cyccnt::Duration, card_scan_pause: rtic::cyccnt::Duration, battery_reader: battery_voltage::BatteryReader, + charging_line: gpioa::PA15>, user_cyclic_time: rtic::cyccnt::Duration, leds_cyclic_time: rtic::cyccnt::Duration, time_computer: CyclesComputer, @@ -284,11 +273,9 @@ const APP: () = { let spi1 = init_spi1( device.SPI1, - gpioa.pa5, - gpioa.pa6, - gpioa.pa7, - &mut gpioa.moder, - &mut gpioa.afrl, + gpioa.pa5.into_af5(&mut gpioa.moder, &mut gpioa.afrl), + gpioa.pa6.into_af5(&mut gpioa.moder, &mut gpioa.afrl), + gpioa.pa7.into_af5(&mut gpioa.moder, &mut gpioa.afrl), &mut rcc.apb2, &clocks, 250.khz(), @@ -296,11 +283,9 @@ const APP: () = { let spi2 = init_spi2( device.SPI2, - gpiob.pb13, - gpiob.pb14, - gpiob.pb15, - &mut gpiob.moder, - &mut gpiob.afrh, + gpiob.pb13.into_af5(&mut gpiob.moder, &mut gpiob.afrh), + gpiob.pb14.into_af5(&mut gpiob.moder, &mut gpiob.afrh), + gpiob.pb15.into_af5(&mut gpiob.moder, &mut gpiob.afrh), &mut rcc.apb1r1, &clocks, 250.khz(), @@ -347,9 +332,18 @@ const APP: () = { let tim7 = hal::timer::Timer::tim7(device.TIM7, 1.mhz(), clocks, &mut rcc.apb1r1); let mut delay = DelayTimer::new(tim7); - let adc = ADC::new(device.ADC, &mut rcc.ahb2, &mut rcc.ccipr, &mut delay); + let adc = ADC::new( + device.ADC1, + device.ADC_COMMON, + &mut rcc.ahb2, + &mut rcc.ccipr, + &mut delay, + ); let adc_in = gpiob.pb0.into_analog(&mut gpiob.moder, &mut gpiob.pupdr); let battery_reader = battery_voltage::BatteryReader::new(adc, adc_in); + let charging_line = gpioa + .pa15 + .into_floating_input(&mut gpioa.moder, &mut gpioa.pupdr); let buttons = Buttons::new( gpiob.pb12, @@ -393,12 +387,14 @@ const APP: () = { btn_click_debase, card_scan_pause, battery_reader, + charging_line, user_cyclic_time, leds_cyclic_time, time_computer, } } + #[allow(clippy::empty_loop)] #[idle()] fn idle(_cx: idle::Context) -> ! { info!("idle"); @@ -454,16 +450,17 @@ const APP: () = { SleepManager::shut_down(&mut pr.state_leds); } - #[task(resources=[time_computer, battery_reader, playing_resources], schedule=[battery_status, shut_down])] + #[task(resources=[time_computer, battery_reader, charging_line, playing_resources], schedule=[battery_status, shut_down])] fn battery_status(mut cx: battery_status::Context) { let start = rtic::cyccnt::Instant::now(); let val = cx.resources.battery_reader.read(); let tc = cx.resources.time_computer; let elapsed = tc.from_cycles(start.elapsed()); + let charging = cx.resources.charging_line.is_low().unwrap_or(false); let mut shut_down = false; info!("Battery value: {}, elapsed: {}us", val, elapsed.as_micros()); cx.resources.playing_resources.lock(|pr| { - if val < BATTERY_SHUTDOWN_LEVEL { + if val < BATTERY_SHUTDOWN_LEVEL && !charging { pr.sound_device.stop_playing(); pr.state_leds.set_state(state::State::ShuttingDown); shut_down = true; @@ -475,11 +472,12 @@ const APP: () = { .shut_down(cx.scheduled + shutting_down_time) .expect("To be able to schedule shut_down"); error!("Will sleep!"); + } else { + let battery_reader_cyclic_time = tc.to_cycles(BATTERY_READER_CYCLIC_TIME); + cx.schedule + .battery_status(cx.scheduled + battery_reader_cyclic_time) + .expect("To be able to schedule battery_status"); } - let battery_reader_cyclic_time = tc.to_cycles(BATTERY_READER_CYCLIC_TIME); - cx.schedule - .battery_status(cx.scheduled + battery_reader_cyclic_time) - .expect("To be able to schedule battery_status"); } #[task(resources=[playing_resources], priority=8, spawn=[playlist_next])] @@ -529,12 +527,12 @@ const APP: () = { info!("Stop playing: "); pr.sound_device.stop_playing(); info!("Starting playlist: {}", directory_name); - playlist - .take() - .map(|playlist| playlist.close(&mut pr.card_reader)); + if let Some(playlist) = playlist.take() { + playlist.close(&mut pr.card_reader); + } let play_result = pr .card_reader - .open_directory(&directory_name.as_str()) + .open_directory(directory_name.as_str()) .map_err(|e| { error!("Can not open directory: {}, err: {:?}", directory_name, e); pr.state_leds.set_state(state::State::Error); @@ -572,7 +570,7 @@ const APP: () = { Some(playlist) => { let play_result = playlist .move_next(direction, &mut pr.card_reader) - .map_err(|e| PlayError::from(e)) + .map_err(PlayError::from) .and_then(|song| { if let Some(song) = song { let file_name = song.file_name(); @@ -620,16 +618,12 @@ const APP: () = { } else { 1 }; - match pr.sound_device.fill_pcm_buffer( - index, - &mut pr.mp3_player, - current_song, - &mut pr.card_reader, - ) { - Err(_) => { - cx.spawn.playlist_next(true).ok(); - } - _ => {} + if pr + .sound_device + .fill_pcm_buffer(index, &mut pr.mp3_player, current_song, &mut pr.card_reader) + .is_err() + { + cx.spawn.playlist_next(true).ok(); } } DmaState::Stopped => { diff --git a/src/mp3_player.rs b/src/mp3_player.rs index 3a057b4..b0f355a 100644 --- a/src/mp3_player.rs +++ b/src/mp3_player.rs @@ -12,6 +12,7 @@ const MP3_TRIGGER_MOVE: usize = 2 * 1024; pub enum PlayError { FileError(FileError), NotAnMp3, + FileToShort, NoValidMp3Frame, PlaylistFinished, } @@ -41,7 +42,7 @@ impl<'a> Mp3Player<'a> { write_index: 0, mp3_data, decoder: mp3::Decoder::new(), - pcm_buffer: pcm_buffer, + pcm_buffer, last_frame_rate: None, } } @@ -89,10 +90,10 @@ impl<'a> Mp3Player<'a> { if buf[5] & 0x10 != 0 { id3v2size += 10; } - debug!("ID3V2 size is {}", id3v2size); + info!("ID3V2 size is {}", id3v2size); data_reader .seek_from_start(id3v2size) - .map_err(|_| PlayError::NotAnMp3) + .map_err(|_| PlayError::FileToShort) } pub fn fill_buffer( @@ -142,7 +143,7 @@ impl<'a> Mp3Player<'a> { let bytes_red = data_reader.read_data(directory_navigator, out_slice); if bytes_red.is_err() { error!("Error reading data: {:?}", bytes_red); - return bytes_red.map(|_| ()).map_err(|e| PlayError::from(e)); + return bytes_red.map(|_| ()).map_err(PlayError::from); } let bytes_red = bytes_red.unwrap(); self.write_index += bytes_red; @@ -154,7 +155,7 @@ impl<'a> Mp3Player<'a> { let mut index: usize = 0; loop { let mp3: &[u8] = &self.mp3_data[self.read_index..self.write_index]; - if mp3.len() == 0 { + if mp3.is_empty() { return index; } let pcm_buffer = &mut self.pcm_buffer; diff --git a/src/playlist.rs b/src/playlist.rs index a06e0b2..c5e3c9a 100644 --- a/src/playlist.rs +++ b/src/playlist.rs @@ -9,7 +9,7 @@ pub enum PlaylistMoveDirection { } #[derive(Clone, Debug)] -pub struct PlaylistName { +pub(crate) struct PlaylistName { pub name: [u8; PLAYLIST_NAME_LEN], pub name_len: usize, } @@ -45,6 +45,12 @@ impl PartialEq for PlaylistName { } } +impl PartialEq for PlaylistName { + fn eq(&self, other: &PlaylistName) -> bool { + self.name == other.name + } +} + pub struct Playlist { directory: sdmmc::Directory, directory_name: sdmmc::ShortFileName, @@ -60,7 +66,7 @@ impl Playlist { } } - pub fn move_next<'a>( + pub fn move_next( &mut self, dir: PlaylistMoveDirection, directory_navigator: &mut impl DirectoryNavigator, @@ -97,7 +103,7 @@ impl Playlist { } pub fn name(&self) -> sdmmc::ShortFileName { - return self.directory_name.clone(); + self.directory_name.clone() } pub fn close(self, directory_navigator: &mut impl DirectoryNavigator) { diff --git a/src/sleep_manager.rs b/src/sleep_manager.rs index 1f20597..8e36ed5 100644 --- a/src/sleep_manager.rs +++ b/src/sleep_manager.rs @@ -1,6 +1,5 @@ use crate::state::{State, StateLeds}; use core::time::Duration; -use cortex_m; pub struct SleepManager { current_click_count: u32, diff --git a/src/sound_device.rs b/src/sound_device.rs index 7ef8012..32c329d 100644 --- a/src/sound_device.rs +++ b/src/sound_device.rs @@ -35,7 +35,7 @@ pub enum DmaState { Unknown, } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct DebuggingData { pub trigger_complete_count: u32, pub half_trigger_count: u32, diff --git a/src/state.rs b/src/state.rs index 24a70d9..164abec 100644 --- a/src/state.rs +++ b/src/state.rs @@ -134,9 +134,8 @@ impl StateLeds { } fn auto_transition(&mut self) { - match &self.state { - State::PlaylistNotFound => self.set_state(State::NotPlaying), - _ => {} + if let State::PlaylistNotFound = &self.state { + self.set_state(State::NotPlaying); } } @@ -145,10 +144,22 @@ impl StateLeds { State::Error => { self.nose_r.update_modulated(); } - State::Playing => self.nose_g.update_modulated(), - State::NotPlaying => self.nose_b.update_modulated(), - State::PlaylistNotFound => self.nose_r.update_modulated(), - State::ShuttingDown => self.mouth.update_modulated(), + State::Playing => { + self.nose_g.update_modulated(); + self.eye.set_high().expect("Infallible"); + } + State::NotPlaying => { + self.nose_b.update_modulated(); + self.eye.set_high().expect("Infallible"); + } + State::PlaylistNotFound => { + self.nose_r.update_modulated(); + self.eye.set_high().expect("Infallible"); + } + State::ShuttingDown => { + self.mouth.update_modulated(); + self.eye.set_high().expect("Infallible"); + } _ => {} }