aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--imxrt1010/src/lib.rs3
-rw-r--r--imxrt1010evk/src/lib.rs4
-rw-r--r--imxrt1010evk/src/main.rs4
-rw-r--r--imxrt1040/src/lib.rs3
-rw-r--r--imxrt1040evk/src/lib.rs4
-rw-r--r--imxrt1040evk/src/main.rs4
-rw-r--r--imxrt1160/src/lib.rs3
-rw-r--r--imxrt1160evk/src/lib.rs3
-rw-r--r--imxrt1160evk/src/main.rs4
-rw-r--r--imxrt1170/src/lib.rs3
-rw-r--r--imxrt1170evk/examples/smoke.rs4
-rw-r--r--imxrt1170evk/src/lib.rs4
-rw-r--r--imxrt1170evk/src/main.rs4
-rw-r--r--src/flash/adesto.rs7
-rw-r--r--src/flash/issi.rs124
-rw-r--r--src/flash/winbond.rs92
-rw-r--r--src/imxrt10xx.rs28
-rw-r--r--src/imxrt11xx.rs26
-rw-r--r--src/lib.rs194
-rw-r--r--src/sequences/common.rs8
20 files changed, 228 insertions, 298 deletions
diff --git a/imxrt1010/src/lib.rs b/imxrt1010/src/lib.rs
index be48362..820e51f 100644
--- a/imxrt1010/src/lib.rs
+++ b/imxrt1010/src/lib.rs
@@ -30,4 +30,5 @@ impl imxrt10xx::Imxrt10xx for Imxrt1010 {
}
}
-pub type Algorithm<F> = imxrt10xx::Algorithm<Imxrt1010, F>;
+pub type Algorithm<const FLASH_SIZE_BYTES: usize> =
+ imxrt10xx::Algorithm<Imxrt1010, FLASH_SIZE_BYTES>;
diff --git a/imxrt1010evk/src/lib.rs b/imxrt1010evk/src/lib.rs
index 5bc0437..01f6f6f 100644
--- a/imxrt1010evk/src/lib.rs
+++ b/imxrt1010evk/src/lib.rs
@@ -2,6 +2,4 @@
use cortex_m as _;
-pub use imxrt1010_flash_algos::flash::adesto::At25sf128 as Flash;
-
-pub type Algorithm = imxrt1010_flash_algos::Algorithm<Flash>;
+pub type Algorithm = imxrt1010_flash_algos::Algorithm<{ 128 / 8 * 1024 * 1024 }>;
diff --git a/imxrt1010evk/src/main.rs b/imxrt1010evk/src/main.rs
index 0d0ad80..8e8aaaf 100644
--- a/imxrt1010evk/src/main.rs
+++ b/imxrt1010evk/src/main.rs
@@ -13,12 +13,12 @@ flash_algorithm::algorithm!(Algorithm, {
// We support page crossings. Suggest a larger page
// size so that probe-rs places larger buffers into
// RAM per programming operation, reducing overhead.
- page_size: 4096,
+ page_size: Algorithm::sector_size_bytes() as _,
empty_value: 0xFF,
program_time_out: 1000,
erase_time_out: 2000,
sectors: [{
- size: Algorithm::sector_size_bytes() as u32,
+ size: Algorithm::sector_size_bytes() as _,
address: 0x0,
}]
});
diff --git a/imxrt1040/src/lib.rs b/imxrt1040/src/lib.rs
index 556f18e..c5237c9 100644
--- a/imxrt1040/src/lib.rs
+++ b/imxrt1040/src/lib.rs
@@ -47,4 +47,5 @@ impl imxrt10xx::Imxrt10xx for Imxrt1040 {
}
}
-pub type Algorithm<F> = imxrt10xx::Algorithm<Imxrt1040, F>;
+pub type Algorithm<const FLASH_SIZE_BYTES: usize> =
+ imxrt10xx::Algorithm<Imxrt1040, FLASH_SIZE_BYTES>;
diff --git a/imxrt1040evk/src/lib.rs b/imxrt1040evk/src/lib.rs
index ad2bb57..ebc7102 100644
--- a/imxrt1040evk/src/lib.rs
+++ b/imxrt1040evk/src/lib.rs
@@ -2,6 +2,4 @@
use cortex_m as _;
-pub use imxrt1040_flash_algos::flash::winbond::W25q64 as Flash;
-
-pub type Algorithm = imxrt1040_flash_algos::Algorithm<Flash>;
+pub type Algorithm = imxrt1040_flash_algos::Algorithm<{ 128 / 8 * 1024 * 1024 }>;
diff --git a/imxrt1040evk/src/main.rs b/imxrt1040evk/src/main.rs
index f144213..3b71188 100644
--- a/imxrt1040evk/src/main.rs
+++ b/imxrt1040evk/src/main.rs
@@ -13,12 +13,12 @@ flash_algorithm::algorithm!(Algorithm, {
// We support page crossings. Suggest a larger page
// size so that probe-rs places larger buffers into
// RAM per programming operation, reducing overhead.
- page_size: 4096,
+ page_size: Algorithm::sector_size_bytes() as _,
empty_value: 0xFF,
program_time_out: 1000,
erase_time_out: 2000,
sectors: [{
- size: Algorithm::sector_size_bytes() as u32,
+ size: Algorithm::sector_size_bytes() as _,
address: 0x0,
}]
});
diff --git a/imxrt1160/src/lib.rs b/imxrt1160/src/lib.rs
index d494c8a..5b14840 100644
--- a/imxrt1160/src/lib.rs
+++ b/imxrt1160/src/lib.rs
@@ -18,4 +18,5 @@ impl imxrt11xx::Imxrt11xx for Imxrt1160 {
const FLEXSPI_FIFO_CAPACITY_BYTES: usize = 128;
}
-pub type Algorithm<F> = imxrt11xx::Algorithm<Imxrt1160, F>;
+pub type Algorithm<const FLASH_SIZE_BYTES: usize> =
+ imxrt11xx::Algorithm<Imxrt1160, FLASH_SIZE_BYTES>;
diff --git a/imxrt1160evk/src/lib.rs b/imxrt1160evk/src/lib.rs
index 5ed3257..5e353d7 100644
--- a/imxrt1160evk/src/lib.rs
+++ b/imxrt1160evk/src/lib.rs
@@ -2,5 +2,4 @@
use cortex_m as _;
-pub use imxrt1160_flash_algos::flash::issi::Is25xP128 as Flash;
-pub type Algorithm = imxrt1160_flash_algos::Algorithm<Flash>;
+pub type Algorithm = imxrt1160_flash_algos::Algorithm<{ 128 / 8 * 1024 * 1024 }>;
diff --git a/imxrt1160evk/src/main.rs b/imxrt1160evk/src/main.rs
index f0dcb27..be410b2 100644
--- a/imxrt1160evk/src/main.rs
+++ b/imxrt1160evk/src/main.rs
@@ -13,12 +13,12 @@ flash_algorithm::algorithm!(Algorithm, {
// We support page crossings. Suggest a larger page
// size so that probe-rs places larger buffers into
// RAM per programming operation, reducing overhead.
- page_size: 4096,
+ page_size: Algorithm::sector_size_bytes() as _,
empty_value: 0xFF,
program_time_out: 1000,
erase_time_out: 2000,
sectors: [{
- size: Algorithm::sector_size_bytes() as u32,
+ size: Algorithm::sector_size_bytes() as _,
address: 0x0,
}]
});
diff --git a/imxrt1170/src/lib.rs b/imxrt1170/src/lib.rs
index 7a78556..53d1626 100644
--- a/imxrt1170/src/lib.rs
+++ b/imxrt1170/src/lib.rs
@@ -18,4 +18,5 @@ impl imxrt11xx::Imxrt11xx for Imxrt1170 {
const FLEXSPI_FIFO_CAPACITY_BYTES: usize = 256;
}
-pub type Algorithm<F> = imxrt11xx::Algorithm<Imxrt1170, F>;
+pub type Algorithm<const FLASH_SIZE_BYTES: usize> =
+ imxrt11xx::Algorithm<Imxrt1170, FLASH_SIZE_BYTES>;
diff --git a/imxrt1170evk/examples/smoke.rs b/imxrt1170evk/examples/smoke.rs
index 63428ac..7a4f1c1 100644
--- a/imxrt1170evk/examples/smoke.rs
+++ b/imxrt1170evk/examples/smoke.rs
@@ -5,14 +5,14 @@ use defmt_rtt as _;
use imxrt1170evk::{self, Algorithm};
use panic_probe as _;
-const LAST_SECTOR: usize = Algorithm::flash_size_bytes() - Algorithm::sector_size_bytes();
+const LAST_SECTOR: usize = (128 * 1024 * 1024 / 8) - 4096;
#[imxrt_rt::entry]
fn main() -> ! {
for _ in 0..5 {
let mut is25wp = Algorithm::initialize();
- let mut sector = [0_u8; Algorithm::sector_size_bytes()];
+ let mut sector = [0_u8; 4096];
is25wp.flash_read(0x400, &mut sector[..4]);
if 0x42464346 != u32::from_le_bytes(sector[..4].try_into().unwrap()) {
defmt::warn!("No FCB found.");
diff --git a/imxrt1170evk/src/lib.rs b/imxrt1170evk/src/lib.rs
index 12da464..4f56b6d 100644
--- a/imxrt1170evk/src/lib.rs
+++ b/imxrt1170evk/src/lib.rs
@@ -1,6 +1,4 @@
#![no_std]
use cortex_m as _;
-
-pub use imxrt1170_flash_algos::flash::issi::Is25xP128 as Flash;
-pub type Algorithm = imxrt1170_flash_algos::Algorithm<Flash>;
+pub type Algorithm = imxrt1170_flash_algos::Algorithm<{ 128 / 8 * 1024 * 1024 }>;
diff --git a/imxrt1170evk/src/main.rs b/imxrt1170evk/src/main.rs
index 05e3a68..9d1ddce 100644
--- a/imxrt1170evk/src/main.rs
+++ b/imxrt1170evk/src/main.rs
@@ -13,12 +13,12 @@ flash_algorithm::algorithm!(Algorithm, {
// We support page crossings. Suggest a larger page
// size so that probe-rs places larger buffers into
// RAM per programming operation, reducing overhead.
- page_size: 4096,
+ page_size: Algorithm::sector_size_bytes() as _,
empty_value: 0xFF,
program_time_out: 1000,
erase_time_out: 2000,
sectors: [{
- size: Algorithm::sector_size_bytes() as u32,
+ size: Algorithm::sector_size_bytes() as _,
address: 0x0,
}]
});
diff --git a/src/flash/adesto.rs b/src/flash/adesto.rs
deleted file mode 100644
index 0c21d8c..0000000
--- a/src/flash/adesto.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//! Adesto serial NOR flash.
-//!
-//! Looks just like a Winbond flash part.
-
-pub use super::winbond::Winbond as Adesto;
-
-pub type At25sf128 = Adesto<{ 128 / 8 * 1024 * 1024 }>;
diff --git a/src/flash/issi.rs b/src/flash/issi.rs
deleted file mode 100644
index 6b517af..0000000
--- a/src/flash/issi.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-//! ISSI Serial NOR Flash.
-//!
-//! The same algorithm will query the flash part to differentiate
-//! the 3.3V part ("LP") from the 1.8V part ("WP"). Sequences and
-//! configurations vary by part. Replace the W and L with 'x'.
-
-use super::*;
-use crate::{ImxrtFlashAlgorithm, sequences::common as sequences};
-
-pub type Is25xP128 = Issi<{ 128 / 8 * 1024 * 1024 }>;
-
-/// An ISSI serial NOR flash driver.
-pub struct Issi<const FLASH_CAPACITY_BYTES: usize>;
-
-const ISSI_WP_MEM_TYPE: u8 = 0x70;
-const ISSI_LP_MEM_TYPE: u8 = 0x60;
-
-impl<const FLASH_CAPACITY_BYTES: usize> ImxrtFlashAlgorithm for Issi<FLASH_CAPACITY_BYTES> {
- const FLASH_CAPACITY_BYTES: usize = FLASH_CAPACITY_BYTES;
- const FLASH_PAGE_SIZE_BYTES: usize = 256;
- const FLASH_SECTOR_SIZE_BYTES: usize = 4096;
-
- fn initialize(flexspi: imxrt_drivers_flexspi::Instance) {
- defmt::assert_eq!(
- READ_ID_JEDEC_ID,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- READ_ID_JEDEC_ID.seq_id,
- &[sequences::SEQ_READ_ID_JEDEC_ID]
- ))
- );
-
- let jedec_id = super::read_jedec_id(flexspi);
- defmt::assert_eq!(jedec_id.mnf_id, 0x9D);
-
- let (dummy_cycles, set_read_params_data) = match jedec_id.mem_type {
- ISSI_WP_MEM_TYPE => (15, 15 << 3),
- ISSI_LP_MEM_TYPE => (10, (0b111 << 5) | (0b11) << 3),
- _ => defmt::panic!("{=u8:#X}", jedec_id.mem_type),
- };
-
- defmt::assert_eq!(
- READ,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- READ.seq_id,
- &[sequences::seq_fast_read_quad_io(dummy_cycles)],
- ))
- );
-
- defmt::assert_eq!(
- SET_READ_PARAMS,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- SET_READ_PARAMS.seq_id,
- &[sequences::SEQ_SET_READ_PARAMS_VOL]
- ))
- );
-
- defmt::assert_eq!(
- WRITE_ENABLE,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- WRITE_ENABLE.seq_id,
- &[sequences::SEQ_WRITE_ENABLE]
- ))
- );
-
- defmt::assert_eq!(
- ERASE_SECTOR,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- ERASE_SECTOR.seq_id,
- &[sequences::SEQ_WRITE_ENABLE, sequences::SEQ_ERASE_SECTOR]
- ))
- );
-
- defmt::assert_eq!(
- READ_STATUS,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- READ_STATUS.seq_id,
- &[sequences::SEQ_READ_STATUS]
- ))
- );
-
- defmt::assert_eq!(
- PAGE_PROGRAM,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- PAGE_PROGRAM.seq_id,
- &[
- sequences::SEQ_WRITE_ENABLE,
- sequences::SEQ_PAGE_PROGRAM_QUAD_INPUT
- ]
- ))
- );
-
- defmt::assert_eq!(
- CHIP_ERASE,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- CHIP_ERASE.seq_id,
- &[sequences::SEQ_WRITE_ENABLE, sequences::SEQ_ERASE_CHIP]
- ))
- );
-
- defmt::assert_eq!(
- RESET,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- RESET.seq_id,
- &[sequences::SEQ_RSTEN, sequences::SEQ_RST]
- ))
- );
-
- let set_read_params_data = [set_read_params_data];
- crate::start_ip_cmd(flexspi, SET_READ_PARAMS, 0, &set_read_params_data);
- crate::transmit_bytes(flexspi, &set_read_params_data);
- crate::wait_for_ip_cmd_done(flexspi);
- crate::clear_tx_fifo(flexspi);
- crate::wait_for_idle(flexspi);
- }
-}
diff --git a/src/flash/winbond.rs b/src/flash/winbond.rs
deleted file mode 100644
index afac605..0000000
--- a/src/flash/winbond.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-//! Winbond Serial NOR Flash.
-
-use super::*;
-use crate::{ImxrtFlashAlgorithm, sequences::common as sequences};
-
-pub type W25q64 = Winbond<{ 64 / 8 * 1024 * 1024 }>;
-
-/// A Winbond serial NOR flash driver.
-pub struct Winbond<const FLASH_CAPACITY_BYTES: usize>;
-
-impl<const FLASH_CAPACITY_BYTES: usize> ImxrtFlashAlgorithm for Winbond<FLASH_CAPACITY_BYTES> {
- const FLASH_CAPACITY_BYTES: usize = FLASH_CAPACITY_BYTES;
- const FLASH_PAGE_SIZE_BYTES: usize = 256;
- const FLASH_SECTOR_SIZE_BYTES: usize = 4096;
-
- fn initialize(flexspi: imxrt_drivers_flexspi::Instance) {
- defmt::assert_eq!(
- READ,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- READ.seq_id,
- &[sequences::seq_fast_read_quad_io(6)],
- ))
- );
-
- defmt::assert_eq!(
- SET_READ_PARAMS,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- SET_READ_PARAMS.seq_id,
- &[sequences::SEQ_SET_READ_PARAMS_VOL]
- ))
- );
-
- defmt::assert_eq!(
- WRITE_ENABLE,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- WRITE_ENABLE.seq_id,
- &[sequences::SEQ_WRITE_ENABLE]
- ))
- );
-
- defmt::assert_eq!(
- ERASE_SECTOR,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- ERASE_SECTOR.seq_id,
- &[sequences::SEQ_WRITE_ENABLE, sequences::SEQ_ERASE_SECTOR]
- ))
- );
-
- defmt::assert_eq!(
- READ_STATUS,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- READ_STATUS.seq_id,
- &[sequences::SEQ_READ_STATUS]
- ))
- );
-
- defmt::assert_eq!(
- PAGE_PROGRAM,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- PAGE_PROGRAM.seq_id,
- &[
- sequences::SEQ_WRITE_ENABLE,
- sequences::SEQ_PAGE_PROGRAM_QUAD_INPUT
- ]
- ))
- );
-
- defmt::assert_eq!(
- CHIP_ERASE,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- CHIP_ERASE.seq_id,
- &[sequences::SEQ_WRITE_ENABLE, sequences::SEQ_ERASE_CHIP]
- ))
- );
-
- defmt::assert_eq!(
- RESET,
- defmt::unwrap!(crate::install_ip_cmd(
- flexspi,
- RESET.seq_id,
- &[sequences::SEQ_RSTEN, sequences::SEQ_RST]
- ))
- );
- }
-}
diff --git a/src/imxrt10xx.rs b/src/imxrt10xx.rs
index 095b91d..042574c 100644
--- a/src/imxrt10xx.rs
+++ b/src/imxrt10xx.rs
@@ -17,26 +17,28 @@ pub trait Imxrt10xx: 'static {
fn configure_clocks(ccm: ccm::Instance, ccm_analog: ccm_analog::Instance, dcdc: dcdc::Instance);
}
-pub struct Algorithm<C: Imxrt10xx, F: crate::ImxrtFlashAlgorithm>(PhantomData<(C, F)>);
+pub struct Algorithm<C: Imxrt10xx, const FLASH_SIZE_BYTES: usize>(PhantomData<C>);
-impl<C: Imxrt10xx, F: crate::ImxrtFlashAlgorithm> Algorithm<C, F> {
- pub const fn flash_size_bytes() -> usize {
- F::FLASH_CAPACITY_BYTES
- }
+impl<C: Imxrt10xx, const FLASH_SIZE_BYTES: usize> Algorithm<C, FLASH_SIZE_BYTES> {
pub const fn flash_address() -> usize {
FLEXSPI1_BASE as _
}
- pub const fn sector_size_bytes() -> usize {
- F::FLASH_SECTOR_SIZE_BYTES
+
+ pub const fn flash_size_bytes() -> usize {
+ FLASH_SIZE_BYTES
}
- pub const fn page_size_bytes() -> usize {
- F::FLASH_PAGE_SIZE_BYTES
+
+ pub const fn sector_size_bytes() -> usize {
+ 4 * 1024
}
pub fn initialize() -> Self {
C::configure_clocks(C::CCM_INSTANCE, C::CCM_ANALOG_INSTANCE, C::DCDC_INSTANCE);
- crate::reset(C::FLEXSPI1_INSTANCE, F::FLASH_CAPACITY_BYTES / 1024, 128);
- F::initialize(C::FLEXSPI1_INSTANCE);
+ crate::flash::initialize(
+ C::FLEXSPI1_INSTANCE,
+ FLASH_SIZE_BYTES,
+ C::FLEXSPI_FIFO_CAPACITY_BYTES,
+ );
Algorithm(PhantomData)
}
@@ -53,8 +55,8 @@ impl<C: Imxrt10xx, F: crate::ImxrtFlashAlgorithm> Algorithm<C, F> {
}
}
-impl<C: Imxrt10xx, F: crate::ImxrtFlashAlgorithm> flash_algorithm::FlashAlgorithm
- for Algorithm<C, F>
+impl<C: Imxrt10xx, const FLASH_SIZE_BYTES: usize> flash_algorithm::FlashAlgorithm
+ for Algorithm<C, FLASH_SIZE_BYTES>
{
fn new(
_: u32,
diff --git a/src/imxrt11xx.rs b/src/imxrt11xx.rs
index 7fc9763..75d5020 100644
--- a/src/imxrt11xx.rs
+++ b/src/imxrt11xx.rs
@@ -157,20 +157,19 @@ pub trait Imxrt11xx: 'static {
const FLEXSPI_FIFO_CAPACITY_BYTES: usize;
}
-pub struct Algorithm<C: Imxrt11xx, F: crate::ImxrtFlashAlgorithm>(PhantomData<(C, F)>);
+pub struct Algorithm<C: Imxrt11xx, const FLASH_SIZE_BYTES: usize>(PhantomData<C>);
-impl<C: Imxrt11xx, F: crate::ImxrtFlashAlgorithm> Algorithm<C, F> {
- pub const fn flash_size_bytes() -> usize {
- F::FLASH_CAPACITY_BYTES
- }
+impl<C: Imxrt11xx, const FLASH_SIZE_BYTES: usize> Algorithm<C, FLASH_SIZE_BYTES> {
pub const fn flash_address() -> usize {
FLEXSPI1_BASE as _
}
- pub const fn sector_size_bytes() -> usize {
- F::FLASH_SECTOR_SIZE_BYTES
+
+ pub const fn flash_size_bytes() -> usize {
+ FLASH_SIZE_BYTES
}
- pub const fn page_size_bytes() -> usize {
- F::FLASH_PAGE_SIZE_BYTES
+
+ pub const fn sector_size_bytes() -> usize {
+ 4 * 1024
}
pub fn initialize() -> Self {
@@ -182,12 +181,11 @@ impl<C: Imxrt11xx, F: crate::ImxrtFlashAlgorithm> Algorithm<C, F> {
C::PMU_INSTANCE,
C::GPC_CPU_INSTANCE,
);
- crate::reset(
+ crate::flash::initialize(
C::FLEXSPI1_INSTANCE,
- F::FLASH_CAPACITY_BYTES / 1024,
+ FLASH_SIZE_BYTES,
C::FLEXSPI_FIFO_CAPACITY_BYTES,
);
- F::initialize(C::FLEXSPI1_INSTANCE);
Algorithm(PhantomData)
}
@@ -204,8 +202,8 @@ impl<C: Imxrt11xx, F: crate::ImxrtFlashAlgorithm> Algorithm<C, F> {
}
}
-impl<C: Imxrt11xx, F: crate::ImxrtFlashAlgorithm> flash_algorithm::FlashAlgorithm
- for Algorithm<C, F>
+impl<C: Imxrt11xx, const FLASH_SIZE_BYTES: usize> flash_algorithm::FlashAlgorithm
+ for Algorithm<C, FLASH_SIZE_BYTES>
{
fn new(
_: u32,
diff --git a/src/lib.rs b/src/lib.rs
index 8f1203f..eeaa022 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,10 +12,6 @@ pub mod sequences {
pub mod flash {
use super::{IpCmd, SeqId, flexspi};
- pub mod adesto;
- pub mod issi;
- pub mod winbond;
-
/// Conveniently the default AHB read sequence index.
const READ: IpCmd = IpCmd::new(SeqId::Seq00, 1).unwrap();
const READ_STATUS: IpCmd = IpCmd::new(SeqId::Seq01, 1).unwrap();
@@ -24,9 +20,8 @@ pub mod flash {
const PAGE_PROGRAM: IpCmd = IpCmd::new(SeqId::Seq09, 2).unwrap();
const CHIP_ERASE: IpCmd = IpCmd::new(SeqId::Seq11, 2).unwrap();
- const SET_READ_PARAMS: IpCmd = IpCmd::new(SeqId::Seq02, 1).unwrap();
const READ_ID_JEDEC_ID: IpCmd = IpCmd::new(SeqId::Seq04, 1).unwrap();
- const RESET: IpCmd = IpCmd::new(SeqId::Seq07, 2).unwrap();
+ const READ_READ_PARAMS: IpCmd = IpCmd::new(SeqId::Seq02, 1).unwrap();
const PAGE_SIZE_BYTES: usize = 256;
@@ -109,15 +104,6 @@ pub mod flash {
wait_for_wip_clear(flexspi);
}
- /// Reset the flash chip.
- pub fn reset(flexspi: flexspi::Instance) {
- crate::start_ip_cmd(flexspi, RESET, 0, &[]);
- crate::wait_for_ip_cmd_done(flexspi);
- crate::wait_for_idle(flexspi);
-
- wait_for_wip_clear(flexspi);
- }
-
#[derive(Debug, Clone, Copy, PartialEq, defmt::Format)]
pub struct JedecId {
pub mnf_id: u8,
@@ -141,6 +127,17 @@ pub mod flash {
}
}
+ /// Read the read register parameters.
+ pub fn read_read_params(flexspi: flexspi::Instance) -> u8 {
+ let mut buffer = [0_u8; 1];
+ crate::start_ip_cmd(flexspi, READ_READ_PARAMS, 0, &buffer);
+ crate::receive_bytes(flexspi, &mut buffer);
+ crate::wait_for_ip_cmd_done(flexspi);
+ crate::clear_rx_fifo(flexspi);
+ crate::wait_for_idle(flexspi);
+ buffer[0]
+ }
+
/// Produce chunks of bytes suitable for page aligned writing.
fn aligned_chunks(start: usize, bytes: &[u8], page_size: usize) -> impl Iterator<Item = &[u8]> {
let next_page_start = page_size - (start % page_size);
@@ -199,6 +196,165 @@ pub mod flash {
assert_eq!(chunks.next(), None);
}
}
+
+ /// Supported NOR flash parts.
+ #[derive(Clone, Copy, defmt::Format)]
+ enum FlashKind {
+ /// Issi 1.8V
+ Is25wp,
+ /// Issi 3.3V
+ Is25lp,
+ /// Adesto 3.3V.
+ At25sf,
+ /// Winbond.
+ W25q,
+ }
+
+ const ISSI_MF_ID: u8 = 0x9D;
+ const WINBOND_MF_ID: u8 = 0xEF;
+ const ADESTO_MF_ID: u8 = 0x1F;
+
+ impl FlashKind {
+ fn discover(jedec_id: &JedecId) -> Option<Self> {
+ let flash = match jedec_id.mnf_id {
+ ISSI_MF_ID => Self::discover_issi(jedec_id)?,
+ WINBOND_MF_ID => Self::discover_winbond(jedec_id)?,
+ ADESTO_MF_ID => Self::discover_adesto(jedec_id)?,
+ _ => return None,
+ };
+
+ Some(flash)
+ }
+
+ fn discover_winbond(_: &JedecId) -> Option<FlashKind> {
+ Some(FlashKind::W25q)
+ }
+
+ fn discover_adesto(_: &JedecId) -> Option<FlashKind> {
+ Some(FlashKind::At25sf)
+ }
+
+ fn discover_issi(jedec_id: &JedecId) -> Option<FlashKind> {
+ const ISSI_WP_MEM_TYPE: u8 = 0x70;
+ const ISSI_LP_MEM_TYPE: u8 = 0x60;
+
+ Some(match jedec_id.mem_type {
+ ISSI_WP_MEM_TYPE => FlashKind::Is25wp,
+ ISSI_LP_MEM_TYPE => FlashKind::Is25lp,
+ _ => return None,
+ })
+ }
+ }
+
+ /// Figure the fast read quad I/O dummy cycles, possibly
+ /// querying the part to discover the value.
+ ///
+ /// This function should check against rated speeds, when
+ /// applicable, to make sure you're not going too fast.
+ fn discover_frqio_dummy_cycles(kind: FlashKind, flexspi: flexspi::Instance) -> u8 {
+ match kind {
+ FlashKind::At25sf | FlashKind::W25q => 6,
+ FlashKind::Is25wp => {
+ let read_params = read_read_params(flexspi);
+ let dummy_cycles = (read_params >> 3) & 0b1111;
+ if dummy_cycles == 0 { 6 } else { dummy_cycles }
+ }
+ FlashKind::Is25lp => {
+ // READ_READ_PARAMS not supported.
+ // Guess that the user has set the
+ // default value.
+ 6
+ }
+ }
+ }
+
+ use super::sequences::common as sequences;
+
+ pub fn initialize(
+ flexspi: flexspi::Instance,
+ flash_size_bytes: usize,
+ fifo_capacity_bytes: usize,
+ ) {
+ crate::reset(flexspi, flash_size_bytes / 1024, fifo_capacity_bytes);
+
+ defmt::assert_eq!(
+ READ_ID_JEDEC_ID,
+ defmt::unwrap!(crate::install_ip_cmd(
+ flexspi,
+ READ_ID_JEDEC_ID.seq_id,
+ &[sequences::SEQ_READ_ID_JEDEC_ID]
+ ))
+ );
+ defmt::assert_eq!(
+ READ_READ_PARAMS,
+ defmt::unwrap!(crate::install_ip_cmd(
+ flexspi,
+ READ_READ_PARAMS.seq_id,
+ &[sequences::SEQ_READ_READ_PARAMS]
+ ))
+ );
+
+ let jedec_id = read_jedec_id(flexspi);
+ let flash = defmt::unwrap!(FlashKind::discover(&jedec_id), "{:?}", jedec_id);
+ let dummy_cycles = discover_frqio_dummy_cycles(flash, flexspi);
+
+ defmt::assert_eq!(
+ READ,
+ defmt::unwrap!(crate::install_ip_cmd(
+ flexspi,
+ READ.seq_id,
+ &[sequences::seq_fast_read_quad_io(dummy_cycles)],
+ ))
+ );
+
+ defmt::assert_eq!(
+ WRITE_ENABLE,
+ defmt::unwrap!(crate::install_ip_cmd(
+ flexspi,
+ WRITE_ENABLE.seq_id,
+ &[sequences::SEQ_WRITE_ENABLE]
+ ))
+ );
+
+ defmt::assert_eq!(
+ ERASE_SECTOR,
+ defmt::unwrap!(crate::install_ip_cmd(
+ flexspi,
+ ERASE_SECTOR.seq_id,
+ &[sequences::SEQ_WRITE_ENABLE, sequences::SEQ_ERASE_SECTOR]
+ ))
+ );
+
+ defmt::assert_eq!(
+ READ_STATUS,
+ defmt::unwrap!(crate::install_ip_cmd(
+ flexspi,
+ READ_STATUS.seq_id,
+ &[sequences::SEQ_READ_STATUS]
+ ))
+ );
+
+ defmt::assert_eq!(
+ PAGE_PROGRAM,
+ defmt::unwrap!(crate::install_ip_cmd(
+ flexspi,
+ PAGE_PROGRAM.seq_id,
+ &[
+ sequences::SEQ_WRITE_ENABLE,
+ sequences::SEQ_PAGE_PROGRAM_QUAD_INPUT
+ ]
+ ))
+ );
+
+ defmt::assert_eq!(
+ CHIP_ERASE,
+ defmt::unwrap!(crate::install_ip_cmd(
+ flexspi,
+ CHIP_ERASE.seq_id,
+ &[sequences::SEQ_WRITE_ENABLE, sequences::SEQ_ERASE_CHIP]
+ ))
+ );
+ }
}
pub mod imxrt10xx;
@@ -491,11 +647,3 @@ impl Iterator for FifoReader {
Some(word)
}
}
-
-pub trait ImxrtFlashAlgorithm: 'static {
- const FLASH_CAPACITY_BYTES: usize;
- const FLASH_SECTOR_SIZE_BYTES: usize;
- const FLASH_PAGE_SIZE_BYTES: usize;
-
- fn initialize(flexspi: flexspi::Instance);
-}
diff --git a/src/sequences/common.rs b/src/sequences/common.rs
index 4bb9493..1c93067 100644
--- a/src/sequences/common.rs
+++ b/src/sequences/common.rs
@@ -88,3 +88,11 @@ pub const SEQ_READ_ID_JEDEC_ID: Sequence = {
instr[1] = Instr::new(SDR_READ, Pads::One, 0);
Sequence(instr)
};
+
+/// Read the read parameters register.
+pub const SEQ_READ_READ_PARAMS: Sequence = {
+ let mut instr = [Instr::STOP; _];
+ instr[0] = Instr::new(SDR_CMD, Pads::One, 0x61);
+ instr[1] = Instr::new(SDR_READ, Pads::One, 0);
+ Sequence(instr)
+};