forked from M-Labs/artiq-zynq
Config: implemented config struct.
This commit is contained in:
parent
854a50a0ba
commit
f7bb339275
|
@ -1,65 +1,96 @@
|
||||||
use log::info;
|
use crate::sd_reader;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use alloc::{vec::Vec, string::String, string::FromUtf8Error};
|
use alloc::{string::FromUtf8Error, string::String, vec::Vec};
|
||||||
use core_io as io;
|
use core_io::{self as io, BufRead, BufReader, Read};
|
||||||
|
|
||||||
use libboard_zynq::sdio;
|
use libboard_zynq::sdio;
|
||||||
|
|
||||||
use crate::sd_reader;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error<'a> {
|
||||||
SdError(sdio::sd_card::CardInitializationError),
|
SdError(sdio::sd_card::CardInitializationError),
|
||||||
IoError(io::Error),
|
IoError(io::Error),
|
||||||
Utf8Error(FromUtf8Error),
|
Utf8Error(FromUtf8Error),
|
||||||
|
ConfigNotFound(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = core::result::Result<T, Error>;
|
pub type Result<'a, T> = core::result::Result<T, Error<'a>>;
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl<'a> fmt::Display for Error<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Error::SdError(error) => write!(f, "SD error: {:?}", error), // TODO: Display for CardInitializationError?
|
Error::SdError(error) => write!(f, "SD error: {}", error),
|
||||||
Error::IoError(error) => write!(f, "I/O error: {}", error),
|
Error::IoError(error) => write!(f, "I/O error: {}", error),
|
||||||
Error::Utf8Error(error) => write!(f, "UTF-8 error: {}", error),
|
Error::Utf8Error(error) => write!(f, "UTF-8 error: {}", error),
|
||||||
|
Error::ConfigNotFound(name) => write!(f, "Config `{}` not found", name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<sdio::sd_card::CardInitializationError> for Error {
|
impl<'a> From<sdio::sd_card::CardInitializationError> for Error<'a> {
|
||||||
fn from(error: sdio::sd_card::CardInitializationError) -> Self {
|
fn from(error: sdio::sd_card::CardInitializationError) -> Self {
|
||||||
Error::SdError(error)
|
Error::SdError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
impl<'a> From<io::Error> for Error<'a> {
|
||||||
fn from(error: io::Error) -> Self {
|
fn from(error: io::Error) -> Self {
|
||||||
Error::IoError(error)
|
Error::IoError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FromUtf8Error> for Error {
|
impl<'a> From<FromUtf8Error> for Error<'a> {
|
||||||
fn from(error: FromUtf8Error) -> Self {
|
fn from(error: FromUtf8Error) -> Self {
|
||||||
Error::Utf8Error(error)
|
Error::Utf8Error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(key: &str) -> Result<Vec<u8>> {
|
fn parse_config<'a>(
|
||||||
|
key: &'a str,
|
||||||
|
buffer: &mut Vec<u8>,
|
||||||
|
file: fatfs::File<sd_reader::SdReader>,
|
||||||
|
) -> Result<'a, ()> {
|
||||||
|
let prefix = [key, "="].concat();
|
||||||
|
for line in BufReader::new(file).lines() {
|
||||||
|
let line = line?;
|
||||||
|
if line.starts_with(&prefix) {
|
||||||
|
buffer.extend(line[prefix.len()..].as_bytes());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(Error::ConfigNotFound(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Config {
|
||||||
|
fs: fatfs::FileSystem<sd_reader::SdReader>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn new() -> Result<'static, Self> {
|
||||||
let sdio = sdio::SDIO::sdio0(true);
|
let sdio = sdio::SDIO::sdio0(true);
|
||||||
let mut sd = sdio::sd_card::SdCard::from_sdio(sdio)?;
|
if !sdio.is_card_inserted() {
|
||||||
let reader = sd_reader::SdReader::new(&mut sd);
|
Err(sdio::sd_card::CardInitializationError::NoCardInserted)?;
|
||||||
|
}
|
||||||
|
let sd = sdio::sd_card::SdCard::from_sdio(sdio)?;
|
||||||
|
let reader = sd_reader::SdReader::new(sd);
|
||||||
|
|
||||||
let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?;
|
let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?;
|
||||||
let root_dir = fs.root_dir();
|
Ok(Config { fs })
|
||||||
for entry in root_dir.iter() {
|
|
||||||
if let Ok(entry) = entry {
|
|
||||||
let bytes = entry.short_file_name_as_bytes();
|
|
||||||
info!("{}", core::str::from_utf8(bytes).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(sdio::sd_card::CardInitializationError::NoCardInserted)? // TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_str(key: &str) -> Result<String> {
|
fn read<'b>(&mut self, key: &'b str) -> Result<'b, Vec<u8>> {
|
||||||
Ok(String::from_utf8(read(key)?)?)
|
let root_dir = self.fs.root_dir();
|
||||||
|
let mut buffer: Vec<u8> = Vec::new();
|
||||||
|
match root_dir.open_file(&["/CONFIG/", key, ".BIN"].concat()) {
|
||||||
|
Ok(mut f) => f.read_to_end(&mut buffer).map(|v| ())?,
|
||||||
|
Err(_) => match root_dir.open_file("/CONFIG.TXT") {
|
||||||
|
Ok(f) => parse_config(key, &mut buffer, f)?,
|
||||||
|
Err(_) => return Err(Error::ConfigNotFound(key)),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Ok(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_str<'b>(&mut self, key: &'b str) -> Result<'b, String> {
|
||||||
|
Ok(String::from_utf8(self.read(key)?)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue