From e601ac9c457516b5f36a1deebbda0e93d9bdc632 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 9 Sep 2020 20:13:13 +0800 Subject: [PATCH] remove flash support PITA to get to work and most boards have SD. --- experiments/src/main.rs | 52 +- libboard_zynq/src/flash/bytes.rs | 41 -- libboard_zynq/src/flash/mod.rs | 503 ------------------ libboard_zynq/src/flash/regs.rs | 122 ----- libboard_zynq/src/flash/spi_flash_register.rs | 62 --- libboard_zynq/src/flash/transfer.rs | 125 ----- libboard_zynq/src/lib.rs | 1 - 7 files changed, 1 insertion(+), 905 deletions(-) delete mode 100644 libboard_zynq/src/flash/bytes.rs delete mode 100644 libboard_zynq/src/flash/mod.rs delete mode 100644 libboard_zynq/src/flash/regs.rs delete mode 100644 libboard_zynq/src/flash/spi_flash_register.rs delete mode 100644 libboard_zynq/src/flash/transfer.rs diff --git a/experiments/src/main.rs b/experiments/src/main.rs index 8b97830..2905013 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -15,7 +15,7 @@ use libboard_zynq::{ self as zynq, clocks::source::{ArmPll, ClockSource, IoPll}, clocks::Clocks, - print, println, stdio, + println, stdio, mpcore, gic, smoltcp::{ @@ -140,17 +140,6 @@ pub fn main_core0() { clocks.cpu_1x() ); - let mut flash = zynq::flash::Flash::flash(200_000_000).linear_addressing_mode(); - let flash_ram: &[u8] = unsafe { core::slice::from_raw_parts(flash.ptr(), flash.size()) }; - for i in 0..=1 { - print!("Flash {}:", i); - for b in &flash_ram[(i * 16 * 1024 * 1024)..][..128] { - print!(" {:02X}", *b); - } - println!(""); - } - let _flash = flash.stop(); - let timer = libboard_zynq::timer::GlobalTimer::start(); let mut ddr = zynq::ddr::DdrRam::ddrram(); @@ -158,45 +147,6 @@ pub fn main_core0() { ddr.memtest(); ram::init_alloc_ddr(&mut ddr); - #[cfg(dev)] - for i in 0..=1 { - let mut flash_io = flash.manual_mode(i); - // println!("rdcr={:02X}", flash_io.rdcr()); - print!("Flash {} ID:", i); - for b in flash_io.rdid() { - print!(" {:02X}", b); - } - println!(""); - print!("Flash {} I/O:", i); - for o in 0..8 { - const CHUNK: u32 = 8; - for b in flash_io.read(CHUNK * o, CHUNK as usize) { - print!(" {:02X}", b); - } - } - println!(""); - - flash_io.dump("Read cr1", 0x35); - flash_io.dump("Read Autoboot", 0x14); - flash_io.dump("Read Bank", 0x16); - flash_io.dump("DLP Bank", 0x16); - flash_io.dump("Read ESig", 0xAB); - flash_io.dump("OTP Read", 0x4B); - flash_io.dump("DYB Read", 0xE0); - flash_io.dump("PPB Read", 0xE2); - flash_io.dump("ASP Read", 0x2B); - flash_io.dump("Password Read", 0xE7); - - flash_io.write_enabled(|flash_io| { - flash_io.erase(0); - }); - flash_io.write_enabled(|flash_io| { - flash_io.program(0, [0x23054223; 0x100 >> 2].iter().cloned()); - }); - - flash = flash_io.stop(); - } - boot::Core1::start(false); let core1_req = unsafe { &mut CORE1_REQ.0 }; diff --git a/libboard_zynq/src/flash/bytes.rs b/libboard_zynq/src/flash/bytes.rs deleted file mode 100644 index 5d35895..0000000 --- a/libboard_zynq/src/flash/bytes.rs +++ /dev/null @@ -1,41 +0,0 @@ -pub trait BytesTransferExt: Sized { - // Turn u32 into u8 - fn bytes_transfer(self) -> BytesTransfer - where - Self: Iterator; -} - -impl> BytesTransferExt for I { - // Turn u32 into u8 - fn bytes_transfer(self) -> BytesTransfer { - BytesTransfer { - iter: self, - shift: 0, - word: 0, - } - } -} - -pub struct BytesTransfer + Sized> { - iter: I, - shift: u8, - word: u32, -} - -impl + Sized> Iterator for BytesTransfer { - type Item = u8; - - fn next(&mut self) -> Option { - if self.shift > 0 { - self.shift -= 8; - Some((self.word >> self.shift) as u8) - } else { - self.iter.next() - .and_then(|word| { - self.shift = 32; - self.word = word; - self.next() - }) - } - } -} diff --git a/libboard_zynq/src/flash/mod.rs b/libboard_zynq/src/flash/mod.rs deleted file mode 100644 index 4b4ecc6..0000000 --- a/libboard_zynq/src/flash/mod.rs +++ /dev/null @@ -1,503 +0,0 @@ -//! Quad-SPI Flash Controller - -use core::marker::PhantomData; -use log::{error, info, warn}; -use libregister::{RegisterR, RegisterW, RegisterRW}; -use crate::{print, println}; -use super::slcr; -use super::clocks::source::{IoPll, ClockSource}; - -mod regs; -mod bytes; -pub use bytes::{BytesTransferExt, BytesTransfer}; -mod spi_flash_register; -use spi_flash_register::*; -mod transfer; -use transfer::Transfer; - -const FLASH_BAUD_RATE: u32 = 50_000_000; -/// 16 MB -pub const SINGLE_CAPACITY: u32 = 0x1000000; -pub const SECTOR_SIZE: u32 = 0x10000; -pub const PAGE_SIZE: u32 = 0x100; - -/// Instruction: Read Identification -const INST_RDID: u8 = 0x9F; -/// Instruction: Read -const INST_READ: u8 = 0x03; -/// Instruction: Quad I/O Fast Read -const INST_4IO_FAST_READ: u8 = 0xEB; -/// Instruction: Write Disable -const INST_WRDI: u8 = 0x04; -/// Instruction: Write Enable -const INST_WREN: u8 = 0x06; -/// Instruction: Program page -const INST_PP: u8 = 0x02; -/// Instruction: Erase 4K Block -const INST_BE_4K: u8 = 0x20; - -#[derive(Clone)] -pub enum SpiWord { - W8(u8), - W16(u16), - W24(u32), - W32(u32), -} - -impl From for SpiWord { - fn from(x: u8) -> Self { - SpiWord::W8(x) - } -} - -impl From for SpiWord { - fn from(x: u16) -> Self { - SpiWord::W16(x) - } -} - -impl From for SpiWord { - fn from(x: u32) -> Self { - SpiWord::W32(x) - } -} - -/// Memory-mapped mode -pub struct LinearAddressing; -/// Manual I/O mode -pub struct Manual; - -/// Flash Interface Driver -/// -/// For 2x Spansion S25FL128SAGMFIR01 -pub struct Flash { - regs: &'static mut regs::RegisterBlock, - _mode: PhantomData, -} - -impl Flash { - fn transition(self) -> Flash { - Flash { - regs: self.regs, - _mode: PhantomData, - } - } - - fn disable_interrupts(&mut self) { - self.regs.intr_dis.write( - regs::IntrDis::zeroed() - .rx_overflow(true) - .tx_fifo_not_full(true) - .tx_fifo_full(true) - .rx_fifo_not_empty(true) - .rx_fifo_full(true) - .tx_fifo_underflow(true) - ); - } - - fn clear_rx_fifo(&self) { - while self.regs.intr_status.read().rx_fifo_not_empty() { - let _ = self.regs.rx_data.read(); - } - } - - fn clear_interrupt_status(&mut self) { - self.regs.intr_status.write( - regs::IntrStatus::zeroed() - .rx_overflow(true) - .tx_fifo_underflow(true) - ); - } - - fn wait_tx_fifo_flush(&mut self) { - self.regs.config.modify(|_, w| w.man_start_com(true)); - while !self.regs.intr_status.read().tx_fifo_not_full() {} - } -} - -impl Flash<()> { - pub fn flash(clock: u32) -> Self { - Self::enable_clocks(clock); - Self::setup_signals(); - Self::reset(); - - let regs = regs::RegisterBlock::qspi(); - let mut flash = Flash { regs, _mode: PhantomData }; - flash.configure((FLASH_BAUD_RATE - 1 + clock) / FLASH_BAUD_RATE); - flash - } - - /// typical: `200_000_000` Hz - fn enable_clocks(clock: u32) { - let io_pll = IoPll::freq(); - let divisor = ((clock - 1 + io_pll) / clock) - .max(1).min(63) as u8; - - slcr::RegisterBlock::unlocked(|slcr| { - slcr.lqspi_clk_ctrl.write( - slcr::LqspiClkCtrl::zeroed() - .src_sel(slcr::PllSource::IoPll) - .divisor(divisor) - .clkact(true) - ); - }); - } - - fn setup_signals() { - slcr::RegisterBlock::unlocked(|slcr| { - // 1. Configure MIO pin 1 for chip select 0 output. - slcr.mio_pin_01.write( - slcr::MioPin01::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - .pullup(true) - ); - - // Configure MIO pins 2 through 5 for I/O. - slcr.mio_pin_02.write( - slcr::MioPin02::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - ); - slcr.mio_pin_03.write( - slcr::MioPin03::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - ); - slcr.mio_pin_04.write( - slcr::MioPin04::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - ); - slcr.mio_pin_05.write( - slcr::MioPin05::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - ); - - // 3. Configure MIO pin 6 for serial clock 0 output. - slcr.mio_pin_06.write( - slcr::MioPin06::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - ); - - // Option: Add Second Device Chip Select - // 4. Configure MIO pin 0 for chip select 1 output. - slcr.mio_pin_00.write( - slcr::MioPin00::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - ); - - // Option: Add Second Serial Clock - // 5. Configure MIO pin 9 for serial clock 1 output. - slcr.mio_pin_09.write( - slcr::MioPin09::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - .pullup(true) - ); - - // Option: Add 4-bit Data - // 6. Configure MIO pins 10 through 13 for I/O. - slcr.mio_pin_10.write( - slcr::MioPin10::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - .pullup(true) - ); - slcr.mio_pin_11.write( - slcr::MioPin11::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - .pullup(true) - ); - slcr.mio_pin_12.write( - slcr::MioPin12::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - .pullup(true) - ); - slcr.mio_pin_13.write( - slcr::MioPin13::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - .pullup(true) - ); - - // Option: Add Feedback Output Clock - // 7. Configure MIO pin 8 for feedback clock. - slcr.mio_pin_08.write( - slcr::MioPin08::zeroed() - .l0_sel(true) - .io_type(slcr::IoBufferType::Lvcmos18) - .pullup(true) - ); - }); - } - - fn reset() { - slcr::RegisterBlock::unlocked(|slcr| { - slcr.lqspi_rst_ctrl.write( - slcr::LqspiRstCtrl::zeroed() - .ref_rst(true) - .cpu1x_rst(true) - ); - slcr.lqspi_rst_ctrl.write( - slcr::LqspiRstCtrl::zeroed() - ); - }); - } - - fn configure(&mut self, divider: u32) { - // Disable - self.regs.enable.write( - regs::Enable::zeroed() - ); - self.disable_interrupts(); - self.regs.lqspi_cfg.write( - regs::LqspiCfg::zeroed() - ); - self.clear_rx_fifo(); - self.clear_interrupt_status(); - - // for a baud_rate_div=1 LPBK_DLY_ADJ would be required - let mut baud_rate_div = 2u32; - while baud_rate_div < 7 && 2u32.pow(1 + baud_rate_div) < divider { - baud_rate_div += 1; - } - - self.regs.config.write(regs::Config::zeroed() - .baud_rate_div(baud_rate_div as u8) - .mode_sel(true) - .leg_flsh(true) - .holdb_dr(true) - // 32 bits TX FIFO width - .fifo_width(0b11) - ); - - // Initialize RX/TX pipes thresholds - unsafe { - self.regs.rx_thres.write(1); - self.regs.tx_thres.write(1); - } - } - - pub fn linear_addressing_mode(self) -> Flash { - // Set manual start enable to auto mode. - // Assert the chip select. - self.regs.config.modify(|_, w| w - .man_start_en(false) - .pcs(false) - .manual_cs(false) - ); - - self.regs.lqspi_cfg.write(regs::LqspiCfg::zeroed() - // Quad I/O Fast Read - .inst_code(INST_4IO_FAST_READ) - .dummy_mask(0x2) - .mode_en(false) - .mode_bits(0xFF) - // 2 devices - .two_mem(true) - .u_page(false) - // Quad SPI mode - .lq_mode(true) - ); - - self.regs.enable.write( - regs::Enable::zeroed() - .spi_en(true) - ); - - self.transition() - } - - pub fn manual_mode(self, chip_index: usize) -> Flash { - self.regs.config.modify(|_, w| w - .man_start_en(true) - .manual_cs(true) - .endian(true) - ); - - self.regs.lqspi_cfg.write(regs::LqspiCfg::zeroed() - // Quad I/O Fast Read - .inst_code(INST_READ) - .dummy_mask(0x2) - .mode_en(false) - .mode_bits(0xFF) - // 2 devices - .two_mem(true) - .u_page(chip_index != 0) - // Quad SPI mode - .lq_mode(false) - ); - - self.transition() - } -} - -impl Flash { - /// Stop linear addressing mode - pub fn stop(self) -> Flash<()> { - self.regs.enable.modify(|_, w| w.spi_en(false)); - // De-assert chip select. - self.regs.config.modify(|_, w| w.pcs(true)); - - self.transition() - } - - pub fn ptr(&mut self) -> *mut T { - 0xFC00_0000 as *mut _ - } - - pub fn size(&self) -> usize { - 2 * (SINGLE_CAPACITY as usize) - } -} - -impl Flash { - pub fn stop(self) -> Flash<()> { - self.transition() - } - - pub fn read_reg(&mut self) -> R { - let args = Some(R::inst_code()); - let transfer = self.transfer(args.into_iter(), 2) - .bytes_transfer(); - R::new(transfer.skip(1).next().unwrap()) - } - - pub fn read_reg_until(&mut self, f: F) -> A - where - R: SpiFlashRegister, - F: Fn(R) -> Option, - { - let mut result = None; - while result.is_none() { - let args = Some(R::inst_code()); - for b in self.transfer(args.into_iter(), 32) - .bytes_transfer().skip(1) { - result = f(R::new(b)); - - if result.is_none() { - break; - } - } - } - result.unwrap() - } - - /// Status Register-1 remains `0x00` immediately after invoking a command. - fn wait_while_sr1_zeroed(&mut self) -> SR1 { - self.read_reg_until::(|sr1| - if sr1.is_zeroed() { - None - } else { - Some(sr1) - } - ) - } - - /// Read Identification - pub fn rdid(&mut self) -> core::iter::Skip, u32>>> { - let args = Some((INST_RDID as u32) << 24); - self.transfer(args.into_iter(), 0x44) - .bytes_transfer().skip(1) - } - - /// Read flash data - pub fn read(&mut self, offset: u32, len: usize - ) -> core::iter::Take, u32>>>> - { - let args = Some(((INST_READ as u32) << 24) | (offset as u32)); - self.transfer(args.into_iter(), len + 6) - .bytes_transfer().skip(6).take(len) - } - - pub fn erase(&mut self, offset: u32) { - let args = Some(((INST_BE_4K as u32) << 24) | (offset as u32)); - self.transfer(args.into_iter(), 4); - - let sr1 = self.wait_while_sr1_zeroed(); - - if sr1.e_err() { - error!("E_ERR"); - } else if sr1.p_err() { - error!("P_ERR"); - } else if sr1.wip() { - info!("Erase in progress"); - while self.read_reg::().wip() { - print!("."); - } - println!(""); - } else { - warn!("erased? sr1={:02X}", sr1.inner); - } - } - - pub fn program>(&mut self, offset: u32, data: I) { - { - let len = 4 + 4 * data.size_hint().0; - let args = Some(SpiWord::W32(((INST_PP as u32) << 24) | (offset as u32))).into_iter() - .chain(data.map(SpiWord::W32)); - self.transfer(args, len); - } - - // let sr1 = self.wait_while_sr1_zeroed(); - let sr1 = self.read_reg::(); - - if sr1.e_err() { - error!("E_ERR"); - } else if sr1.p_err() { - error!("P_ERR"); - } else if sr1.wip() { - info!("Program in progress"); - while self.read_reg::().wip() { - print!("."); - } - println!(""); - } else { - warn!("programmed? sr1={:02X}", sr1.inner); - } - } - - pub fn write_enabled 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)); - let sr1 = self.wait_while_sr1_zeroed(); - if !sr1.wel() { - panic!("Cannot write-enable flash"); - } - - 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)); - - result - } - - pub fn transfer<'s: 't, 't, Args, W>(&'s mut self, args: Args, len: usize) -> Transfer<'t, Args, W> - where - Args: Iterator, - W: Into, - { - Transfer::new(self, args, len) - } - - pub fn dump(&mut self, label: &'_ str, inst_code: u8) { - print!("{}:", label); - - let args = Some(u32::from(inst_code) << 24); - for b in self.transfer(args.into_iter(), 32).bytes_transfer() { - print!(" {:02X}", b); - } - println!(""); - } -} diff --git a/libboard_zynq/src/flash/regs.rs b/libboard_zynq/src/flash/regs.rs deleted file mode 100644 index 9a62dac..0000000 --- a/libboard_zynq/src/flash/regs.rs +++ /dev/null @@ -1,122 +0,0 @@ -use volatile_register::{RO, WO, RW}; - -use libregister::{register, register_at, register_bit, register_bits}; - -#[repr(C)] -pub struct RegisterBlock { - pub config: Config, - pub intr_status: IntrStatus, - pub intr_en: IntrEn, - pub intr_dis: IntrDis, - pub intr_mask: RO, - pub enable: Enable, - pub delay: RW, - pub txd0: WO, - pub rx_data: RO, - pub slave_idle_count: RW, - pub tx_thres: RW, - pub rx_thres: RW, - pub gpio: QspiGpio, - pub _unused1: RO, - pub lpbk_dly_adj: RW, - pub _unused2: [RO; 17], - pub txd1: WO, - pub txd2: WO, - pub txd3: WO, - pub _unused3: [RO; 5], - pub lqspi_cfg: LqspiCfg, - pub lqspi_sts: RW, - pub _unused4: [RO; 21], - pub mod_id: RW, -} - -const BASE_ADDRESS: u32 = 0xE000D000; - -register_at!(RegisterBlock, 0xE000D000, qspi); - -register!(config, Config, RW, u32); -register_bit!(config, - /// Enables master mode - mode_sel, 0); -register_bit!(config, - /// Clock polarity low/high - clk_pol, 1); -register_bit!(config, - /// Clock phase - clk_ph, 2); -register_bits!(config, - /// divider = 2 ** (1 + baud_rate_div) - baud_rate_div, u8, 3, 5); -register_bits!(config, - /// Must be set to 0b11 - fifo_width, u8, 6, 7); -register_bit!(config, - /// Must be 0 - ref_clk, 8); -register_bit!(config, - /// Peripheral Chip Select Line - pcs, 10); -register_bit!(config, - /// false: auto mode, true: manual CS mode - manual_cs, 14); -register_bit!(config, - /// false: auto mode, true: enables manual start enable - man_start_en, 15); -register_bit!(config, - /// false: auto mode, true: enables manual start command - man_start_com, 16); -register_bit!(config, holdb_dr, 19); -register_bit!(config, - /// false: little, true: endian - endian, 26); -register_bit!(config, - /// false: legacy SPI mode, true: Flash memory interface mode - leg_flsh, 31); - -register!(intr_status, IntrStatus, RW, u32); -register_bit!(intr_status, rx_overflow, 0); -register_bit!(intr_status, - /// < tx_thres - tx_fifo_not_full, 2); -register_bit!(intr_status, tx_fifo_full, 3); -register_bit!(intr_status, - /// >= rx_thres - rx_fifo_not_empty, 4); -register_bit!(intr_status, rx_fifo_full, 5); -register_bit!(intr_status, tx_fifo_underflow, 6); - -register!(intr_en, IntrEn, WO, u32); -register_bit!(intr_en, rx_overflow, 0); -register_bit!(intr_en, tx_fifo_not_full, 2); -register_bit!(intr_en, tx_fifo_full, 3); -register_bit!(intr_en, rx_fifo_not_empty, 4); -register_bit!(intr_en, rx_fifo_full, 5); -register_bit!(intr_en, tx_fifo_underflow, 6); - -register!(intr_dis, IntrDis, WO, u32); -register_bit!(intr_dis, rx_overflow, 0); -register_bit!(intr_dis, tx_fifo_not_full, 2); -register_bit!(intr_dis, tx_fifo_full, 3); -register_bit!(intr_dis, rx_fifo_not_empty, 4); -register_bit!(intr_dis, rx_fifo_full, 5); -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_mask, u8, 8, 10); -register_bits!(lqspi_cfg, mode_bits, u8, 16, 23); -register_bit!(lqspi_cfg, mode_on, 24); -register_bit!(lqspi_cfg, mode_en, 25); -register_bit!(lqspi_cfg, u_page, 28); -register_bit!(lqspi_cfg, sep_bus, 29); -register_bit!(lqspi_cfg, two_mem, 30); -register_bit!(lqspi_cfg, lq_mode, 31); diff --git a/libboard_zynq/src/flash/spi_flash_register.rs b/libboard_zynq/src/flash/spi_flash_register.rs deleted file mode 100644 index ad3521e..0000000 --- a/libboard_zynq/src/flash/spi_flash_register.rs +++ /dev/null @@ -1,62 +0,0 @@ -use bit_field::BitField; - -pub trait SpiFlashRegister { - fn inst_code() -> u8; - fn new(src: u8) -> Self; -} - -macro_rules! u8_register { - ($name: ident, $doc: tt, $inst_code: expr) => { - #[derive(Clone)] - #[doc=$doc] - pub struct $name { - pub inner: u8, - } - - impl SpiFlashRegister for $name { - fn inst_code() -> u8 { - $inst_code - } - - fn new(src: u8) -> Self { - $name { - inner: src, - } - } - } - - impl $name { - #[allow(unused)] - pub fn is_zeroed(&self) -> bool { - self.inner == 0 - } - } - }; -} - -u8_register!(CR, "Configuration Register", 0x35); -u8_register!(SR1, "Status Register-1", 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, "Status Register-2", 0x07); -u8_register!(BA, "Bank Address Register", 0xB9); diff --git a/libboard_zynq/src/flash/transfer.rs b/libboard_zynq/src/flash/transfer.rs deleted file mode 100644 index 53f0996..0000000 --- a/libboard_zynq/src/flash/transfer.rs +++ /dev/null @@ -1,125 +0,0 @@ -use libregister::{RegisterR, RegisterW, RegisterRW}; -use super::regs; -use super::{SpiWord, Flash, Manual}; - -pub struct Transfer<'a, Args: Iterator, W: Into> { - flash: &'a mut Flash, - args: Args, - sent: usize, - received: usize, - len: usize, -} - -impl<'a, Args: Iterator, W: Into> Transfer<'a, Args, W> { - pub fn new(flash: &'a mut Flash, args: Args, len: usize) -> Self { - flash.regs.config.modify(|_, w| w.pcs(false)); - flash.regs.enable.write( - regs::Enable::zeroed() - .spi_en(true) - ); - - let mut xfer = Transfer { - flash, - args, - sent: 0, - received: 0, - len, - }; - xfer.fill_tx_fifo(); - xfer.flash.regs.config.modify(|_, w| w.man_start_com(true)); - xfer - } - - fn fill_tx_fifo(&mut self) { - while self.sent < self.len && !self.flash.regs.intr_status.read().tx_fifo_full() { - let arg = self.args.next() - .map(|n| n.into()) - .unwrap_or(SpiWord::W32(0)); - match arg { - SpiWord::W32(w) => { - // println!("txd0 {:08X}", w); - unsafe { - self.flash.regs.txd0.write(w); - } - self.sent += 4; - } - // Only txd0 can be used without flushing - _ => { - if !self.flash.regs.intr_status.read().tx_fifo_not_full() { - // Flush if necessary - self.flash.wait_tx_fifo_flush(); - } - - match arg { - SpiWord::W8(w) => { - // println!("txd1 {:02X}", w); - unsafe { - self.flash.regs.txd1.write(u32::from(w) << 24); - } - self.sent += 1; - } - SpiWord::W16(w) => { - unsafe { - self.flash.regs.txd2.write(u32::from(w) << 16); - } - self.sent += 2; - } - SpiWord::W24(w) => { - unsafe { - self.flash.regs.txd3.write(w << 8); - } - self.sent += 3; - } - SpiWord::W32(_) => unreachable!(), - } - - self.flash.wait_tx_fifo_flush(); - } - } - } - } - - fn can_read(&mut self) -> bool { - self.flash.regs.intr_status.read().rx_fifo_not_empty() - } - - fn read(&mut self) -> u32 { - let rx = self.flash.regs.rx_data.read(); - self.received += 4; - rx - } -} - -impl<'a, Args: Iterator, W: Into> Drop for Transfer<'a, Args, W> { - fn drop(&mut self) { - // Discard remaining rx_data - while self.can_read() { - self.read(); - } - - // Stop - self.flash.regs.enable.write( - regs::Enable::zeroed() - .spi_en(false) - ); - self.flash.regs.config.modify(|_, w| w - .pcs(true) - .man_start_com(false) - ); - } -} - -impl<'a, Args: Iterator, W: Into> Iterator for Transfer<'a, Args, W> { - type Item = u32; - - fn next<'s>(&'s mut self) -> Option { - if self.received >= self.len { - return None; - } - - self.fill_tx_fifo(); - - while !self.can_read() {} - Some(self.read()) - } -} diff --git a/libboard_zynq/src/lib.rs b/libboard_zynq/src/lib.rs index 12343b2..a7c5ad1 100644 --- a/libboard_zynq/src/lib.rs +++ b/libboard_zynq/src/lib.rs @@ -16,7 +16,6 @@ pub mod axi_gp; pub mod ddr; pub mod mpcore; pub mod gic; -pub mod flash; pub mod time; pub mod timer; pub mod sdio;