Skip to content

Commit 4114f56

Browse files
committed
Improve fatfs support.
1 parent caf5008 commit 4114f56

File tree

2 files changed

+124
-17
lines changed

2 files changed

+124
-17
lines changed

src/rtc.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,15 @@ use crate::{
4545
};
4646

4747
/// Interrupt event
48+
#[derive(Debug)]
4849
pub enum Event {
4950
WakeupTimer,
5051
AlarmA,
5152
AlarmB,
5253
Timestamp,
5354
}
5455

56+
#[derive(Debug)]
5557
pub enum Alarm {
5658
AlarmA,
5759
AlarmB,
@@ -67,6 +69,7 @@ impl From<Alarm> for Event {
6769
}
6870

6971
/// RTC Abstraction
72+
#[derive(Debug)]
7073
pub struct Rtc {
7174
rtc: RTC,
7275
rtc_config: RtcConfig,
@@ -858,3 +861,28 @@ impl embedded_sdmmc::TimeSource for Rtc {
858861
}
859862
}
860863
}
864+
865+
#[cfg(feature = "fatfs")]
866+
impl fatfs::TimeProvider for Rtc {
867+
fn get_current_date(&self) -> fatfs::Date {
868+
let (year, month, day) = self.date_raw();
869+
870+
fatfs::Date::new(year.into(), month.into(), day.into())
871+
}
872+
873+
fn get_current_date_time(&self) -> fatfs::DateTime {
874+
let (hour, minute, second) = self.time_raw();
875+
let micro = self.microsecond_raw();
876+
let (year, month, day) = self.date_raw();
877+
878+
let time = fatfs::Time::new(
879+
hour.into(),
880+
minute.into(),
881+
second.into(),
882+
(micro / 1000) as u16,
883+
);
884+
let date = fatfs::Date::new(year.into(), month.into(), day.into());
885+
886+
fatfs::DateTime::new(date, time)
887+
}
888+
}

src/sdmmc.rs

Lines changed: 96 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,24 @@ pub enum Error {
165165
RxOverrun,
166166
/// Transmit FIFO underrun.
167167
TxUnderrun,
168+
/// Invalid input.
169+
InvalidInput,
170+
}
171+
172+
impl fmt::Display for Error {
173+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174+
match self {
175+
Self::NoCard => "no card",
176+
Self::CommandCrc => "command CRC check failed",
177+
Self::DataCrc => "data block CRC check failed",
178+
Self::Timeout => "timeout",
179+
Self::SoftwareTimeout => "software timeout",
180+
Self::RxOverrun => "receive FIFO overrun",
181+
Self::TxUnderrun => "transmit FIFO underrun",
182+
Self::InvalidInput => "invalid input",
183+
}
184+
.fmt(f)
185+
}
168186
}
169187

