seems working

This commit is contained in:
pca006132 2020-06-11 12:55:17 +08:00
parent f1247203cc
commit d539597f56
2 changed files with 77 additions and 81 deletions

View File

@ -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);
}

View File

@ -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)