Skip to content

Commit 699f19f

Browse files
authored
Merge pull request #3522 from tannewt/imx_metro
Unify iMX RT flash config and add Metro M7 1011
2 parents e1a80ae + ef42d6b commit 699f19f

File tree

26 files changed

+1394
-961
lines changed

26 files changed

+1394
-961
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ jobs:
243243
- "metro_m0_express"
244244
- "metro_m4_airlift_lite"
245245
- "metro_m4_express"
246+
- "metro_m7_1011"
246247
- "metro_nrf52840_express"
247248
- "mini_sam_m4"
248249
- "monster_m4sk"

extmod/vfs_fat_diskio.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ DRESULT disk_write (
123123

124124
DRESULT disk_ioctl (
125125
bdev_t pdrv, /* Physical drive nmuber (0..) */
126-
BYTE cmd, /* Control code */
126+
BYTE cmd, /* Control code */
127127
void *buff /* Buffer to send/receive control data */
128128
)
129129
{
@@ -133,7 +133,7 @@ DRESULT disk_ioctl (
133133
}
134134

135135
// First part: call the relevant method of the underlying block device
136-
mp_obj_t ret = mp_const_none;
136+
mp_int_t out_value = 0;
137137
if (vfs->flags & FSUSER_HAVE_IOCTL) {
138138
// new protocol with ioctl
139139
static const uint8_t op_map[8] = {
@@ -144,9 +144,19 @@ DRESULT disk_ioctl (
144144
};
145145
uint8_t bp_op = op_map[cmd & 7];
146146
if (bp_op != 0) {
147-
vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(bp_op);
148-
vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
149-
ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl);
147+
if (vfs->flags & FSUSER_NATIVE) {
148+
bool (*f)(size_t, mp_int_t*) = (void*)(uintptr_t)vfs->u.ioctl[2];
149+
if (!f(bp_op, (mp_int_t*) &out_value)) {
150+
return RES_ERROR;
151+
}
152+
} else {
153+
vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(bp_op);
154+
vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
155+
mp_obj_t ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl);
156+
if (ret != mp_const_none) {
157+
out_value = mp_obj_get_int(ret);
158+
}
159+
}
150160
}
151161
} else {
152162
// old protocol with sync and count
@@ -157,10 +167,13 @@ DRESULT disk_ioctl (
157167
}
158168
break;
159169

160-
case GET_SECTOR_COUNT:
161-
ret = mp_call_method_n_kw(0, 0, vfs->u.old.count);
170+
case GET_SECTOR_COUNT: {
171+
mp_obj_t ret = mp_call_method_n_kw(0, 0, vfs->u.old.count);
172+
if (ret != mp_const_none) {
173+
out_value = mp_obj_get_int(ret);
174+
}
162175
break;
163-
176+
}
164177
case GET_SECTOR_SIZE:
165178
// old protocol has fixed sector size of 512 bytes
166179
break;
@@ -177,16 +190,16 @@ DRESULT disk_ioctl (
177190
return RES_OK;
178191

179192
case GET_SECTOR_COUNT: {
180-
*((DWORD*)buff) = mp_obj_get_int(ret);
193+
*((DWORD*)buff) = out_value;
181194
return RES_OK;
182195
}
183196

184197
case GET_SECTOR_SIZE: {
185-
if (ret == mp_const_none) {
198+
if (out_value == 0) {
186199
// Default sector size
187200
*((WORD*)buff) = 512;
188201
} else {
189-
*((WORD*)buff) = mp_obj_get_int(ret);
202+
*((WORD*)buff) = out_value;
190203
}
191204
#if _MAX_SS != _MIN_SS
192205
// need to store ssize because we use it in disk_read/disk_write
@@ -202,7 +215,7 @@ DRESULT disk_ioctl (
202215
case IOCTL_INIT:
203216
case IOCTL_STATUS: {
204217
DSTATUS stat;
205-
if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0) {
218+
if (out_value != 0) {
206219
// error initialising
207220
stat = STA_NOINIT;
208221
} else if (vfs->writeblocks[0] == MP_OBJ_NULL) {

ports/mimxrt10xx/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ INC += \
7575

7676
# NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt.
7777

78-
CFLAGS += -Os -DNDEBUG
78+
CFLAGS += -Os -DNDEBUG -ffreestanding
7979

8080
# TinyUSB defines
8181
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX -DCFG_TUD_MIDI_RX_BUFSIZE=512 -DCFG_TUD_CDC_RX_BUFSIZE=512 -DCFG_TUD_MIDI_TX_BUFSIZE=512 -DCFG_TUD_CDC_TX_BUFSIZE=512 -DCFG_TUD_MSC_BUFSIZE=1024

ports/mimxrt10xx/boards/board.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include "py/mpconfig.h"
3535
#include "fsl_common.h"
36+
#include "fsl_flexspi_nor_config.h"
3637

3738
// Initializes board related state once on start up.
3839
void board_init(void);
@@ -45,4 +46,11 @@ bool board_requests_safe_mode(void);
4546
// Reset the state of off MCU components such as neopixels.
4647
void reset_board(void);
4748

49+
#define SEQUENCE(first, second, third, fourth) first, second, third, fourth
50+
#define TWO_EMPTY_STEPS 0x00000000
51+
#define EMPTY_SEQUENCE SEQUENCE(TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS)
52+
53+
// FlexSPI configuration that stores command info.
54+
extern const flexspi_nor_config_t qspiflash_config;
55+
4856
#endif // MICROPY_INCLUDED_MIMXRT10XX_BOARDS_BOARD_H

ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c

Lines changed: 117 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
#include "fsl_flexspi_nor_boot.h"
9-
#include "fsl_flexspi_nor_config.h"
9+
#include "boards/board.h"
1010

1111

1212
__attribute__((section(".boot_hdr.ivt")))
@@ -35,88 +35,135 @@ const BOOT_DATA_T boot_data = {
3535
0xFFFFFFFF /* empty - extra data word */
3636
};
3737

38+
// Config for W25Q32JV with QSPI routed.
3839
__attribute__((section(".boot_hdr.conf")))
39-
// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
4040
const flexspi_nor_config_t qspiflash_config = {
41+
.pageSize = 256u,
42+
.sectorSize = 4u * 1024u,
43+
.ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
44+
.blockSize = 0x00010000,
45+
.isUniformBlockSize = false,
4146
.memConfig =
4247
{
4348
.tag = FLEXSPI_CFG_BLK_TAG,
4449
.version = FLEXSPI_CFG_BLK_VERSION,
4550
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
46-
.csHoldTime = 1u,
47-
.csSetupTime = 2u,
48-
// Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
51+
.csHoldTime = 3u,
52+
.csSetupTime = 3u,
53+
54+
.busyOffset = 0u, // Status bit 0 indicates busy.
55+
.busyBitPolarity = 0u, // Busy when the bit is 1.
56+
57+
.deviceModeCfgEnable = 1u,
58+
.deviceModeType = kDeviceConfigCmdType_QuadEnable,
59+
.deviceModeSeq = {
60+
.seqId = 4u,
61+
.seqNum = 1u,
62+
},
63+
.deviceModeArg = 0x02, // Bit pattern for setting Quad Enable.
4964
.deviceType = kFlexSpiDeviceType_SerialNOR,
5065
.sflashPadType = kSerialFlash_4Pads,
51-
.serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
66+
.serialClkFreq = kFlexSpiSerialClk_133MHz,
5267
.sflashA1Size = FLASH_SIZE,
5368
.lookupTable =
5469
{
5570
// FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
56-
// (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
57-
// FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
58-
// Read LUTs
59-
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
60-
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
61-
0,
62-
0,
63-
64-
0x24040405,
65-
0,
66-
0,
67-
0,
68-
69-
0,
70-
0,
71-
0,
72-
0,
73-
74-
0x00000406,
75-
0,
76-
0,
77-
0,
78-
79-
0,
80-
0,
81-
0,
82-
0,
83-
84-
0x08180420,
85-
0,
86-
0,
87-
0,
88-
89-
0,
90-
0,
91-
0,
92-
0,
93-
94-
0,
95-
0,
96-
0,
97-
0,
98-
99-
0x081804D8,
100-
0,
101-
0,
102-
0,
103-
104-
0x08180402,
105-
0x00002004,
106-
0,
107-
0,
108-
109-
0,
110-
0,
111-
0,
112-
0,
113-
114-
0x00000460,
71+
// The high 16 bits is command 1 and the low are command 0.
72+
// Within a command, the top 6 bits are the opcode, the next two are the number
73+
// of pads and then last byte is the operand. The operand's meaning changes
74+
// per opcode.
75+
76+
// Indices with ROM should always have the same function because the ROM
77+
// bootloader uses it.
78+
79+
// 0: ROM: Read LUTs
80+
// Quad version
81+
SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */,
82+
RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */),
83+
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */,
84+
READ_SDR, FLEXSPI_4PAD, 0x04),
85+
// Single fast read version, good for debugging.
86+
// FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */,
87+
// RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */),
88+
// FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */,
89+
// READ_SDR, FLEXSPI_1PAD, 0x04),
90+
TWO_EMPTY_STEPS,
91+
TWO_EMPTY_STEPS),
92+
93+
// 1: ROM: Read status
94+
SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */,
95+
READ_SDR, FLEXSPI_1PAD, 0x02),
96+
TWO_EMPTY_STEPS,
97+
TWO_EMPTY_STEPS,
98+
TWO_EMPTY_STEPS),
99+
100+
// 2: Empty
101+
EMPTY_SEQUENCE,
102+
103+
// 3: ROM: Write Enable
104+
SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */,
105+
STOP, FLEXSPI_1PAD, 0x00),
106+
TWO_EMPTY_STEPS,
107+
TWO_EMPTY_STEPS,
108+
TWO_EMPTY_STEPS),
109+
110+
// 4: Config: Write Status -2
111+
SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */,
112+
WRITE_SDR, FLEXSPI_1PAD, 0x01 /* number of bytes to write */),
113+
TWO_EMPTY_STEPS,
114+
TWO_EMPTY_STEPS,
115+
TWO_EMPTY_STEPS),
116+
117+
// 5: ROM: Erase Sector
118+
SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */,
119+
RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */),
120+
TWO_EMPTY_STEPS,
121+
TWO_EMPTY_STEPS,
122+
TWO_EMPTY_STEPS),
123+
124+
// 6: Empty
125+
EMPTY_SEQUENCE,
126+
127+
// 7: Empty
128+
EMPTY_SEQUENCE,
129+
130+
// 8: Block Erase
131+
SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */,
132+
RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */),
133+
TWO_EMPTY_STEPS,
134+
TWO_EMPTY_STEPS,
135+
TWO_EMPTY_STEPS),
136+
137+
// 9: ROM: Page program
138+
SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */,
139+
RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */),
140+
141+
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */,
142+
STOP, FLEXSPI_1PAD, 0),
143+
TWO_EMPTY_STEPS,
144+
TWO_EMPTY_STEPS),
145+
146+
// 10: Empty
147+
EMPTY_SEQUENCE,
148+
149+
// 11: ROM: Chip erase
150+
SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */,
151+
STOP, FLEXSPI_1PAD, 0),
152+
TWO_EMPTY_STEPS,
153+
TWO_EMPTY_STEPS,
154+
TWO_EMPTY_STEPS),
155+
156+
// 12: Empty
157+
EMPTY_SEQUENCE,
158+
159+
// 13: ROM: Read SFDP
160+
EMPTY_SEQUENCE,
161+
162+
// 14: ROM: Restore no cmd
163+
EMPTY_SEQUENCE,
164+
165+
// 15: ROM: Dummy
166+
EMPTY_SEQUENCE
115167
},
116168
},
117-
.pageSize = 256u,
118-
.sectorSize = 4u * 1024u,
119-
.ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
120-
.blockSize = 0x00010000,
121-
.isUniformBlockSize = false,
122169
};

0 commit comments

Comments
 (0)