diff --git a/README.md b/README.md index 1f0e205..b191a4a 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,14 @@ TODO TODO +### Implementing a new device + +If you end up depending on a fork or a newer version of this crate than the +HAL crate for your device, you can override the version pulled in by the +external crate using a `[patch]` section in your `Cargo.toml`, as described +in the +[Cargo Book](https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html#the-patch-section). + ## Releasing * Update Cargo.toml diff --git a/src/devices/is42s16400j.rs b/src/devices/is42s16400j.rs index c8e042a..09a3f36 100644 --- a/src/devices/is42s16400j.rs +++ b/src/devices/is42s16400j.rs @@ -3,7 +3,7 @@ /// Speed Grade 7 pub mod is42s16400j_7 { - use crate::sdram::{FmcSdramConfiguration, FmcSdramTiming, SdramChip}; + use crate::sdram::{SdramChip, SdramConfiguration, SdramTiming}; const BURST_LENGTH_1: u16 = 0x0000; const BURST_LENGTH_2: u16 = 0x0001; @@ -32,7 +32,7 @@ pub mod is42s16400j_7 { | WRITEBURST_MODE_SINGLE; /// Timing Parameters - const TIMING: FmcSdramTiming = FmcSdramTiming { + const TIMING: SdramTiming = SdramTiming { startup_delay_ns: 100_000, // 100 µs max_sd_clock_hz: 100_000_000, // 100 MHz refresh_period_ns: 15_625, // 64ms / (4096 rows) = 15625ns @@ -45,7 +45,7 @@ pub mod is42s16400j_7 { }; /// SDRAM controller configuration - const CONFIG: FmcSdramConfiguration = FmcSdramConfiguration { + const CONFIG: SdramConfiguration = SdramConfiguration { column_bits: 8, row_bits: 12, memory_data_width: 16, // 16-bit diff --git a/src/devices/is42s32800g.rs b/src/devices/is42s32800g.rs index e47d3af..2c8ec2b 100644 --- a/src/devices/is42s32800g.rs +++ b/src/devices/is42s32800g.rs @@ -3,7 +3,7 @@ /// Speed Grade 6 pub mod is42s32800g_6 { - use crate::sdram::{FmcSdramConfiguration, FmcSdramTiming, SdramChip}; + use crate::sdram::{SdramChip, SdramConfiguration, SdramTiming}; const BURST_LENGTH_1: u16 = 0x0000; const BURST_LENGTH_2: u16 = 0x0001; @@ -30,7 +30,7 @@ pub mod is42s32800g_6 { | WRITEBURST_MODE_SINGLE; /// Timing Parameters - const TIMING: FmcSdramTiming = FmcSdramTiming { + const TIMING: SdramTiming = SdramTiming { startup_delay_ns: 100_000, // 100 µs max_sd_clock_hz: 100_000_000, // 100 MHz refresh_period_ns: 15_625, // 64ms / (4096 rows) = 15625ns @@ -43,7 +43,7 @@ pub mod is42s32800g_6 { }; /// SDRAM controller configuration - const CONFIG: FmcSdramConfiguration = FmcSdramConfiguration { + const CONFIG: SdramConfiguration = SdramConfiguration { column_bits: 9, row_bits: 12, memory_data_width: 32, // 32-bit diff --git a/src/devices/mt48lc4m32b2.rs b/src/devices/mt48lc4m32b2.rs index 22d90aa..661e3be 100644 --- a/src/devices/mt48lc4m32b2.rs +++ b/src/devices/mt48lc4m32b2.rs @@ -5,7 +5,7 @@ /// Speed Grade 6 pub mod mt48lc4m32b2_6 { - use crate::sdram::{FmcSdramConfiguration, FmcSdramTiming, SdramChip}; + use crate::sdram::{SdramChip, SdramConfiguration, SdramTiming}; const BURST_LENGTH_1: u16 = 0x0000; const BURST_LENGTH_2: u16 = 0x0001; @@ -32,7 +32,7 @@ pub mod mt48lc4m32b2_6 { | WRITEBURST_MODE_SINGLE; /// Timing Parameters - const TIMING: FmcSdramTiming = FmcSdramTiming { + const TIMING: SdramTiming = SdramTiming { startup_delay_ns: 100_000, // 100 µs max_sd_clock_hz: 100_000_000, // 100 MHz refresh_period_ns: 15_625, // 64ms / (4096 rows) = 15625ns @@ -45,7 +45,7 @@ pub mod mt48lc4m32b2_6 { }; /// SDRAM controller configuration - const CONFIG: FmcSdramConfiguration = FmcSdramConfiguration { + const CONFIG: SdramConfiguration = SdramConfiguration { column_bits: 9, row_bits: 12, memory_data_width: 32, // 32-bit diff --git a/src/lib.rs b/src/lib.rs index 448a8ef..bef3d17 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,7 +140,10 @@ pub use fmc::*; #[cfg(feature = "sdram")] mod sdram; #[cfg(feature = "sdram")] -pub use sdram::{PinsSdram, Sdram, SdramChip, SdramPinSet, SdramTargetBank}; +pub use sdram::{ + PinsSdram, Sdram, SdramChip, SdramConfiguration, SdramPinSet, + SdramTargetBank, SdramTiming, +}; /// Memory device definitions pub mod devices; diff --git a/src/sdram.rs b/src/sdram.rs index 4306e7d..95119ae 100644 --- a/src/sdram.rs +++ b/src/sdram.rs @@ -13,7 +13,7 @@ use crate::ral::{fmc, modify_reg, write_reg}; /// FMC SDRAM Configuration Structure definition #[derive(Clone, Copy, Debug, PartialEq)] -pub struct FmcSdramConfiguration { +pub struct SdramConfiguration { /// Number of bits of column address pub column_bits: u8, /// Number of bits of column address @@ -34,7 +34,7 @@ pub struct FmcSdramConfiguration { /// FMC SDRAM Timing parameters structure definition #[derive(Clone, Copy, Debug, PartialEq)] -pub struct FmcSdramTiming { +pub struct SdramTiming { /// Time between applying a valid clock and any command other than /// COMMAND INHIBIT or NOP pub startup_delay_ns: u32, @@ -62,10 +62,10 @@ pub trait SdramChip { const MODE_REGISTER: u16; /// SDRAM controller configuration - const CONFIG: FmcSdramConfiguration; + const CONFIG: SdramConfiguration; /// Timing parameters - const TIMING: FmcSdramTiming; + const TIMING: SdramTiming; } /// SDRAM Controller @@ -338,8 +338,8 @@ impl Sdram { /// For example, see RM0433 rev 7 Section 22.9.3 unsafe fn set_features_timings( &mut self, - config: FmcSdramConfiguration, - timing: FmcSdramTiming, + config: SdramConfiguration, + timing: SdramTiming, sd_clock_divide: u32, ) { // Features ---- SDCR REGISTER diff --git a/tests/sdram_pin.rs b/tests/sdram_pin.rs index 6dd7cba..0ce7c7d 100644 --- a/tests/sdram_pin.rs +++ b/tests/sdram_pin.rs @@ -100,3 +100,67 @@ fn sdram_pins_12a_4b_not_enough_bank_pins() { // Check we can create a SDRAM Sdram::new(fmc, pins, chip); } + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct DummyChip {} + +const BURST_LENGTH_1: u16 = 0x0000; +const BURST_TYPE_SEQUENTIAL: u16 = 0x0000; +const CAS_LATENCY_3: u16 = 0x0030; +const OPERATING_MODE_STANDARD: u16 = 0x0000; +const WRITEBURST_MODE_SINGLE: u16 = 0x0200; + +impl SdramChip for DummyChip { + const MODE_REGISTER: u16 = BURST_LENGTH_1 + | BURST_TYPE_SEQUENTIAL + | CAS_LATENCY_3 + | OPERATING_MODE_STANDARD + | WRITEBURST_MODE_SINGLE; + + const CONFIG: stm32_fmc::SdramConfiguration = SdramConfiguration { + column_bits: 9, + row_bits: 12, + memory_data_width: 32, // 32-bit + internal_banks: 4, // 4 internal banks + cas_latency: 3, // CAS latency = 3 + write_protection: false, + read_burst: true, + read_pipe_delay_cycles: 0, + }; + + const TIMING: stm32_fmc::SdramTiming = SdramTiming { + startup_delay_ns: 100_000, // 100 µs + max_sd_clock_hz: 100_000_000, // 100 MHz + refresh_period_ns: 15_625, // 64ms / (4096 rows) = 15625ns + mode_register_to_active: 2, // tMRD = 2 cycles + exit_self_refresh: 7, // tXSR = 70ns + active_to_precharge: 4, // tRAS = 42ns + row_cycle: 7, // tRC = 70ns + row_precharge: 2, // tRP = 18ns + row_to_column: 2, // tRCD = 18ns + }; +} + +#[test] +/// Test that we can implement the SdramChip trait +fn sdram_chip_impl() { + let fmc = DummyFMC {}; + let pins = fmc_pin_set!( + // 12 address bits + A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, + // 4 internal banks -------------------------------------- + BA0, BA1, + // 32 bit data ------------------------------------------- + D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, + D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, + D30, D31, + // NBL0-3 ------------------------------------------------ + NBL0, NBL1, NBL2, NBL3, + // SDRAM Bank 0 ------------------------------------------ + SDCKE0, SDCLK, SDNCAS, SDNE0, SDNRAS, SDNWE + ); + let chip = DummyChip {}; + + // Check we can create a SDRAM + Sdram::new(fmc, pins, chip); +}