8000 stm32/sdram: Add SDRAM driver for stm32 · micropython/micropython@e8200b7 · GitHub
[go: up one dir, main page]

Skip to content

Commit e8200b7

Browse files
committed
stm32/sdram: Add SDRAM driver for stm32
Use SDRAM for micropython GC heap if enabled
1 parent 6244b29 commit e8200b7

File tree

4 files changed

+203
-79
lines changed

4 files changed

+203
-79
lines changed

ports/stm32/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ SRC_C = \
253253
spibdev.c \
254254
storage.c \
255255
sdcard.c \
256+
sdram.c \
256257
fatfs_port.c \
257258
lcd.c \
258259
accel.c \
@@ -305,10 +306,17 @@ ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7 l4))
305306
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
306307
hal_sd.c \
307308
ll_sdmmc.c \
309+
ll_fmc.c \
308310
ll_usb.c \
309311
)
310312
endif
311313

314+
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7))
315+
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
316+
hal_sdram.c \
317+
)
318+
endif
319+
312320
ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx))
313321
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_, hal_fdcan.c)
314322
else

ports/stm32/main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include "rtc.h"
5656
#include "storage.h"
5757
#include "sdcard.h"
58+
#include "sdram.h"
5859
#include "rng.h"
5960
#include "accel.h"
6061
#include "servo.h"
@@ -555,7 +556,16 @@ void stm32_main(uint32_t reset_mode) {
555556
mp_stack_set_limit((char*)&_estack - (char*)&_heap_end - 1024);
556557

557558
// GC init
559+
#if MICROPY_HW_SDRAM_SIZE
560+
sdram_init();
561+
#if MICROPY_HW_SDRAM_STARTUP_TEST
562+
sdram_test(true);
563+
#endif
564+
565+
gc_init(sdram_start(), sdram_end());
566+
#else
558567
gc_init(&_heap_start, &_heap_end);
568+
#endif
559569

560570
#if MICROPY_ENABLE_PYSTACK
561571
static mp_obj_t pystack[384];

ports/stm32/sdram.c

Lines changed: 182 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
*/
99
#include <stdio.h>
1010
#include <stdbool.h>
11-
#include <stm32f4xx_hal.h>
12-
#include "mdefs.h"
13-
#include "pincfg.h"
11+
#include <string.h>
12+
#include "py/runtime.h"
13+
#include "py/mphal.h"
14+
#include "pin.h"
15+
#include "pin_static_af.h"
1416
#include "systick.h"
1517
#include "sdram.h"
1618

17-
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
18-
#define REFRESH_COUNT ((uint32_t)0x0569) /* SDRAM refresh counter (90Mhz SD clock) */
19+
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
1920
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
2021
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
2122
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
@@ -28,43 +29,115 @@
2829
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
2930
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
3031

31-
static SDRAM_HandleTypeDef hsdram;
32-
static FMC_SDRAM_TimingTypeDef SDRAM_Timing;
33-
static FMC_SDRAM_CommandTypeDef command;
32+
#if defined(MICROPY_HW_FMC_SDCKE0) && defined(MICROPY_HW_FMC_SDNE0)
33+
#define FMC_SDRAM_BANK FMC_SDRAM_BANK1
34+
#define FMC_SDRAM_CMD_TARGET_BANK FMC_SDRAM_CMD_TARGET_BANK1
35+
#define SDRAM_START_ADDRESS 0xC0000000
36+
37+
#elif defined(MICROPY_HW_FMC_SDCKE1) && defined(MICROPY_HW_FMC_SDNE1)
38+
#define FMC_SDRAM_BANK FMC_SDRAM_BANK2
39+
#define FMC_SDRAM_CMD_TARGET_BANK FMC_SDRAM_CMD_TARGET_BANK2
40+
#define SDRAM_START_ADDRESS 0xD0000000
41+
#endif
42+
43+
#ifdef FMC_SDRAM_BANK
3444
static void sdram_init_seq(SDRAM_HandleTypeDef
3545
*hsdram, FMC_SDRAM_CommandTypeDef *command);
3646
extern void __fatal_error(const char *msg);
47+
#endif
3748

3849
bool sdram_init()
3950
{
51+
#ifndef FMC_SDRAM_BANK
52+
return false;
53+
#else
54+
55+
SDRAM_HandleTypeDef hsdram;
56+
FMC_SDRAM_TimingTypeDef SDRAM_Timing;
57+
FMC_SDRAM_CommandTypeDef command;
58+
59+
__HAL_RCC_FMC_CLK_ENABLE();
60+
61+
#if defined(MICROPY_HW_FMC_SDCKE0)
62+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDCKE0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_SDCKE0);
63+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDNE0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_SDNE0);
64+
65+
#elif defined(MICROPY_HW_FMC_SDCKE1)
66+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDCKE1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_SDCKE1);
67+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDNE1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_SDNE1);
68+
#endif
69+
70+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDCLK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_SDCLK);
71+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDNCAS, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_SDNCAS);
72+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDNRAS, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_SDNRAS);
73+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_SDNWE, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_SDNWE);
74+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_BA0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_BA0);
75+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_BA1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_BA1);
76+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_NBL0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_NBL0);
77+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_NBL1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_NBL1);
78+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A0);
79+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A1);
80+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A2);
81+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A3);
82+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A4, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A4);
83+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A5, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A5);
84+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A6, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A6);
85+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A7, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A7);
86+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A8, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A8);
87+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A9, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A9);
88+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A10, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A10);
89+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A11, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A11);
90+
#ifdef MICROPY_HW_FMC_A12
91+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_A12, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_A12);
92+
#endif
93+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D0);
94+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D1);
95+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D2);
96+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D3);
97+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D4, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D4);
98+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D5, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D5);
99+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D6, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D6);
100+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D7, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D7);
101+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D8, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D8);
102+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D9, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D9);
103+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D10, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D10);
104+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D11, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D11);
105+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D12, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D12);
106+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D13, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D13);
107+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D14, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D14);
108+
mp_hal_pin_config_alt_static(MICROPY_HW_FMC_D15, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_FMC_D15);
109+
40110
/* SDRAM device configuration */
41111
hsdram.Instance = FMC_SDRAM_DEVICE;
42112
/* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */
43113
/* TMRD: 2 Clock cycles */
44-
SDRAM_Timing.LoadToActiveDelay = 2;
114+
SDRAM_Timing.LoadToActiveDelay = MICROPY_HW_SDRAM_TIMING_TMRD;
45115
/* TXSR: min=70ns (6x11.90ns) */
46-
SDRAM_Timing.ExitSelfRefreshDelay = 7;
47-
/* TRAS: min=45ns (4x11.90ns) max=120k (ns) */
48-
SDRAM_Timing.SelfRefreshTime = 7;
49-
/* TRC: min=67ns (6x11.90ns) */
50-
SDRAM_Timing.RowCycleDelay = 10;
51-
/* TWR: 2 Clock cycles */
52-
SDRAM_Timing.WriteRecoveryTime = 2;
53-
/* TRP: 20ns => 2x11.90ns */
54-
SDRAM_Timing.RPDelay = 3;
55-
/* TRCD: 20ns => 2x11.90ns */
56-
SDRAM_Timing.RCDDelay = 3;
57-
58-
hsdram.Init.SDBank = FMC_SDRAM_BANK1;
59-
hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
60-
hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_10;
61-
hsdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_8;
62-
hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
63-
hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
64-
hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
65-
hsdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;
66-
hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
67-
hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
116+
SDRAM_Timing.ExitSelfRefreshDelay = MICROPY_HW_SDRAM_TIMING_TXSR;
117+
/* TRAS */
118+
SDRAM_Timing.SelfRefreshTime = MICROPY_HW_SDRAM_TIMING_TRAS;
119+
/* TRC */
120+
SDRAM_Timing.RowCycleDelay = MICROPY_HW_SDRAM_TIMING_TRC;
121+
/* TWR */
122+
SDRAM_Timing.WriteRecoveryTime = MICROPY_HW_SDRAM_TIMING_TWR;
123+
/* TRP */
124+
SDRAM_Timing.RPDelay = MICROPY_HW_SDRAM_TIMING_TRP;
125+
/* TRCD */
126+
SDRAM_Timing.RCDDelay = MICROPY_HW_SDRAM_TIMING_TRCD;
127+
128+
#define _FMC_INIT(x, n) x ## _ ## n
129+
#define FMC_INIT(x, n) _FMC_INIT(x, n)
130+
131+
hsdram.Init.SDBank = FMC_SDRAM_BANK;
132+
hsdram.Init.ColumnBitsNumber = FMC_INIT(FMC_SDRAM_COLUMN_BITS_NUM, MICROPY_HW_SDRAM_COLUMN_BITS_NUM);
133+
hsdram.Init.RowBitsNumber = FMC_INIT(FMC_SDRAM_ROW_BITS_NUM, MICROPY_HW_SDRAM_ROW_BITS_NUM);
134+
hsdram.Init.MemoryDataWidth = FMC_INIT(FMC_SDRAM_MEM_BUS_WIDTH, MICROPY_HW_SDRAM_MEM_BUS_WIDTH);
135+
hsdram.Init.InternalBankNumber = FMC_INIT(FMC_SDRAM_INTERN_BANKS_NUM, MICROPY_HW_SDRAM_INTERN_BANKS_NUM);
136+
hsdram.Init.CASLatency = FMC_INIT(FMC_SDRAM_CAS_LATENCY, MICROPY_HW_SDRAM_CAS_LATENCY);
137+
hsdram.Init.SDClockPeriod = FMC_INIT(FMC_SDRAM_CLOCK_PERIOD, MICROPY_HW_SDRAM_CLOCK_PERIOD);
138+
hsdram.Init.ReadPipeDelay = FMC_INIT(FMC_SDRAM_RPIPE_DELAY, MICROPY_HW_SDRAM_RPIPE_DELAY);
139+
hsdram.Init.ReadBurst = (MICROPY_HW_SDRAM_RBURST) ? FMC_SDRAM_RBURST_ENABLE : FMC_SDRAM_RBURST_DISABLE;
140+
hsdram.Init.WriteProtection = (MICROPY_HW_SDRAM_WRITE_PROTECTION) ? FMC_SDRAM_WRITE_PROTECTION_ENABLE : FMC_SDRAM_WRITE_PROTECTION_DISABLE;
68141

69142
/* Initialize the SDRAM controller */
70143
if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK) {
@@ -73,8 +146,27 @@ bool sdram_init()
73146

74147
sdram_init_seq(&hsdram, &command);
75148
return true;
149+
150+
#endif
76151
}
77152

153+
void * sdram_start() {
154+
#ifdef FMC_SDRAM_BANK
155+
return (void *)SDRAM_START_ADDRESS;
156+
#else
157+
return NULL;
158+
#endif
159+
}
160+
161+
void * sdram_end() {
162+
#ifdef FMC_SDRAM_BANK
163+
return (void *)(SDRAM_START_ADDRESS + MICROPY_HW_SDRAM_SIZE);
164+
#else
165+
return NULL;
166+
#endif
167+
}
168+
169+
#ifdef FMC_SDRAM_BANK
78170
static void sdram_init_seq(SDRAM_HandleTypeDef
79171
*hsdram, FMC_SDRAM_CommandTypeDef *command)
80172
{
@@ -83,7 +175,7 @@ static void sdram_init_seq(SDRAM_HandleTypeDef
83175

84176
/* Step 3: Configure a clock configuration enable command */
85177
command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
86-
command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
178+
command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK;
87179
command->AutoRefreshNumber = 1;
88180
command->ModeRegisterDefinition = 0;
89181

@@ -95,7 +187,7 @@ static void sdram_init_seq(SDRAM_HandleTypeDef
95187

96188
/* Step 5: Configure a PALL (precharge all) command */
97189
command->CommandMode = FMC_SDRAM_CMD_PALL;
98-
command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
190+
command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK;
99191
command->AutoRefreshNumber = 1;
100192
command->ModeRegisterDefinition = 0;
101193

@@ -104,7 +196,7 @@ static void sdram_init_seq(SDRAM_HandleTypeDef
104196

105197
/* Step 6 : Configure a Auto-Refresh command */
106198
command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
107-
command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
199+
command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK;
108200
command->AutoRefreshNumber = 4;
109201
command->ModeRegisterDefinition = 0;
110202

@@ -114,70 +206,82 @@ static void sdram_init_seq(SDRAM_HandleTypeDef
114206
/* Step 7: Program the external memory mode register */
115207
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
116208
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
117-
SDRAM_MODEREG_CAS_LATENCY_3 |
209+
FMC_INIT(SDRAM_MODEREG_CAS_LATENCY, MICROPY_HW_SDRAM_CAS_LATENCY) |
118210
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
119211
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
120212

121213
command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
122-
command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
214+
command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK;
123215
command->AutoRefreshNumber = 1;
124216
command->ModeRegisterDefinition = tmpmrd;
125217

126218
/* Send the command */
127219
HAL_SDRAM_SendCommand(hsdram, command, 0x1000);
128220

129-
/* Step 8: Set the refresh rate counter */
130-
/* (15.62 us x Freq) - 20 */
131-
/* Set the device refresh counter */
221+
/* Step 8: Set the refresh rate counter
222+
RefreshRate = 64 ms / 8192 cyc = 7.8125 us/cyc
223+
224+
RefreshCycles = 7.8125 us * 90 MHz = 703
225+
According to the formula on p.1665 of the reference manual,
226+
we also need to subtract 20 from the value, so the target
227+
refresh rate is 703 - 20 = 683.
228+
*/
229+
#define REFRESH_COUNT (MICROPY_HW_SDRAM_REFRESH_RATE*90000/8192-20)
132230
HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);
133231
}
232+
#endif //FMC_SDRAM_BANK
134233

135-
136-
bool DISABLE_OPT sdram_test()
234+
bool __attribute__((optimize("O0"))) sdram_test(bool fast)
137235
{
138-
uint8_t pattern = 0xAA;
139-
uint8_t antipattern = 0x55;
140-
uint32_t mem_size = (16*1024*1024);
141-
uint8_t * const mem_base = (uint8_t*)0xC0000000;
142-
143-
printf("sdram test...\n");
144-
/* test data bus */
145-
for (uint8_t i=1; i; i<<=1) {
146-
*mem_base = i;
147-
if (*mem_base != i) {
148-
printf("data bus lines test failed! data (%d)\n", i);
149-
BREAK();
236+
#ifndef FMC_SDRAM_BANK
237+
return false;
238+
#else
239+
240+
uint8_t const pattern = 0xAA;
241+
uint8_t const antipattern = 0x55;
242+
uint8_t * const mem_base = (uint8_t*)sdram_start();
243+
244+
/* test data bus */
245+
for (uint8_t i=1; i; i<<=1) {
246+
*mem_base = i;
247+
if (*mem_base != i) {
248+
printf("data bus lines test failed! data (%d)\n", i);
249+
__asm__ volatile ("BKPT");
250+
}
150251
}
151-
}
152252

153-
/* test address bus */
154-
/* Check individual address lines */
155-
for (uint32_t i=1; i<mem_size; i<<=1) {
156-
mem_base[i] = pattern;
157-
if (mem_base[i] != pattern) {
158-
printf("address bus lines test failed! address (%p)\n", &mem_base[i]);
159-
BREAK();
253+
/* test address bus */
254+
/* Check individual address lines */
255+
for (uint32_t i=1; i<MICROPY_HW_SDRAM_SIZE; i<<=1) {
256+
mem_base[i] = pattern;
257+
if (mem_base[i] != pattern) {
258+
printf("address bus lines test failed! address (%p)\n", &mem_base[i]);
259+
__asm__ volatile ("BKPT");
260+
}
160261
}
161-
}
162262

163-
/* Check for aliasing (overlaping addresses) */
164-
mem_base[0] = antipattern;
165-
for (uint32_t i=1; i<mem_size; i<<=1) {
166-
if (mem_base[i] != pattern) {
167-
printf("address bus overlap %p\n", &mem_base[i]);
168-
BREAK();
263+
/* Check for aliasing (overlaping addresses) */
264+
mem_base[0] = antipattern;
265+
for (uint32_t i=1; i<MICROPY_HW_SDRAM_SIZE; i<<=1) {
266+
if (mem_base[i] != pattern) {
267+
printf("address bus overlap %p\n", &mem_base[i]);
268+
__asm__ volatile ("BKPT");
269+
}
169270
}
170-
}
171271

172-
/* test all ram cells */
173-
for (uint32_t i=0; i<mem_size; i++) {
174-
mem_base[i] = pattern;
175-
if (mem_base[i] != pattern) {
176-
printf("address bus test failed! address (%p)\n", &mem_base[i]);
177-
BREAK();
272+
/* test all ram cells */
273+
if (!fast) {
274+
for (uint32_t i=0; i<MICROPY_HW_SDRAM_SIZE; i++) {
275+
mem_base[i] = pattern;
276+
if (mem_base[i] != pattern) {
277+
printf("address bus test failed! address (%p)\n", &mem_base[i]);
278+
__asm__ volatile ("BKPT");
279+
}
280+
}
281+
} else {
282+
memset(mem_base, pattern, MICROPY_HW_SDRAM_SIZE);
178283
}
179-
}
180284

181-
printf("sdram test passed\n");
182-
return true;
285+
return true;
286+
#endif
183287
}

0 commit comments

Comments
 (0)
0