1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
/// Describes the shape of the flash configuration header that the Boot ROM
/// expects to find at offset 0x0400 in the flash memory connected to
/// FlexSPI0, if booting from that device.
///
/// The board support package for a board that boots from flash memory on
/// FlexSPI0 should arrange for a suitable value of this type to be placed at
/// 0x0400 in the flash image (0x08000400 if the Flash will be memory mapped)
/// and then the on-chip Boot ROM will retrieve it during boot.
///
/// See _i.MX RT500 Reference Manual_ section 18.6.1.2:
/// FlexSPI NOR Configuration Block(FCB).
#[repr(C)]
#[derive(Clone, Copy)]
pub struct FlexSpiNorFlashConfig {
/// Common memory configuration info via FlexSPI.
pub mem_config: FlexSpiMemConfig,
/// Page size of serial NOR.
pub page_size: u32,
/// Sector size of serial NOR.
pub sector_size: u32,
/// Clock frequency for IP command.
pub ip_cmd_serial_clk_freq: u8,
/// Sector/block size is the same.
pub is_uniform_block_size: u8,
/// Data order (D0, D1, D2, D3) is swapped (D1, D0, D3, D2).
pub is_data_order_swapped: u8,
/// Reserved for future use.
pub reserved0: [u8; 1],
/// Serial NOR flash type: 0/1/2/3.
pub serial_nor_type: u8,
/// Need to exit NoCmd mode before other IP command.
pub need_exit_no_cmd_mode: u8,
/// Half the Serial Clock for non-read command: true/false.
pub half_clk_for_non_read_cmd: u8,
/// Need to Restore NoCmd mode after IP commmand execution.
pub need_restore_no_cmd_mode: u8,
/// Block size.
pub block_size: u32,
/// Flash state context.
pub flash_state_ctx: u32,
/// Reserved for future use.
pub reserved2: [u32; 10],
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct FlexSpiMemConfig {
/// Tag, fixed value `0x42464346`.
pub tag: u32,
/// Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix.
pub version: u32,
/// Reserved for future use.
pub reserved0: u32,
/// Read Sample Clock Source, valid value: 0/1/3.
pub read_sample_clk_src: u8,
/// CS hold time, default value: 3.
pub cs_hold_time: u8,
/// CS setup time, default value: 3.
pub cs_setup_time: u8,
/// Column Address with, for HyperBus protocol, it is fixed to 3, For
/// Serial NAND, need to refer to datasheet.
pub column_address_width: u8,
/// Device Mode Configure enable flag, 1 - Enable, 0 - Disable.
pub device_mode_cfg_enable: u8,
/// Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch,
/// Generic configuration, etc.
pub device_mode_type: u8,
/// Wait time for all configuration commands, unit: 100us, Used for
/// DPI/QPI/OPI switch or reset command.
pub wait_time_cfg_commands: u16,
/// Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt
/// sequence number, [31:16] Reserved.
pub device_mode_seq: FlexSpiLutSeq,
/// Argument/Parameter for device configuration.
pub device_mode_arg: u32,
/// Configure command Enable Flag, 1 - Enable, 0 - Disable.
pub config_cmd_enable: u8,
/// Configure Mode Type, similar as `device_mode_type`.
pub config_mode_type: [u8; 3],
/// Sequence info for Device Configuration command, similar as `device_mode_seq`.
pub config_cmd_seqs: [FlexSpiLutSeq; 3],
/// Reserved for future use.
pub reserved1: u32,
/// Arguments/Parameters for device Configuration commands.
pub config_cmd_args: [u32; 3],
/// Reserved for future use.
pub reserved2: u32,
/// Controller Misc Options, see Misc feature bit definitions for more details.
pub controller_misc_option: u32,
/// Device Type: See Flash Type Definition for more details.
pub device_type: u8,
/// Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal.
pub serial_flash_pad_type: u8,
/// Serial Flash Frequencey, device specific definitions, See System Boot
/// Chapter for more details.
pub serial_clk_freq: u8,
/// LUT customization Enable, it is required if the program/erase cannot
/// be done using 1 LUT sequence, currently, only applicable to HyperFLASH.
pub lut_custom_seq_enable: u8,
/// Reserved for future use.
pub reserved3: [u32; 2],
/// Size of Flash connected to A1.
pub serial_flash_a1_size: u32,
/// Size of Flash connected to A2.
pub serial_flash_a2_size: u32,
/// Size of Flash connected to B1.
pub serial_flash_b1_size: u32,
/// Size of Flash connected to B2.
pub serial_flash_b2_size: u32,
/// CS pad setting override value.
pub cs_pad_setting_override: u32,
/// SCLK pad setting override value.
pub sclk_pad_setting_override: u32,
/// Data pad setting override value.
pub data_pad_setting_override: u32,
/// DQS pad setting override value.
pub dqs_pad_setting_override: u32,
/// Timeout threshold for read status command.
pub timeout_in_ms: u32,
/// CS deselect interval between two commands.
pub command_interval: u32,
/// CLK edge to data valid time for PORT A and PORT B.
pub data_valid_time: [FlexSpiDllTime; 2],
/// Busy offset, valid value: 0-31.
pub busy_offset: u16,
/// Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 -
/// busy flag is 0 when flash device is busy.
pub busy_bit_polarity: u16,
/// Lookup table holds Flash command sequences.
pub lookup_table: [u32; 64],
/// Customizable LUT Sequences.
pub lut_custom_seq: [FlexSpiLutSeq; 12],
/// Reserved for future use.
pub reserved4: [u32; 4],
}
impl FlexSpiMemConfig {
pub const TAG: u32 = 0x42464346;
pub const VERSION: u32 = 0x56010400;
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct FlexSpiLutSeq {
/// Sequence Number, valid number: 1-16.
pub seq_num: u8,
/// Sequence index, valid number: 0-15.
pub seq_id: u8,
/// Reserved for future use.
pub reserved: u16,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct FlexSpiDllTime {
/// Data valid time, in terms of 100ps.
pub time_100ps: u8,
/// Data valid time, in terms of delay cells.
pub delay_cells: u8,
}
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum FlexspiLutCmd {
CMD_SDR = 0x01,
CMD_DDR = 0x21,
RADDR_SDR = 0x02,
RADDR_DDR = 0x22,
CADDR_SDR = 0x03,
CADDR_DDR = 0x23,
MODE1_SDR = 0x04,
MODE1_DDR = 0x24,
MODE2_SDR = 0x05,
MODE2_DDR = 0x25,
MODE4_SDR = 0x06,
MODE4_DDR = 0x26,
MODE8_SDR = 0x07,
MODE8_DDR = 0x27,
WRITE_SDR = 0x08,
WRITE_DDR = 0x28,
READ_SDR = 0x09,
READ_DDR = 0x29,
LEARN_SDR = 0x0A,
LEARN_DDR = 0x2A,
DATSZ_SDR = 0x0B,
DATSZ_DDR = 0x2B,
DUMMY_SDR = 0x0C,
DUMMY_DDR = 0x2C,
DUMMY_RWDS_SDR = 0x0D,
DUMMY_RWDS_DDR = 0x2D,
JMP_ON_CS = 0x1F,
STOP_EXE = 0,
}
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum FlexspiPad {
FLEXSPI_1PAD = 0,
FLEXSPI_2PAD = 1,
FLEXSPI_4PAD = 2,
FLEXSPI_8PAD = 3,
}
pub const fn flexspi_lut_seq(
cmd0: FlexspiLutCmd,
pad0: FlexspiPad,
op0: u8,
cmd1: FlexspiLutCmd,
pad1: FlexspiPad,
op1: u8,
) -> u32 {
let cmd0_raw = ((cmd0 as u32) << 10) & 0xfc00;
let pad0_raw = ((pad0 as u32) << 8) & 0x300;
let op0_raw = ((op0 as u32) << 0) & 0xff;
let cmd1_raw = ((cmd1 as u32) << 26) & 0xfc000000;
let pad1_raw = ((pad1 as u32) << 24) & 0x3000000;
let op1_raw = ((op1 as u32) << 16) & 0xff0000;
cmd0_raw | pad0_raw | op0_raw | cmd1_raw | pad1_raw | op1_raw
}