Skip to content

Commit

Permalink
feature: wip add sd card manager support recovering from sd card gett…
Browse files Browse the repository at this point in the history
…ing disconnected
  • Loading branch information
darrenrahnemoon committed Mar 4, 2024
1 parent d24b6c9 commit 85ff03a
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 18 deletions.
8 changes: 7 additions & 1 deletion boards/communication/src/health.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use atsamd_hal::gpio::{Alternate, Pin, B, PB00, PB01, PB02, PB03, PB05, PB06, PB07, PB08, PB09};
use atsamd_hal::{adc::Adc, ehal::adc::OneShot, pac::ADC0, pac::ADC1};
use common_arm::HealthMonitorChannels;
use common_arm::{HealthMonitorChannels, SdManager};

// make sure to define the ADC types in types.rs

Expand All @@ -13,6 +13,7 @@ use common_arm::HealthMonitorChannels;
pub struct HealthMonitorChannelsCommunication {
reader: Adc<ADC0>,
reader1: Adc<ADC1>,
sd_manager: SdManager,
pin_3v3: Pin<PB01, Alternate<B>>,
pin_5v: Pin<PB02, Alternate<B>>,
pin_pyro: Pin<PB03, Alternate<B>>,
Expand Down Expand Up @@ -52,12 +53,16 @@ impl HealthMonitorChannels for HealthMonitorChannelsCommunication {
fn get_failover(&mut self) -> Option<u16> {
self.reader1.read(&mut self.pin_failover).ok()
}
fn get_sd_status(&mut self) -> Option<bool> {
self.sd_manager.is_mounted()
}
}

impl HealthMonitorChannelsCommunication {
pub fn new(
reader: Adc<ADC0>,
reader1: Adc<ADC1>,
sd_manager: SdManager,
pin_3v3: Pin<PB01, Alternate<B>>,
pin_5v: Pin<PB02, Alternate<B>>,
pin_pyro: Pin<PB03, Alternate<B>>,
Expand All @@ -71,6 +76,7 @@ impl HealthMonitorChannelsCommunication {
HealthMonitorChannelsCommunication {
reader,
reader1,
sd_manager,
pin_3v3,
pin_5v,
pin_pyro,
Expand Down
1 change: 1 addition & 0 deletions boards/communication/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ mod app {
let health_monitor_channels = HealthMonitorChannelsCommunication::new(
adc0,
adc1,
sd_manager,
pins.pb01.into(),
pins.pb02.into(),
pins.pb03.into(),
Expand Down
3 changes: 3 additions & 0 deletions libraries/common-arm/src/health/health_monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub trait HealthMonitorChannels {
fn get_ext_5v(&mut self) -> Option<u16>;
fn get_ext_3v3(&mut self) -> Option<u16>;
fn get_failover(&mut self) -> Option<u16>;
fn get_sd_status(&mut self) -> Option<bool>;
}

pub struct HealthMonitor<T: HealthMonitorChannels> {
Expand Down Expand Up @@ -74,6 +75,7 @@ where
ext_v5: None,
ext_3v3: None,
failover_sense: None,
sd_card: None
},
range_5v,
range_3v3,
Expand Down Expand Up @@ -102,6 +104,7 @@ where
self.data.ext_v5 = self.channels.get_ext_5v();
self.data.ext_3v3 = self.channels.get_ext_3v3();
self.data.failover_sense = self.channels.get_failover();
self.data.sd_card = self.channels.get_sd_status_card();
}
}

Expand Down
66 changes: 49 additions & 17 deletions libraries/common-arm/src/sd_manager.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use core::{fmt::Debug, marker::PhantomData};
use defmt::info;
use defmt::{info, error};
use embedded_hal as hal;
use embedded_sdmmc as sd;
use hal::spi::FullDuplex;

use messages::ErrorContext;
use crate::herror;

/// Time source for `[SdInterface]`. It doesn't return any useful information for now, and will
/// always return an arbitrary time.
pub struct TimeSink {
Expand Down Expand Up @@ -39,8 +42,8 @@ where
CS: hal::digital::v2::OutputPin,
{
pub sd_controller: sd::Controller<sd::SdMmcSpi<SPI, CS>, TimeSink>,
pub volume: sd::Volume,
pub root_directory: sd::Directory,
pub volume: Option<sd::Volume>,
pub root_directory: Option<sd::Directory>,
pub file: Option<sd::File>,
}

Expand All @@ -52,31 +55,33 @@ where
{
pub fn new(spi: SPI, cs: CS) -> Self {
let time_sink: TimeSink = TimeSink::new(); // Need to give this a DateTime object for actual timing.
let mut sd_cont = sd::Controller::new(sd::SdMmcSpi::new(spi, cs), time_sink);
match sd_cont.device().init() {
Ok(_) => match sd_cont.device().card_size_bytes() {
let mut sd_controller = sd::Controller::new(sd::SdMmcSpi::new(spi, cs), time_sink);
match sd_controller.device().init() {
Ok(_) => match sd_controller.device().card_size_bytes() {
Ok(size) => info!("Card is {} bytes", size),
Err(_) => panic!("Cannot get card size"),
Err(_) => error!("Cannot get card size"),
},
Err(_) => {
panic!("Cannot get SD card.");
herror!(Error, ErrorContext::SDCardNotConnected);
}
}

let mut volume = match sd_cont.get_volume(sd::VolumeIdx(0)) {
let mut volume = match sd_controller.get_volume(sd::VolumeIdx(0)) {
Ok(volume) => volume,
Err(_) => {
panic!("Cannot get volume 0");
error!("Cannot get volume 0");
None
}
};

let root_directory = match sd_cont.open_root_dir(&volume) {
let root_directory = match sd_controller.open_root_dir(&volume) {
Ok(root_directory) => root_directory,
Err(_) => {
panic!("Cannot get root");
error!("Cannot get root");
None
}
};
let file = sd_cont.open_file_in_dir(
let file = sd_controller.open_file_in_dir(
&mut volume,
&root_directory,
"log.txt",
Expand All @@ -85,14 +90,15 @@ where
let file = match file {
Ok(file) => file,
Err(_) => {
panic!("Cannot create file.");
error!("Cannot create file.");
None
}
};

SdManager {
sd_controller: sd_cont,
volume,
root_directory,
sd_controller: sd_controller,
volume: Some(volume),
root_directory: Some(root_directory),
file: Some(file),
}
}
Expand All @@ -101,17 +107,26 @@ where
file: &mut sd::File,
buffer: &[u8],
) -> Result<usize, sd::Error<sd::SdMmcError>> {
if !self.is_mounted() {
return sd::Error::DeviceError(());
}
self.sd_controller.write(&mut self.volume, file, buffer)
}
pub fn write_str(
&mut self,
file: &mut sd::File,
msg: &str,
) -> Result<usize, sd::Error<sd::SdMmcError>> {
if !self.is_mounted() {
return sd::Error::DeviceError(());
}
let buffer: &[u8] = msg.as_bytes();
self.sd_controller.write(&mut self.volume, file, buffer)
}
pub fn open_file(&mut self, file_name: &str) -> Result<sd::File, sd::Error<sd::SdMmcError>> {
if !self.is_mounted() {
return sd::Error::DeviceError(());
}
self.sd_controller.open_file_in_dir(
&mut self.volume,
&self.root_directory,
Expand All @@ -120,18 +135,35 @@ where
)
}
pub fn close_current_file(&mut self) -> Result<(), sd::Error<sd::SdMmcError>> {
if !self.is_mounted() {
return sd::Error::DeviceError(());
}
if let Some(file) = self.file.take() {
return self.close_file(file);
}
Ok(())
}
pub fn close_file(&mut self, file: sd::File) -> Result<(), sd::Error<sd::SdMmcError>> {
if !self.is_mounted() {
return sd::Error::DeviceError(());
}
self.sd_controller.close_file(&self.volume, file)
}
pub fn close(mut self) {
if !self.is_mounted() {
return sd::Error::DeviceError(());
}
self.sd_controller
.close_dir(&self.volume, self.root_directory);
}
pub fn is_mounted(mut self) {
// Sd crate doesn't have a check method for SD card being still mounted
// Use `card_size_bytes()` as indicator if device is still connected or not
match self.sd_controller.device().card_size_bytes() {
Ok(size) => true,
Err(_) => false,
}
}
}

unsafe impl<SPI, CS> Send for SdManager<SPI, CS>
Expand Down
1 change: 1 addition & 0 deletions libraries/messages/src/health.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub struct HealthStatus {
pub ext_v5: Option<u16>,
pub ext_3v3: Option<u16>,
pub failover_sense: Option<u16>,
pub sd_card: Option<bool>,
}

impl Health {
Expand Down
2 changes: 2 additions & 0 deletions libraries/messages/src/logging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub enum ErrorContext {
UnknownRadioMessage,
UnkownPostcardMessage,
NoRadioTransfer,
SDCardNotConnected,
}

display_context!(
Expand All @@ -51,4 +52,5 @@ display_context!(
[UnknownRadioMessage, "Unknown radio message received"],
[NoRadioTransfer, "No radio transfer available"],
[UnkownPostcardMessage, "Unknown postcard message received"]
[SDCardNotConnected, "SD Card is not connected"]

Check failure on line 55 in libraries/messages/src/logging/mod.rs

View workflow job for this annotation

GitHub Actions / All

no rules expected the token `[`
);

0 comments on commit 85ff03a

Please sign in to comment.