Skip to content

Commit

Permalink
Finish saving and reading of playlist mementos
Browse files Browse the repository at this point in the history
ceigel committed Dec 29, 2021
1 parent 2a9aa76 commit 53b5bac
Showing 8 changed files with 193 additions and 243 deletions.
10 changes: 3 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -17,8 +17,8 @@ nb = "1.0.0"

[dependencies.mfrc522]
version = "0.2.0"
#git="https://github.com/ceigel/mfrc522.git"
path="../mfrc522"
git="https://github.com/ceigel/mfrc522.git"
#path="../mfrc522"

[dependencies.embedded-mp3]
version = "0.1.0"
@@ -35,10 +35,6 @@ git = "https://github.com/rust-embedded-community/embedded-sdmmc-rs.git"
#path="../embedded-sdmmc-rs/"
rev = "8d27bebbf75623e5e52b63c7f41fa63ee04142ab"

[dependencies.cast]
default-features = false
version = "0.2.7"

# this lets you use `cargo fix`!
[[bin]]
name = "rfid-audio"
@@ -55,5 +51,5 @@ opt-level = 3
opt-level='z'

[profile.dev.package."*"]
opt-level=3
opt-level='z'
debug = true # symbols are nice and they don't increase the size on Flash
177 changes: 60 additions & 117 deletions src/data_reader.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ const BOM: [u8; 3] = [0xEF, 0xBB, 0xBF];
struct DummyTimeSource {}
impl sdmmc::TimeSource for DummyTimeSource {
fn get_timestamp(&self) -> sdmmc::Timestamp {
sdmmc::Timestamp::from_calendar(2020, 3, 7, 13, 23, 0).expect("To create date")
sdmmc::Timestamp::from_calendar(2020, 3, 7, 13, 23, 0).unwrap()
}
}

@@ -26,10 +26,7 @@ pub struct DataReader {
}

