zynq::flash: abstract SpiFlashRegister

master
Astro 2019-12-14 01:55:17 +01:00
parent 2d1c8e1f4f
commit 0b9a150255
2 changed files with 66 additions and 19 deletions

View File

@ -8,14 +8,12 @@ use super::clocks::CpuClocks;
mod regs;
mod bytes;
pub use bytes::{BytesTransferExt, BytesTransfer};
mod spi_flash_register;
use spi_flash_register::*;
const FLASH_BAUD_RATE: u32 = 50_000_000;
const SINGLE_CAPACITY: u32 = 16 * 1024 * 1024;
/// Instruction: Read Configure Register
const INST_RDCR: u8 = 0x35;
/// Instruction: Read Status Register-1
const INST_RDSR1: u8 = 0x05;
/// Instruction: Read Identification
const INST_RDID: u8 = 0x9F;
@ -349,23 +347,14 @@ impl Flash<Manual> {
self.transition()
}
/// Read Configuration Register
pub fn rdcr(&mut self) -> u8 {
let args = Some((INST_RDCR as u32) << 24);
self.transfer(args.into_iter(), 4)
.bytes_transfer().skip(1)
.next().unwrap() as u8
pub fn read_reg<R: SpiFlashRegister>(&mut self) -> R {
let args = Some(R::inst_code());
let transfer = self.transfer(args.into_iter(), R::transfer_len())
.bytes_transfer().skip(1);
R::new(transfer)
}
/// Read Status Register-1
pub fn rdsr1(&mut self) -> u8 {
let args = Some(INST_RDSR1 as u8);
self.transfer(args.into_iter(), 2)
.bytes_transfer().skip(1)
.next().unwrap()
}
/// Read Identifiaction
/// Read Identification
pub fn rdid(&mut self) -> core::iter::Skip<BytesTransfer<Transfer<core::option::IntoIter<u32>, u32>>> {
let args = Some((INST_RDID as u32) << 24);
self.transfer(args.into_iter(), 0x44)

View File

@ -0,0 +1,58 @@
use bit_field::BitField;
pub trait SpiFlashRegister {
fn inst_code() -> u8;
fn transfer_len() -> usize;
fn new<I: Iterator<Item=u8>>(src: I) -> Self;
}
macro_rules! u8_register {
($name: ident, $inst_code: expr) => {
#[derive(Clone)]
pub struct $name {
pub inner: u8,
}
impl SpiFlashRegister for $name {
fn inst_code() -> u8 {
$inst_code
}
fn transfer_len() -> usize {
2
}
fn new<I: Iterator<Item=u8>>(mut src: I) -> Self {
$name {
inner: src.next().unwrap(),
}
}
}
};
}
u8_register!(CR, 0x35);
u8_register!(SR1, 0x05);
impl SR1 {
/// Write In Progress
pub fn wip(&self) -> bool {
self.inner.get_bit(0)
}
/// Write Enable Latch
pub fn wel(&self) -> bool {
self.inner.get_bit(1)
}
/// Erase Error Occurred
pub fn e_err(&self) -> bool {
self.inner.get_bit(5)
}
/// Programming Error Occurred
pub fn p_err(&self) -> bool {
self.inner.get_bit(6)
}
}
u8_register!(SR2, 0x07);