170188
macro_rules! sta_rx_tx_err {
@@ -932,8 +950,8 @@ pub struct FatFsCursor<SDMMC> {
932950
current_block: Option<u32>,
933951
}
934952

935-
impl FatFsCursor<Sdmmc> {
936-
pub fn new(sdmmc: Sdmmc) -> Self {
953+
impl<SDMMC> FatFsCursor<SDMMC> {
954+
pub fn new(sdmmc: SDMMC) -> Self {
937955
Self {
938956
sdmmc,
939957
pos: 0,
@@ -942,14 +960,19 @@ impl FatFsCursor<Sdmmc> {
942960
current_block: None,
943961
}
944962
}
963+
}
945964

965+
impl<SDMMC> FatFsCursor<SDMMC>
966+
where
967+
SDMMC: AsMut<Sdmmc>,
968+
{
946969
pub fn partition_info(&mut self) -> Result<(u32, u32), Error> {
947970
if let Some(partition_info) = self.partition_info {
948971
return Ok(partition_info);
949972
}
950973

951974
let mut block = [0; 512];
952-
self.sdmmc.read_block(0, &mut block)?;
975+
self.sdmmc.as_mut().read_block(0, &mut block)?;
953976

954977
// TODO: Support other partitions.
955978
let partition1_info = &block[446..][..16];
@@ -971,20 +994,33 @@ impl FatFsCursor<Sdmmc> {
971994
}
972995
}
973996

997+
impl AsMut<Sdmmc> for Sdmmc {
998+
fn as_mut(&mut self) -> &mut Self {
999+
self
1000+
}
1001+
}
1002+
9741003
#[cfg(feature = "fatfs")]
975-
impl IntoStorage<FatFsCursor<Sdmmc>> for Sdmmc {
976-
fn into_storage(self) -> FatFsCursor<Sdmmc> {
1004+
impl<'sdmmc> IntoStorage<FatFsCursor<&'sdmmc mut Sdmmc>> for &'sdmmc mut Sdmmc {
1005+
fn into_storage(self) -> FatFsCursor<&'sdmmc mut Sdmmc> {
9771006
FatFsCursor::new(self)
9781007
}
9791008
}
9801009

9811010
#[cfg(feature = "fatfs")]
9821011
impl<SDMMC> IoBase for FatFsCursor<SDMMC> {
983-
type Error = fatfs::Error<Error>;
1012+
type Error = Error;
9841013
}
9851014

9861015
#[cfg(feature = "fatfs")]
987-
impl Seek for FatFsCursor<Sdmmc> {
1016+
impl<SDMMC> IoBase for &mut FatFsCursor<SDMMC> {
1017+
type Error = Error;
1018+
}
1019+
1020+
impl<SDMMC> Seek for FatFsCursor<SDMMC>
1021+
where
1022+
SDMMC: AsMut<Sdmmc>,
1023+
{
9881024
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Self::Error> {
9891025
// TODO: Use `checked_add_signed` when stable.
9901026
let new_pos = match pos {
@@ -1008,21 +1044,37 @@ impl Seek for FatFsCursor<Sdmmc> {
10081044
}
10091045

10101046
#[cfg(feature = "fatfs")]
1011-
impl Read for FatFsCursor<Sdmmc> {
1012-
#[track_caller]
1047+
impl<SDMMC> Seek for &mut FatFsCursor<SDMMC>
1048+
where
1049+
SDMMC: AsMut<Sdmmc>,
1050+
{
1051+
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Self::Error> {
1052+
(*self).seek(pos)
1053+
}
1054+
}
1055+
1056+
#[cfg(feature = "fatfs")]
1057+
impl<SDMMC> Read for FatFsCursor<SDMMC>
1058+
where
1059+
SDMMC: AsMut<Sdmmc>,
1060+
{
10131061
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
10141062
let (start, end) = self.partition_info()?;
10151063

10161064
let end = end as u64 * 512;
1017-
let pos = self.pos.min(end);
1065+
let pos = self.pos;
1066+
1067+
if pos >= end {
1068+
return Ok(0);
1069+
}
10181070

10191071
let addr = start + (pos / 512) as u32;
10201072
let offset = (pos % 512) as usize;
10211073
let len = buf.len().min(512 - offset);
10221074

10231075
// Only read the block if we have not already read it.
10241076
if self.current_block != Some(addr) {
1025-
self.sdmmc.read_block(addr, &mut self.block)?;
1077+
self.sdmmc.as_mut().read_block(addr, &mut self.block)?;
10261078
self.current_block = Some(addr);
10271079
}
10281080

@@ -1037,29 +1089,42 @@ impl Read for FatFsCursor<Sdmmc> {
10371089
}
10381090

10391091
#[cfg(feature = "fatfs")]
1040-
impl Write for FatFsCursor<Sdmmc> {
1092+
impl<SDMMC> Read for &mut FatFsCursor<SDMMC>
1093+
where
1094+
SDMMC: AsMut<Sdmmc>,
1095+
{
1096+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1097+
(*self).read(buf)
1098+
}
1099+
}
1100+
1101+
#[cfg(feature = "fatfs")]
1102+
impl<SDMMC> Write for FatFsCursor<SDMMC>
1103+
where
1104+
SDMMC: AsMut<Sdmmc>,
1105+
{
10411106
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
10421107
let (start, end) = self.partition_info()?;
10431108

10441109
let end = end as u64 * 512;
10451110
let pos = self.pos;
10461111

1047-
if pos + buf.len() as u64 >= end {
1048-
return Err(Self::Error::NotEnoughSpace);
1112+
if pos >= end {
1113+
return Ok(0);
10491114
}
10501115

10511116
let addr = start + (pos / 512) as u32;
10521117
let offset = (pos % 512) as usize;
10531118
let len = buf.len().min(512 - offset);
10541119

10551120
// Only read the block if we have not already read it.
1056-
if self.current_block != Some(addr) {
1121+
if self.current_block != Some(addr) && len != 512 {
10571122
self.current_block = None;
1058-
self.sdmmc.read_block(addr, &mut self.block)?;
1123+
self.sdmmc.as_mut().read_block(addr, &mut self.block)?;
10591124
}
10601125

10611126
self.block[offset..(offset + len)].copy_from_slice(&buf[0..len]);
1062-
self.sdmmc.write_block(addr, &self.block)?;
1127+
self.sdmmc.as_mut().write_block(addr, &self.block)?;
10631128
self.current_block = Some(addr);
10641129

10651130
self.pos += len as u64;
@@ -1073,3 +1138,17 @@ impl Write for FatFsCursor<Sdmmc> {
10731138
Ok(())
10741139
}
10751140
}
1141+
1142+
#[cfg(feature = "fatfs")]
1143+
impl<SDMMC> Write for &mut FatFsCursor<SDMMC>
1144+
where
1145+
SDMMC: AsMut<Sdmmc>,
1146+
{
1147+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1148+
(*self).write(buf)
1149+
}
1150+
1151+
fn flush(&mut self) -> Result<(), Self::Error> {
1152+
(*self).flush()
1153+
}
1154+
}

0 commit comments

Comments
 (0)