artiq-zynq/src/runtime/src/config.rs

97 lines
2.8 KiB
Rust
Raw Normal View History

2020-06-18 11:29:33 +08:00
use crate::sd_reader;
2020-06-13 16:44:54 +08:00
use core::fmt;
2020-06-18 11:29:33 +08:00
use alloc::{string::FromUtf8Error, string::String, vec::Vec};
use core_io::{self as io, BufRead, BufReader, Read};
2020-06-13 16:44:54 +08:00
use libboard_zynq::sdio;
#[derive(Debug)]
2020-06-18 11:29:33 +08:00
pub enum Error<'a> {
2020-06-13 16:44:54 +08:00
SdError(sdio::sd_card::CardInitializationError),
IoError(io::Error),
Utf8Error(FromUtf8Error),
KeyNotFoundError(&'a str),
2020-06-13 16:44:54 +08:00
}
2020-06-18 11:29:33 +08:00
pub type Result<'a, T> = core::result::Result<T, Error<'a>>;
2020-06-13 16:44:54 +08:00
2020-06-18 11:29:33 +08:00
impl<'a> fmt::Display for Error<'a> {
2020-06-13 16:44:54 +08:00
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
2020-06-18 11:29:33 +08:00
Error::SdError(error) => write!(f, "SD error: {}", error),
Error::IoError(error) => write!(f, "I/O error: {}", error),
2020-06-13 16:44:54 +08:00
Error::Utf8Error(error) => write!(f, "UTF-8 error: {}", error),
Error::KeyNotFoundError(name) => write!(f, "Configuration key `{}` not found", name),
2020-06-13 16:44:54 +08:00
}
}
}
2020-06-18 11:29:33 +08:00
impl<'a> From<sdio::sd_card::CardInitializationError> for Error<'a> {
2020-06-13 16:44:54 +08:00
fn from(error: sdio::sd_card::CardInitializationError) -> Self {
Error::SdError(error)
}
}
2020-06-18 11:29:33 +08:00
impl<'a> From<io::Error> for Error<'a> {
2020-06-13 16:44:54 +08:00
fn from(error: io::Error) -> Self {
Error::IoError(error)
}
}
2020-06-18 11:29:33 +08:00
impl<'a> From<FromUtf8Error> for Error<'a> {
2020-06-13 16:44:54 +08:00
fn from(error: FromUtf8Error) -> Self {
Error::Utf8Error(error)
}
}
2020-06-18 11:29:33 +08:00
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(());
2020-06-13 16:44:54 +08:00
}
}
Err(Error::KeyNotFoundError(key))
2020-06-13 16:44:54 +08:00
}
2020-06-18 11:29:33 +08:00
pub struct Config {
fs: fatfs::FileSystem<sd_reader::SdReader>,
}
impl Config {
pub fn new() -> Result<'static, Self> {
let sdio = sdio::SDIO::sdio0(true);
if !sdio.is_card_inserted() {
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)?;
Ok(Config { fs })
}
fn read<'b>(&mut self, key: &'b str) -> Result<'b, Vec<u8>> {
let root_dir = self.fs.root_dir();
let mut buffer: Vec<u8> = Vec::new();
match root_dir.open_file(&["/CONFIG/", key, ".BIN"].concat()) {
2020-06-29 10:00:13 +08:00
Ok(mut f) => f.read_to_end(&mut buffer).map(|_| ())?,
2020-06-18 11:29:33 +08:00
Err(_) => match root_dir.open_file("/CONFIG.TXT") {
Ok(f) => parse_config(key, &mut buffer, f)?,
Err(_) => return Err(Error::KeyNotFoundError(key)),
2020-06-18 11:29:33 +08:00
},
};
Ok(buffer)
}
pub fn read_str<'b>(&mut self, key: &'b str) -> Result<'b, String> {
Ok(String::from_utf8(self.read(key)?)?)
}
2020-06-13 16:44:54 +08:00
}