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}