Compare commits

..

4 Commits

Author SHA1 Message Date
Astro 8a9dde6119 zynq::flash: add consts 2019-12-14 01:57:51 +01:00
Astro 5268839467 zynq::flash: add write_enabled() 2019-12-14 01:56:49 +01:00
Astro 0b9a150255 zynq::flash: abstract SpiFlashRegister 2019-12-14 01:55:17 +01:00
Astro 2d1c8e1f4f zynq::flash: fix txd[123] alignment 2019-12-14 01:07:15 +01:00
3 changed files with 103 additions and 24 deletions

View File

@ -8,16 +8,22 @@ 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;
/// 16 MB
pub const SINGLE_CAPACITY: u32 = 0x1000000;
pub const SECTOR_SIZE: u32 = 0x10000;
pub const PAGE_SIZE: u32 = 0x100;
/// 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;
const INST_READ: u8 = 0x03;
/// Instruction: Write Disable
const INST_WRDI: u8 = 0x04;
/// Instruction: Write Enable
const INST_WREN: u8 = 0x06;
#[derive(Clone)]
pub enum SpiWord {
@ -349,23 +355,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)
@ -381,6 +378,24 @@ impl Flash<Manual> {
.bytes_transfer().skip(6).take(len)
}
pub fn write_enabled<F: Fn(&mut Self) -> R, R>(&mut self, f: F) -> R {
// Write Enable
let args = Some(INST_WREN);
self.transfer(args.into_iter(), 1);
self.regs.gpio.modify(|_, w| w.wp_n(true));
while !self.read_reg::<SR1>().wel() {}
let result = f(self);
// Write Disable
let args = Some(INST_WRDI);
self.transfer(args.into_iter(), 1);
self.regs.gpio.modify(|_, w| w.wp_n(false));
while self.read_reg::<SR1>().wel() {}
result
}
pub fn transfer<'s: 't, 't, Args, W>(&'s mut self, args: Args, len: usize) -> Transfer<'t, Args, W>
where
Args: Iterator<Item = W>,
@ -443,19 +458,19 @@ impl<'a, Args: Iterator<Item = W>, W: Into<SpiWord>> Transfer<'a, Args, W> {
SpiWord::W8(w) => {
// println!("txd1 {:02X}", w);
unsafe {
self.flash.regs.txd1.write(w.into());
self.flash.regs.txd1.write(u32::from(w) << 24);
}
self.sent += 1;
}
SpiWord::W16(w) => {
unsafe {
self.flash.regs.txd2.write(w.into());
self.flash.regs.txd2.write(u32::from(w) << 16);
}
self.sent += 2;
}
SpiWord::W24(w) => {
unsafe {
self.flash.regs.txd3.write(w);
self.flash.regs.txd3.write(w << 8);
}
self.sent += 3;
}

View File

@ -16,7 +16,7 @@ pub struct RegisterBlock {
pub slave_idle_count: RW<u32>,
pub tx_thres: RW<u32>,
pub rx_thres: RW<u32>,
pub gpio: RW<u32>,
pub gpio: QspiGpio,
pub _unused1: RO<u32>,
pub lpbk_dly_adj: RW<u32>,
pub _unused2: [RO<u32>; 17],
@ -108,6 +108,12 @@ register_bit!(intr_dis, tx_fifo_underflow, 6);
register!(enable, Enable, RW, u32);
register_bit!(enable, spi_en, 0);
// named to avoid confusion with normal gpio
register!(qspi_gpio, QspiGpio, RW, u32);
register_bit!(qspi_gpio,
/// Write protect pin (inverted)
wp_n, 0);
register!(lqspi_cfg, LqspiCfg, RW, u32);
register_bits!(lqspi_cfg, inst_code, u8, 0, 7);
register_bits!(lqspi_cfg, dummy_byte, u8, 8, 10);

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