seems working
This commit is contained in:
parent
f1247203cc
commit
d539597f56
|
@ -7,13 +7,14 @@ extern crate alloc;
|
|||
|
||||
use core::{cmp, str};
|
||||
use log::info;
|
||||
|
||||
use libboard_zynq::{timer::GlobalTimer, logger, devc, ddr};
|
||||
use libboard_zynq::{timer::GlobalTimer, logger, devc, ddr, sdio};
|
||||
use libsupport_zynq::ram;
|
||||
|
||||
use core_io::{Seek, Read, Write, SeekFrom};
|
||||
|
||||
mod proto_core_io;
|
||||
mod proto_async;
|
||||
mod comms;
|
||||
// mod comms;
|
||||
mod rpc;
|
||||
#[path = "../../../build/pl.rs"]
|
||||
mod pl;
|
||||
|
@ -42,9 +43,28 @@ pub fn main_core0() {
|
|||
log::set_max_level(log::LevelFilter::Debug);
|
||||
info!("NAR3/Zynq7000 starting...");
|
||||
|
||||
let mut ddr_ram = ddr::DdrRam::new();
|
||||
ram::init_alloc_linker();
|
||||
ram::init_alloc_ddr(&mut ddr_ram);
|
||||
// let mut ddr_ram = ddr::DdrRam::new();
|
||||
// ram::init_alloc_linker();
|
||||
// ram::init_alloc_ddr(&mut ddr_ram);
|
||||
|
||||
let mut sdio0 = sdio::SDIO::sdio0(true);
|
||||
if sdio0.is_card_inserted() {
|
||||
info!("Card inserted. Getting SD Card data.");
|
||||
let mut sd = sdio::sd_card::SdCard::from_sdio(sdio0).unwrap();
|
||||
let mut reader = sd_reader::SdReader::new(&mut sd);
|
||||
// let mut buffer: alloc::vec::Vec<u8> = alloc::vec::Vec::with_capacity(128);
|
||||
// unsafe {
|
||||
// buffer.set_len(128);
|
||||
// }
|
||||
let mut buffer: [u8; 1000] = [0; 1000];
|
||||
reader.seek(SeekFrom::Start(1000));
|
||||
reader.read(&mut buffer).unwrap();
|
||||
for i in 0..buffer.len() {
|
||||
info!("buffer[{}] = {:0X}", i, buffer[i]);
|
||||
}
|
||||
} else {
|
||||
info!("Card not inserted")
|
||||
}
|
||||
|
||||
let devc = devc::DevC::new();
|
||||
if devc.is_done() {
|
||||
|
@ -62,5 +82,5 @@ pub fn main_core0() {
|
|||
pl::csr::rtio_core::reset_phy_write(1);
|
||||
}
|
||||
|
||||
comms::main(timer);
|
||||
// comms::main(timer);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use core_io::{BufRead, Error, ErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write};
|
||||
use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError};
|
||||
use log::debug;
|
||||
|
||||
fn cmd_error_to_io_error(_: CmdTransferError) -> Error {
|
||||
Error::new(ErrorKind::Other, "Command transfer error")
|
||||
|
@ -7,7 +8,7 @@ fn cmd_error_to_io_error(_: CmdTransferError) -> Error {
|
|||
|
||||
const BLOCK_SIZE: usize = 512;
|
||||
|
||||
struct SdReader<'a> {
|
||||
pub struct SdReader<'a> {
|
||||
/// Internal SdCard handle.
|
||||
sd: &'a mut SdCard,
|
||||
/// Read buffer with the size of 1 block.
|
||||
|
@ -65,26 +66,47 @@ impl<'a> SdReader<'a> {
|
|||
self.consume(buf.len());
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn block_align<'b>(&self, buf: &'b [u8]) -> (&'b [u8], &'b [u8], &'b [u8]) {
|
||||
let head_len = BLOCK_SIZE - (self.byte_addr as usize % BLOCK_SIZE);
|
||||
if head_len > buf.len() {
|
||||
(buf, &[], &[])
|
||||
} else {
|
||||
let remaining_length = buf.len() - head_len;
|
||||
let mid_length = remaining_length - remaining_length % BLOCK_SIZE;
|
||||
let (head, remaining) = buf.split_at(head_len);
|
||||
let (mid, tail) = remaining.split_at(mid_length);
|
||||
(head, mid, tail)
|
||||
}
|
||||
}
|
||||
|
||||
fn block_align_mut<'b>(&self, buf: &'b mut [u8]) -> (&'b mut [u8], &'b mut [u8], &'b mut [u8]) {
|
||||
let head_len = BLOCK_SIZE - (self.byte_addr as usize % BLOCK_SIZE);
|
||||
if head_len > buf.len() {
|
||||
(buf, &mut [], &mut [])
|
||||
} else {
|
||||
let remaining_length = buf.len() - head_len;
|
||||
let mid_length = remaining_length - remaining_length % BLOCK_SIZE;
|
||||
let (head, remaining) = buf.split_at_mut(head_len);
|
||||
let (mid, tail) = remaining.split_at_mut(mid_length);
|
||||
(head, mid, tail)
|
||||
}
|
||||
}
|
||||
|
||||
fn invalidate_buffer(&mut self) {
|
||||
self.index = BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Read for SdReader<'a> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
let total_length = buf.len();
|
||||
let boundary1 = self.byte_addr as usize % BLOCK_SIZE;
|
||||
let (a, b, c) = if boundary1 > buf.len() {
|
||||
(buf, &mut [] as &mut [u8], &mut [] as &mut [u8])
|
||||
} else {
|
||||
let boundary2 = buf.len() - (buf.len() + self.byte_addr as usize) % BLOCK_SIZE;
|
||||
let (head, remaining) = buf.split_at_mut(boundary1);
|
||||
if boundary1 != boundary2 {
|
||||
let (mid, last) = remaining.split_at_mut(boundary2);
|
||||
(head, mid, last)
|
||||
} else {
|
||||
(head, &mut [] as &mut [u8], remaining)
|
||||
}
|
||||
};
|
||||
let (a, b, c) = self.block_align_mut(buf);
|
||||
debug!("{}, {}, {}", a.len(), b.len(), c.len());
|
||||
self.read_unaligned(a)?;
|
||||
if b.len() > 0 {
|
||||
// invalidate internal buffer
|
||||
self.invalidate_buffer();
|
||||
self.sd
|
||||
.read_block(
|
||||
self.byte_addr / BLOCK_SIZE as u32,
|
||||
|
@ -126,64 +148,17 @@ impl<'a> BufRead for SdReader<'a> {
|
|||
|
||||
impl<'a> Write for SdReader<'a> {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
|
||||
let mut remaining_length = buf.len();
|
||||
if self.byte_addr % (BLOCK_SIZE as u32) == 0 && buf.len() >= BLOCK_SIZE {
|
||||
// block aligned and the buffer contains at least 1 block
|
||||
// write directly into the SD card
|
||||
self.sd
|
||||
.write_block(
|
||||
self.byte_addr / (BLOCK_SIZE as u32),
|
||||
(remaining_length / BLOCK_SIZE) as u16,
|
||||
buf,
|
||||
)
|
||||
.map_err(cmd_error_to_io_error)?;
|
||||
self.byte_addr += (remaining_length - remaining_length % BLOCK_SIZE) as u32;
|
||||
// invalidate the read_buffer
|
||||
self.index = BLOCK_SIZE;
|
||||
remaining_length %= BLOCK_SIZE;
|
||||
} else {
|
||||
// update the read_buffer first, we will write into it
|
||||
let filled_buffer_len = self.fill_buf()?.len();
|
||||
let end_index = core::cmp::min(buf.len(), filled_buffer_len);
|
||||
for (src, target) in buf[..end_index]
|
||||
.iter()
|
||||
.zip(self.buffer[self.index..].iter_mut())
|
||||
{
|
||||
*target = *src;
|
||||
}
|
||||
remaining_length -= end_index;
|
||||
self.dirty = true;
|
||||
self.consume(end_index);
|
||||
if remaining_length > BLOCK_SIZE {
|
||||
// flush the content first
|
||||
self.flush()?;
|
||||
// now write directly...
|
||||
self.sd
|
||||
.write_block(
|
||||
self.byte_addr / (BLOCK_SIZE as u32),
|
||||
(remaining_length / BLOCK_SIZE) as u16,
|
||||
&buf[end_index..],
|
||||
)
|
||||
.map_err(cmd_error_to_io_error)?;
|
||||
remaining_length %= BLOCK_SIZE;
|
||||
// invalidate the read buffer
|
||||
self.index = BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
assert!(remaining_length < BLOCK_SIZE);
|
||||
if remaining_length > 0 {
|
||||
let buf_len = buf.len();
|
||||
// fill the read buffer
|
||||
self.fill_buf()?;
|
||||
for (src, target) in buf[buf_len - remaining_length..]
|
||||
.iter()
|
||||
.zip(self.buffer[self.index..].iter_mut())
|
||||
{
|
||||
*target = *src;
|
||||
}
|
||||
self.dirty = true;
|
||||
self.consume(remaining_length);
|
||||
let (a, b, c) = self.block_align(buf);
|
||||
self.write_unaligned(a)?;
|
||||
if b.len() > 0 {
|
||||
self.invalidate_buffer();
|
||||
self.sd.write_block(
|
||||
self.byte_addr / BLOCK_SIZE as u32,
|
||||
(b.len() / BLOCK_SIZE) as u16,
|
||||
b,
|
||||
);
|
||||
}
|
||||
self.write_unaligned(c)?;
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
|
@ -210,9 +185,9 @@ impl<'a> Seek for SdReader<'a> {
|
|||
return Err(Error::new(ErrorKind::InvalidInput, "Invalid address"));
|
||||
}
|
||||
let target_byte_addr = raw_target as u32;
|
||||
let same_block = self.byte_addr / (BLOCK_SIZE as u32)
|
||||
== target_byte_addr / (BLOCK_SIZE as u32)
|
||||
&& self.index != BLOCK_SIZE;
|
||||
let address_same_block = self.byte_addr / (BLOCK_SIZE as u32) == target_byte_addr / (BLOCK_SIZE as u32);
|
||||
// if the buffer was invalidated, we consider seek as different block
|
||||
let same_block = address_same_block && self.index != BLOCK_SIZE;
|
||||
if !same_block {
|
||||
self.flush()?;
|
||||
}
|
||||
|
@ -220,6 +195,7 @@ impl<'a> Seek for SdReader<'a> {
|
|||
self.index = if same_block {
|
||||
target_byte_addr as usize % BLOCK_SIZE
|
||||
} else {
|
||||
// invalidate the buffer as we moved to a different block
|
||||
BLOCK_SIZE
|
||||
};
|
||||
Ok(self.byte_addr as u64)
|
||||
|
|
Loading…
Reference in New Issue