zynq::flash: add read_reg_until()
This commit is contained in:
parent
0d1cf04a34
commit
b94afa1581
|
@ -359,9 +359,40 @@ impl Flash<Manual> {
|
||||||
|
|
||||||
pub fn read_reg<R: SpiFlashRegister>(&mut self) -> R {
|
pub fn read_reg<R: SpiFlashRegister>(&mut self) -> R {
|
||||||
let args = Some(R::inst_code());
|
let args = Some(R::inst_code());
|
||||||
let transfer = self.transfer(args.into_iter(), R::transfer_len())
|
let transfer = self.transfer(args.into_iter(), 2)
|
||||||
.bytes_transfer().skip(1);
|
.bytes_transfer();
|
||||||
R::new(transfer)
|
R::new(transfer.skip(1).next().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_reg_until<R, F, A>(&mut self, f: F) -> A
|
||||||
|
where
|
||||||
|
R: SpiFlashRegister,
|
||||||
|
F: Fn(R) -> Option<A>,
|
||||||
|
{
|
||||||
|
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, _, SR1>(|sr1|
|
||||||
|
if sr1.is_zeroed() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(sr1)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read Identification
|
/// Read Identification
|
||||||
|
@ -385,7 +416,10 @@ impl Flash<Manual> {
|
||||||
let args = Some(INST_WREN);
|
let args = Some(INST_WREN);
|
||||||
self.transfer(args.into_iter(), 1);
|
self.transfer(args.into_iter(), 1);
|
||||||
self.regs.gpio.modify(|_, w| w.wp_n(true));
|
self.regs.gpio.modify(|_, w| w.wp_n(true));
|
||||||
while !self.read_reg::<SR1>().wel() {}
|
let sr1 = self.wait_while_sr1_zeroed();
|
||||||
|
if !sr1.wel() {
|
||||||
|
panic!("Cannot write-enable flash");
|
||||||
|
}
|
||||||
|
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@ use bit_field::BitField;
|
||||||
|
|
||||||
pub trait SpiFlashRegister {
|
pub trait SpiFlashRegister {
|
||||||
fn inst_code() -> u8;
|
fn inst_code() -> u8;
|
||||||
fn transfer_len() -> usize;
|
fn new(src: u8) -> Self;
|
||||||
fn new<I: Iterator<Item=u8>>(src: I) -> Self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! u8_register {
|
macro_rules! u8_register {
|
||||||
|
@ -18,14 +17,16 @@ macro_rules! u8_register {
|
||||||
$inst_code
|
$inst_code
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer_len() -> usize {
|
fn new(src: u8) -> Self {
|
||||||
2
|
$name {
|
||||||
|
inner: src,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new<I: Iterator<Item=u8>>(mut src: I) -> Self {
|
impl $name {
|
||||||
$name {
|
pub fn is_zeroed(&self) -> bool {
|
||||||
inner: src.next().unwrap(),
|
self.inner == 0
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue