Skip to content

Commit 402b90a

Browse files
committed
mimxrt: Add initial PSRAM implementation.
Signed-off-by: Dryw Wade <dryw.wade@sparkfun.com>
1 parent cfea71d commit 402b90a

File tree

5 files changed

+321
-1
lines changed

5 files changed

+321
-1
lines changed

ports/mimxrt/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ SRC_C += \
265265
network_lan.c \
266266
pendsv.c \
267267
pin.c \
268+
psram.c \
268269
sdcard.c \
269270
sdio.c \
270271
systick.c \

ports/mimxrt/main.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "ticks.h"
3838
#include "led.h"
3939
#include "pendsv.h"
40+
#include "psram.h"
4041
#include "modmachine.h"
4142
#include "modmimxrt.h"
4243

@@ -67,6 +68,10 @@ int main(void) {
6768
ticks_init();
6869
pendsv_init();
6970

71+
#if MICROPY_HW_ENABLE_PSRAM
72+
size_t psram_size = configure_external_ram();
73+
#endif
74+
7075
#if MICROPY_PY_LWIP
7176
// lwIP doesn't allow to reinitialise itself by subsequent calls to this function
7277
// because the system timeout list (next_timeout) is only ever reset by BSS clearing.
@@ -101,7 +106,20 @@ int main(void) {
101106

102107
mp_cstack_init_with_top(&_estack, &_estack - &_sstack);
103108

109+
#if MICROPY_HW_ENABLE_PSRAM
110+
if(psram_size) {
111+
#if MICROPY_GC_SPLIT_HEAP
112+
gc_init(&_gc_heap_start, &_gc_heap_end);
113+
gc_add((void *)PSRAM_BASE, (void *)(PSRAM_BASE + psram_size));
114+
#else
115+
gc_init((void *)PSRAM_BASE, (void *)(PSRAM_BASE + psram_size));
116+
#endif
117+
} else {
118+
gc_init(&_gc_heap_start, &_gc_heap_end);
119+
}
120+
#else
104121
gc_init(&_gc_heap_start, &_gc_heap_end);
122+
#endif
105123
mp_init();
106124

107125
#if MICROPY_PY_NETWORK

ports/mimxrt/mpconfigport.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,20 @@ uint32_t trng_random_u32(void);
3535
// Config level
3636
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_FULL_FEATURES)
3737

38+
#ifndef MICROPY_HW_ENABLE_PSRAM
39+
#define MICROPY_HW_ENABLE_PSRAM (0)
40+
#endif
41+
3842
// Memory allocation policies
39-
#if MICROPY_HW_SDRAM_AVAIL
43+
#if MICROPY_HW_SDRAM_AVAIL || MICROPY_HW_ENABLE_PSRAM
4044
#define MICROPY_GC_STACK_ENTRY_TYPE uint32_t
4145
#else
4246
#define MICROPY_GC_STACK_ENTRY_TYPE uint16_t
4347
#endif
4448
#define MICROPY_ALLOC_PATH_MAX (256)
49+
#ifndef MICROPY_GC_SPLIT_HEAP
50+
#define MICROPY_GC_SPLIT_HEAP MICROPY_HW_ENABLE_PSRAM
51+
#endif
4552

4653
// MicroPython emitters
4754
#define MICROPY_PERSISTENT_CODE_LOAD (1)

ports/mimxrt/psram.c

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2025 Paul Stoffregen
7+
* Dryw Wade
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include "py/mphal.h"
29+
30+
#if MICROPY_HW_ENABLE_PSRAM
31+
32+
// Copied from here:
33+
// https://github.com/PaulStoffregen/cores/blob/a23cade55c7530cce43c641ec3ddb8b7f83148a8/teensy4/avr/pgmspace.h#L31
34+
#define FLASHMEM __attribute__((section(".flashmem")))
35+
36+
// These #defines are from here:
37+
// https://github.com/PaulStoffregen/cores/blob/a23cade55c7530cce43c641ec3ddb8b7f83148a8/teensy4/imxrt.h
38+
#define CCM_CCGR_ON 3
39+
#define FLEXSPI_MCR2_CLRLEARNPHASE(x) ((uint32_t)(x<<14))
40+
#define FLEXSPI_LUTKEY_VALUE ((uint32_t)0x5AF05AF0)
41+
#define FLEXSPI_LUT_INSTRUCTION(opcode, pads, operand) ((uint32_t)(\
42+
(((opcode) & 0x3F) << 10) | (((pads) & 0x03) << 8) | ((operand) & 0xFF)))
43+
#define FLEXSPI_LUT_OPCODE_CMD_SDR 0x01
44+
#define FLEXSPI_LUT_OPCODE_RADDR_SDR 0x02
45+
#define FLEXSPI_LUT_OPCODE_WRITE_SDR 0x08
46+
#define FLEXSPI_LUT_OPCODE_READ_SDR 0x09
47+
#define FLEXSPI_LUT_OPCODE_DUMMY_SDR 0x0C
48+
#define FLEXSPI_LUT_NUM_PADS_1 0x00
49+
#define FLEXSPI_LUT_NUM_PADS_4 0x02
50+
51+
// The rest of the implementation is adapted from here:
52+
// https://github.com/PaulStoffregen/cores/blob/a23cade55c7530cce43c641ec3ddb8b7f83148a8/teensy4/startup.c#L379-L587
53+
// Modified to use #define's from:
54+
// `lib/nxp_driver/sdk/devices/MIMXRT1062/MIMXRT1062.h`
55+
#define LUT0(opcode, pads, operand) (FLEXSPI_LUT_INSTRUCTION((opcode), (pads), (operand)))
56+
#define LUT1(opcode, pads, operand) (FLEXSPI_LUT_INSTRUCTION((opcode), (pads), (operand)) << 16)
57+
#define CMD_SDR FLEXSPI_LUT_OPCODE_CMD_SDR
58+
#define ADDR_SDR FLEXSPI_LUT_OPCODE_RADDR_SDR
59+
#define READ_SDR FLEXSPI_LUT_OPCODE_READ_SDR
60+
#define WRITE_SDR FLEXSPI_LUT_OPCODE_WRITE_SDR
61+
#define DUMMY_SDR FLEXSPI_LUT_OPCODE_DUMMY_SDR
62+
#define PINS1 FLEXSPI_LUT_NUM_PADS_1
63+
#define PINS4 FLEXSPI_LUT_NUM_PADS_4
64+
65+
FLASHMEM static void flexspi2_command(uint32_t index, uint32_t addr)
66+
{
67+
FLEXSPI2->IPCR0 = addr;
68+
FLEXSPI2->IPCR1 = FLEXSPI_IPCR1_ISEQID(index);
69+
FLEXSPI2->IPCMD = FLEXSPI_IPCMD_TRG(1);
70+
while (!(FLEXSPI2->INTR & FLEXSPI_INTR_IPCMDDONE(1))); // wait
71+
FLEXSPI2->INTR = FLEXSPI_INTR_IPCMDDONE(1);
72+
}
73+
74+
FLASHMEM static uint32_t flexspi2_psram_id(uint32_t addr)
75+
{
76+
FLEXSPI2->IPCR0 = addr;
77+
FLEXSPI2->IPCR1 = FLEXSPI_IPCR1_ISEQID(3) | FLEXSPI_IPCR1_IDATSZ(4);
78+
FLEXSPI2->IPCMD = FLEXSPI_IPCMD_TRG(1);
79+
while (!(FLEXSPI2->INTR & FLEXSPI_INTR_IPCMDDONE(1))); // wait
80+
uint32_t id = FLEXSPI2->RFDR[0];
81+
FLEXSPI2->INTR = FLEXSPI_INTR_IPCMDDONE(1) | FLEXSPI_INTR_IPRXWA(1);
82+
return id;
83+
}
84+
85+
/**
86+
* \return size of PSRAM in MBytes, or 0 if not present
87+
*/
88+
FLASHMEM static uint8_t flexspi2_psram_size(uint32_t addr)
89+
{
90+
uint8_t result = 0; // assume we don't have PSRAM at this address
91+
flexspi2_command(0, addr); // exit quad mode
92+
flexspi2_command(1, addr); // reset enable
93+
flexspi2_command(2, addr); // reset (is this really necessary?)
94+
uint32_t id = flexspi2_psram_id(addr);
95+
96+
switch (id & 0xFFFF)
97+
{
98+
default:
99+
break;
100+
101+
case 0x5D0D: // AP / Ipus / ESP / Lyontek
102+
result = 8;
103+
break;
104+
105+
case 0x5D9D: // ISSI
106+
switch ((id >> 21) & 0x7) // get size (Datasheet Table 6.2)
107+
{
108+
case 0b011:
109+
result = 8;
110+
break;
111+
case 0b100:
112+
result = 16;
113+
break;
114+
}
115+
break;
116+
}
117+
118+
return result;
119+
}
120+
121+
FLASHMEM size_t configure_external_ram()
122+
{
123+
// initialize pins
124+
IOMUXC->SW_PAD_CTL_PAD[22] = 0x1B0F9; // 100K pullup, strong drive, max speed, hyst
125+
IOMUXC->SW_PAD_CTL_PAD[23] = 0x110F9; // keeper, strong drive, max speed, hyst
126+
IOMUXC->SW_PAD_CTL_PAD[24] = 0x1B0F9; // 100K pullup, strong drive, max speed, hyst
127+
IOMUXC->SW_PAD_CTL_PAD[25] = 0x100F9; // strong drive, max speed, hyst
128+
IOMUXC->SW_PAD_CTL_PAD[26] = 0x170F9; // 47K pullup, strong drive, max speed, hyst
129+
IOMUXC->SW_PAD_CTL_PAD[27] = 0x170F9; // 47K pullup, strong drive, max speed, hyst
130+
IOMUXC->SW_PAD_CTL_PAD[28] = 0x170F9; // 47K pullup, strong drive, max speed, hyst
131+
IOMUXC->SW_PAD_CTL_PAD[29] = 0x170F9; // 47K pullup, strong drive, max speed, hyst
132+
133+
IOMUXC->SW_MUX_CTL_PAD[22] = 8 | 0x10; // ALT1 = FLEXSPI2_A_SS1_B (Flash)
134+
IOMUXC->SW_MUX_CTL_PAD[23] = 8 | 0x10; // ALT1 = FLEXSPI2_A_DQS
135+
IOMUXC->SW_MUX_CTL_PAD[24] = 8 | 0x10; // ALT1 = FLEXSPI2_A_SS0_B (RAM)
136+
IOMUXC->SW_MUX_CTL_PAD[25] = 8 | 0x10; // ALT1 = FLEXSPI2_A_SCLK
137+
IOMUXC->SW_MUX_CTL_PAD[26] = 8 | 0x10; // ALT1 = FLEXSPI2_A_DATA0
138+
IOMUXC->SW_MUX_CTL_PAD[27] = 8 | 0x10; // ALT1 = FLEXSPI2_A_DATA1
139+
IOMUXC->SW_MUX_CTL_PAD[28] = 8 | 0x10; // ALT1 = FLEXSPI2_A_DATA2
140+
IOMUXC->SW_MUX_CTL_PAD[29] = 8 | 0x10; // ALT1 = FLEXSPI2_A_DATA3
141+
142+
IOMUXC->SELECT_INPUT_1[kIOMUXC_FLEXSPI2_IPP_IND_DQS_FA_SELECT_INPUT] = 1; // GPIO_EMC_23 for Mode: ALT8, pg 986
143+
IOMUXC->SELECT_INPUT_1[kIOMUXC_FLEXSPI2_IPP_IND_IO_FA_BIT0_SELECT_INPUT] = 1; // GPIO_EMC_26 for Mode: ALT8
144+
IOMUXC->SELECT_INPUT_1[kIOMUXC_FLEXSPI2_IPP_IND_IO_FA_BIT1_SELECT_INPUT] = 1; // GPIO_EMC_27 for Mode: ALT8
145+
IOMUXC->SELECT_INPUT_1[kIOMUXC_FLEXSPI2_IPP_IND_IO_FA_BIT2_SELECT_INPUT] = 1; // GPIO_EMC_28 for Mode: ALT8
146+
IOMUXC->SELECT_INPUT_1[kIOMUXC_FLEXSPI2_IPP_IND_IO_FA_BIT3_SELECT_INPUT] = 1; // GPIO_EMC_29 for Mode: ALT8
147+
IOMUXC->SELECT_INPUT_1[kIOMUXC_FLEXSPI2_IPP_IND_SCK_FA_SELECT_INPUT] = 1; // GPIO_EMC_25 for Mode: ALT8
148+
149+
// turn on clock (QSPI flash & PSRAM chips usually spec max clock 100 to 133 MHz)
150+
CCM->CBCMR = (CCM->CBCMR & ~(CCM_CBCMR_FLEXSPI2_PODF_MASK | CCM_CBCMR_FLEXSPI2_CLK_SEL_MASK))
151+
//| CCM_CBCMR_FLEXSPI2_PODF(5) | CCM_CBCMR_FLEXSPI2_CLK_SEL(3); // 88.0 MHz
152+
//| CCM_CBCMR_FLEXSPI2_PODF(3) | CCM_CBCMR_FLEXSPI2_CLK_SEL(0); // 99.0 MHz
153+
//| CCM_CBCMR_FLEXSPI2_PODF(6) | CCM_CBCMR_FLEXSPI2_CLK_SEL(1); // 102.9 MHz
154+
| CCM_CBCMR_FLEXSPI2_PODF(4) | CCM_CBCMR_FLEXSPI2_CLK_SEL(3); // 105.6 MHz
155+
//| CCM_CBCMR_FLEXSPI2_PODF(5) | CCM_CBCMR_FLEXSPI2_CLK_SEL(2); // 110.8 MHz
156+
//| CCM_CBCMR_FLEXSPI2_PODF(5) | CCM_CBCMR_FLEXSPI2_CLK_SEL(1); // 120.0 MHz
157+
//| CCM_CBCMR_FLEXSPI2_PODF(3) | CCM_CBCMR_FLEXSPI2_CLK_SEL(3); // 132.0 MHz
158+
//| CCM_CBCMR_FLEXSPI2_PODF(4) | CCM_CBCMR_FLEXSPI2_CLK_SEL(1); // 144.0 MHz
159+
//| CCM_CBCMR_FLEXSPI2_PODF(3) | CCM_CBCMR_FLEXSPI2_CLK_SEL(2); // 166.2 MHz
160+
//| CCM_CBCMR_FLEXSPI2_PODF(2) | CCM_CBCMR_FLEXSPI2_CLK_SEL(3); // 176.0 MHz
161+
CCM->CCGR7 |= CCM_CCGR7_CG1(CCM_CCGR_ON);
162+
163+
FLEXSPI2->MCR0 |= FLEXSPI_MCR0_MDIS(1);
164+
FLEXSPI2->MCR0 = (FLEXSPI2->MCR0 & ~(FLEXSPI_MCR0_AHBGRANTWAIT_MASK
165+
| FLEXSPI_MCR0_IPGRANTWAIT_MASK | FLEXSPI_MCR0_SCKFREERUNEN(1)
166+
| FLEXSPI_MCR0_COMBINATIONEN(1) | FLEXSPI_MCR0_DOZEEN(1)
167+
| FLEXSPI_MCR0_HSEN(1) | FLEXSPI_MCR0_ATDFEN(1) | FLEXSPI_MCR0_ARDFEN(1)
168+
| FLEXSPI_MCR0_RXCLKSRC_MASK | FLEXSPI_MCR0_SWRESET(1)))
169+
| FLEXSPI_MCR0_AHBGRANTWAIT(0xFF) | FLEXSPI_MCR0_IPGRANTWAIT(0xFF)
170+
| FLEXSPI_MCR0_RXCLKSRC(1) | FLEXSPI_MCR0_MDIS(1);
171+
FLEXSPI2->MCR1 = FLEXSPI_MCR1_SEQWAIT(0xFFFF) | FLEXSPI_MCR1_AHBBUSWAIT(0xFFFF);
172+
FLEXSPI2->MCR2 = (FLEXSPI->MCR2 & ~(FLEXSPI_MCR2_RESUMEWAIT_MASK
173+
| FLEXSPI_MCR2_SCKBDIFFOPT(1) | FLEXSPI_MCR2_SAMEDEVICEEN(1)
174+
| FLEXSPI_MCR2_CLRLEARNPHASE(1) | FLEXSPI_MCR2_CLRAHBBUFOPT(1)))
175+
| FLEXSPI_MCR2_RESUMEWAIT(0x20) /*| FLEXSPI_MCR2_SAMEDEVICEEN*/;
176+
177+
FLEXSPI2->AHBCR = FLEXSPI2->AHBCR & ~(FLEXSPI_AHBCR_READADDROPT(1) | FLEXSPI_AHBCR_PREFETCHEN(1)
178+
| FLEXSPI_AHBCR_BUFFERABLEEN(1) | FLEXSPI_AHBCR_CACHABLEEN(1));
179+
uint32_t mask = (FLEXSPI_AHBRXBUFCR0_PREFETCHEN(1) | FLEXSPI_AHBRXBUFCR0_PRIORITY_MASK
180+
| FLEXSPI_AHBRXBUFCR0_MSTRID_MASK | FLEXSPI_AHBRXBUFCR0_BUFSZ_MASK);
181+
FLEXSPI2->AHBRXBUFCR0[0] = (FLEXSPI2->AHBRXBUFCR0[0] & ~mask)
182+
| FLEXSPI_AHBRXBUFCR0_PREFETCHEN(1) | FLEXSPI_AHBRXBUFCR0_BUFSZ(64);
183+
FLEXSPI2->AHBRXBUFCR0[1] = (FLEXSPI2->AHBRXBUFCR0[0] & ~mask)
184+
| FLEXSPI_AHBRXBUFCR0_PREFETCHEN(1) | FLEXSPI_AHBRXBUFCR0_BUFSZ(64);
185+
FLEXSPI2->AHBRXBUFCR0[2] = mask;
186+
FLEXSPI2->AHBRXBUFCR0[3] = mask;
187+
188+
// RX watermark = one 64 bit line
189+
FLEXSPI2->IPRXFCR = (FLEXSPI->IPRXFCR & 0xFFFFFFC0) | FLEXSPI_IPRXFCR_CLRIPRXF(1);
190+
// TX watermark = one 64 bit line
191+
FLEXSPI2->IPTXFCR = (FLEXSPI->IPTXFCR & 0xFFFFFFC0) | FLEXSPI_IPTXFCR_CLRIPTXF(1);
192+
193+
FLEXSPI2->INTEN = 0;
194+
FLEXSPI2->FLSHCR1[0] = FLEXSPI_FLSHCR1_CSINTERVAL(0)
195+
| FLEXSPI_FLSHCR1_TCSH(1) | FLEXSPI_FLSHCR1_TCSS(1);
196+
FLEXSPI2->FLSHCR2[0] = FLEXSPI_FLSHCR2_AWRSEQID(6) | FLEXSPI_FLSHCR2_AWRSEQNUM(0)
197+
| FLEXSPI_FLSHCR2_ARDSEQID(5) | FLEXSPI_FLSHCR2_ARDSEQNUM(0);
198+
199+
FLEXSPI2->FLSHCR1[1] = FLEXSPI_FLSHCR1_CSINTERVAL(0)
200+
| FLEXSPI_FLSHCR1_TCSH(1) | FLEXSPI_FLSHCR1_TCSS(1);
201+
FLEXSPI2->FLSHCR2[1] = FLEXSPI_FLSHCR2_AWRSEQID(6) | FLEXSPI_FLSHCR2_AWRSEQNUM(0)
202+
| FLEXSPI_FLSHCR2_ARDSEQID(5) | FLEXSPI_FLSHCR2_ARDSEQNUM(0);
203+
204+
FLEXSPI2->MCR0 &= ~FLEXSPI_MCR0_MDIS(1);
205+
206+
FLEXSPI2->LUTKEY = FLEXSPI_LUTKEY_VALUE;
207+
FLEXSPI2->LUTCR = FLEXSPI_LUTCR_UNLOCK(1);
208+
volatile uint32_t *luttable = &FLEXSPI2->LUT[0];
209+
for (int i=0; i < 64; i++) luttable[i] = 0;
210+
FLEXSPI2->MCR0 |= FLEXSPI_MCR0_SWRESET(1);
211+
while (FLEXSPI2->MCR0 & FLEXSPI_MCR0_SWRESET(1)) ; // wait
212+
213+
FLEXSPI2->LUTKEY = FLEXSPI_LUTKEY_VALUE;
214+
FLEXSPI2->LUTCR = FLEXSPI_LUTCR_UNLOCK(1);
215+
216+
// cmd index 0 = exit QPI mode
217+
FLEXSPI2->LUT[0] = LUT0(CMD_SDR, PINS4, 0xF5);
218+
// cmd index 1 = reset enable
219+
FLEXSPI2->LUT[4] = LUT0(CMD_SDR, PINS1, 0x66);
220+
// cmd index 2 = reset
221+
FLEXSPI2->LUT[8] = LUT0(CMD_SDR, PINS1, 0x99);
222+
// cmd index 3 = read ID bytes
223+
FLEXSPI2->LUT[12] = LUT0(CMD_SDR, PINS1, 0x9F) | LUT1(DUMMY_SDR, PINS1, 24);
224+
FLEXSPI2->LUT[13] = LUT0(READ_SDR, PINS1, 1);
225+
// cmd index 4 = enter QPI mode
226+
FLEXSPI2->LUT[16] = LUT0(CMD_SDR, PINS1, 0x35);
227+
// cmd index 5 = read QPI
228+
FLEXSPI2->LUT[20] = LUT0(CMD_SDR, PINS4, 0xEB) | LUT1(ADDR_SDR, PINS4, 24);
229+
FLEXSPI2->LUT[21] = LUT0(DUMMY_SDR, PINS4, 6) | LUT1(READ_SDR, PINS4, 1);
230+
// cmd index 6 = write QPI
231+
FLEXSPI2->LUT[24] = LUT0(CMD_SDR, PINS4, 0x38) | LUT1(ADDR_SDR, PINS4, 24);
232+
FLEXSPI2->LUT[25] = LUT0(WRITE_SDR, PINS4, 1);
233+
234+
// Detected PSRAM size in MB
235+
uint8_t external_psram_size = 0;
236+
237+
// look for the first PSRAM chip
238+
uint8_t size1 = flexspi2_psram_size(0);
239+
if (size1 > 0) {
240+
FLEXSPI2->FLSHCR0[0] = size1 << 10;
241+
flexspi2_command(4, 0); // enter QPI mode
242+
// look for a second PSRAM chip
243+
uint8_t size2 = flexspi2_psram_size(size1 << 20);
244+
external_psram_size = size1 + size2;
245+
if (size2 > 0) {
246+
FLEXSPI2->FLSHCR0[1] = size2 << 10;
247+
flexspi2_command(4, size1 << 20); // enter QPI mode
248+
}
249+
} else {
250+
// No PSRAM
251+
external_psram_size = 0;
252+
}
253+
254+
// Return the size of the PSRAM in bytes
255+
return external_psram_size * 0x100000;
256+
}
257+
258+
#endif

ports/mimxrt/psram.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2025 Paul Stoffregen
7+
* Dryw Wade
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#ifndef MICROPY_INCLUDED_MIMXRT_PSRAM_H
29+
#define MICROPY_INCLUDED_MIMXRT_PSRAM_H
30+
31+
#define PSRAM_BASE (0x70000000)
32+
33+
// Configures external PSRAM if available, returns size in bytes (0 if none).
34+
size_t configure_external_ram();
35+
36+
#endif // MICROPY_INCLUDED_MIMXRT_PSRAM_H

0 commit comments

Comments
 (0)