impl DataReader {
pub fn open_direntry(
directory_navigator: &mut impl DirectoryNavigator,
dir_entry: &sdmmc::DirEntry,
) -> Result<DataReader, FileError> {
pub fn open_direntry(directory_navigator: &mut impl DirectoryNavigator, dir_entry: &sdmmc::DirEntry) -> Result<DataReader, FileError> {
let file = directory_navigator.open_direntry(dir_entry)?;
Ok(DataReader {
file,
@@ -45,11 +42,7 @@ impl DataReader {
directory_navigator.open_file_in_dir(file_name, directory)
}

pub fn read_data(
&mut self,
directory_navigator: &mut impl DirectoryNavigator,
out: &mut [u8],
) -> Result<usize, FileError> {
pub fn read_data(&mut self, directory_navigator: &mut impl DirectoryNavigator, out: &mut [u8]) -> Result<usize, FileError> {
directory_navigator.read_data(&mut self.file, out)
}

@@ -73,10 +66,7 @@ impl DataReader {
self.file.seek_from_start(offset)
}

pub fn close_file(
self,
directory_navigator: &mut impl DirectoryNavigator,
) -> Result<(), FileError> {
pub fn close_file(self, directory_navigator: &mut impl DirectoryNavigator) -> Result<(), FileError> {
directory_navigator.close_file(self.file)
}
}
@@ -94,18 +84,10 @@ impl<CS> SdCardReader<CS>
where
CS: embedded_hal::digital::v2::OutputPin,
{
pub fn new(
spi: Spi1Type,
cs: CS,
freq: impl Into<Hertz>,
clocks: Clocks,
) -> Result<Self, FileError> {
pub fn new(spi: Spi1Type, cs: CS, freq: impl Into<Hertz>, clocks: Clocks) -> Result<Self, FileError> {
let ts = DummyTimeSource {};
let mut controller = sdmmc::Controller::new(sdmmc::SdMmcSpi::new(spi, cs), ts);
controller
.device()
.init()
.map_err(sdmmc::Error::DeviceError)?;
controller.device().init().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)?;
@@ -117,10 +99,7 @@ where
}

pub fn open_directory(&mut self, directory_name: &str) -> Result<Playlist, FileError> {
match self
.controller
.find_directory_entry(&self.volume, &self.root_dir, directory_name)
{
match self.controller.find_directory_entry(&self.volume, &self.root_dir, directory_name) {
Ok(_) => self.open_existing_directory(directory_name),
Err(FileError::FileNotFound) => {
error!("directory {} not found", directory_name);
@@ -132,46 +111,28 @@ where
}

fn open_existing_directory(&mut self, directory_name: &str) -> Result<Playlist, FileError> {
let dir = self
.controller
.open_dir(&self.volume, &self.root_dir, directory_name)?;
let dir_name = sdmmc::ShortFileName::create_from_str(directory_name)
.map_err(FileError::FilenameError)?;
let dir = self.controller.open_dir(&self.volume, &self.root_dir, directory_name)?;
let dir_name = sdmmc::ShortFileName::create_from_str(directory_name).map_err(FileError::FilenameError)?;
Ok(Playlist::new(dir, dir_name))
}

fn directory_not_found(&mut self, directory_name: &str) -> Result<(), FileError> {
let mut buf: [u8; sdmmc::Block::LEN] = [0; sdmmc::Block::LEN];
let sz_read =
match self
.controller
.find_directory_entry(&self.volume, &self.root_dir, LOGGING_FILE)
{
Ok(dir_entry) => {
let mut log_file = self.controller.open_dir_entry(
&mut self.volume,
dir_entry,
sdmmc::Mode::ReadOnly,
)?;
if log_file.length() as usize > buf.len() {
log_file
.seek_from_end(buf.len() as u32)
.expect("To be able to seek inside log file");
} else if log_file.length() > 0 {
log_file
.seek_from_start(BOM.len() as u32)
.expect("To be able to seek inside log file");
}
let sz_read = self
.controller
.read(&self.volume, &mut log_file, &mut buf)
.unwrap_or_default();
self.controller.close_file(&self.volume, log_file).ok();
sz_read
let sz_read = match self.controller.find_directory_entry(&self.volume, &self.root_dir, LOGGING_FILE) {
Ok(dir_entry) => {
let mut log_file = self.controller.open_dir_entry(&mut self.volume, dir_entry, sdmmc::Mode::ReadOnly)?;
if log_file.length() as usize > buf.len() {
log_file.seek_from_end(buf.len() as u32).unwrap();
} else if log_file.length() > 0 {
log_file.seek_from_start(BOM.len() as u32).unwrap();
}
Err(FileError::FileNotFound) => 0,
Err(e) => return Err(e),
};
let sz_read = self.controller.read(&self.volume, &mut log_file, &mut buf).unwrap_or_default();
self.controller.close_file(&self.volume, log_file).ok();
sz_read
}
Err(FileError::FileNotFound) => 0,
Err(e) => return Err(e),
};

const WRITE_BUF_LEN: usize = MAX_UNKNOWN * LOG_LINE_LEN + BOM.len();
let mut write_buf: [u8; WRITE_BUF_LEN] = [0; WRITE_BUF_LEN];
@@ -192,14 +153,10 @@ where
write_idx += END_LINE.len();
}

let mut log_file = self.controller.open_file_in_dir(
&mut self.volume,
&self.root_dir,
LOGGING_FILE,
sdmmc::Mode::ReadWriteCreateOrTruncate,
)?;
self.controller
.write(&mut self.volume, &mut log_file, &write_buf[..write_idx])?;
let mut log_file =
self.controller
.open_file_in_dir(&mut self.volume, &self.root_dir, LOGGING_FILE, sdmmc::Mode::ReadWriteCreateOrTruncate)?;
self.controller.write(&mut self.volume, &mut log_file, &write_buf[..write_idx])?;
self.controller.close_file(&self.volume, log_file)?;
Ok(())
}
@@ -216,11 +173,7 @@ pub trait DirectoryNavigator {
extension: &str,
comp: impl Fn(&sdmmc::DirEntry, &sdmmc::DirEntry) -> bool,
) -> Result<Option<sdmmc::DirEntry>, FileError>;
fn open_file_in_dir(
&mut self,
file_name: &sdmmc::ShortFileName,
directory: &sdmmc::Directory,
) -> Result<DataReader, FileError>;
fn open_file_in_dir(&mut self, file_name: &sdmmc::ShortFileName, directory: &sdmmc::Directory) -> Result<DataReader, FileError>;
fn close_dir(&mut self, dir: sdmmc::Directory);
}

@@ -237,8 +190,7 @@ where
}

fn open_direntry(&mut self, file: &sdmmc::DirEntry) -> Result<sdmmc::File, FileError> {
self.controller
.open_dir_entry(&mut self.volume, file.clone(), sdmmc::Mode::ReadOnly)
self.controller.open_dir_entry(&mut self.volume, file.clone(), sdmmc::Mode::ReadOnly)
}
fn next_file(
&mut self,
@@ -248,62 +200,53 @@ where
comp: impl Fn(&sdmmc::DirEntry, &sdmmc::DirEntry) -> bool,
) -> Result<Option<sdmmc::DirEntry>, FileError> {
let mut next_dir_entry: Option<sdmmc::DirEntry> = None;
self.controller
.iterate_dir(&self.volume, dir, |dir_entry: &sdmmc::DirEntry| {
if dir_entry.attributes.is_hidden() || dir_entry.attributes.is_directory() {
return;
}
if dir_entry.name.extension() != extension.as_bytes() {
return;
}
match (current_file, next_dir_entry.as_ref()) {
(Some(current_file), Some(nde)) => {
if comp(current_file, dir_entry) && comp(dir_entry, nde) {
next_dir_entry.replace(dir_entry.clone());
}
}
(Some(current_file), None) => {
if comp(current_file, dir_entry) {
next_dir_entry.replace(dir_entry.clone());
}
self.controller.iterate_dir(&self.volume, dir, |dir_entry: &sdmmc::DirEntry| {
if dir_entry.attributes.is_hidden() || dir_entry.attributes.is_directory() {
return;
}
if dir_entry.name.extension() != extension.as_bytes() {
return;
}
match (current_file, next_dir_entry.as_ref()) {
(Some(current_file), Some(nde)) => {
if comp(current_file, dir_entry) && comp(dir_entry, nde) {
next_dir_entry.replace(dir_entry.clone());
}
(None, Some(nde)) => {
if comp(dir_entry, nde) {
next_dir_entry.replace(dir_entry.clone());
}
}
(Some(current_file), None) => {
if comp(current_file, dir_entry) {
next_dir_entry.replace(dir_entry.clone());
}
(None, None) => {
}
(None, Some(nde)) => {
if comp(dir_entry, nde) {
next_dir_entry.replace(dir_entry.clone());
}
};
})?;
}
(None, None) => {
next_dir_entry.replace(dir_entry.clone());
}
};
})?;
Ok(next_dir_entry)
}

fn close_dir(&mut self, directory: sdmmc::Directory) {
self.controller.close_dir(&self.volume, directory);
}

fn open_file_in_dir(
&mut self,
file_name: &sdmmc::ShortFileName,
directory: &sdmmc::Directory,
) -> Result<DataReader, FileError> {
fn open_file_in_dir(&mut self, file_name: &sdmmc::ShortFileName, directory: &sdmmc::Directory) -> Result<DataReader, FileError> {
let mut open_file: Option<sdmmc::DirEntry> = None;
self.controller
.iterate_dir(&self.volume, directory, |dir_entry: &sdmmc::DirEntry| {
if dir_entry.name == *file_name {
open_file.replace(dir_entry.clone());
}
})?;
self.controller.iterate_dir(&self.volume, directory, |dir_entry: &sdmmc::DirEntry| {
if dir_entry.name == *file_name {
open_file.replace(dir_entry.clone());
}
})?;
match open_file {
Some(de) => self
.controller
.open_dir_entry(&mut self.volume, de.clone(), sdmmc::Mode::ReadOnly)
.map(|file| DataReader {
file: file,
dir_entry: de,
}),
.map(|file| DataReader { file, dir_entry: de }),
None => Err(FileError::FileNotFound),
}
}
Loading

0 comments on commit 53b5bac

Please sign in to comment.