mimxrt500_bootstub/
bootrom.rs

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