Skip to content

Commit 7649f5f

Browse files
iabdalkaderdpgeorge
authored andcommitted
stm32/sdram: Make SDRAM test cache aware, and optional failure with msg.
* Make SDRAM test cache-aware for newer MCUs. * Use the defined data bus width (instead of the fixed 8-bits). * Allow optional failure on error with verbose error messages. * Test speed is now inverted (test accepts exhaustive instead fast).
1 parent 6214fa3 commit 7649f5f

File tree

3 files changed

+73
-19
lines changed

3 files changed

+73
-19
lines changed

ports/stm32/main.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ void stm32_main(uint32_t reset_mode) {
404404
bool sdram_valid = true;
405405
UNUSED(sdram_valid);
406406
#if MICROPY_HW_SDRAM_STARTUP_TEST
407-
sdram_valid = sdram_test(true);
407+
sdram_valid = sdram_test(false);
408408
#endif
409409
#endif
410410
#if MICROPY_PY_THREAD

ports/stm32/sdram.c

+71-17
Original file line numberDiff line numberDiff line change
@@ -283,52 +283,106 @@ void sdram_leave_low_power(void) {
283283
#pragma GCC diagnostic ignored "-Wstringop-overflow"
284284
#endif
285285

286-
bool sdram_test(bool fast) {
286+
bool __attribute__((optimize("O0"))) sdram_test(bool exhaustive) {
287287
uint8_t const pattern = 0xaa;
288288
uint8_t const antipattern = 0x55;
289289
uint8_t *const mem_base = (uint8_t *)sdram_start();
290290

291-
/* test data bus */
292-
for (uint8_t i = 1; i; i <<= 1) {
293-
*mem_base = i;
294-
if (*mem_base != i) {
295-
printf("data bus lines test failed! data (%d)\n", i);
291+
#if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
292+
char error_buffer[1024];
293+
#endif
294+
295+
#if (__DCACHE_PRESENT == 1)
296+
bool i_cache_disabled = false;
297+
bool d_cache_disabled = false;
298+
299+
// Disable caches for testing.
300+
if (SCB->CCR & (uint32_t)SCB_CCR_IC_Msk) {
301+
SCB_DisableICache();
302+
i_cache_disabled = true;
303+
}
304+
305+
if (SCB->CCR & (uint32_t)SCB_CCR_DC_Msk) {
306+
SCB_DisableDCache();
307+
d_cache_disabled = true;
308+
}
309+
#endif
310+
311+
// Test data bus
312+
for (uint32_t i = 0; i < MICROPY_HW_SDRAM_MEM_BUS_WIDTH; i++) {
313+
*((uint32_t *)mem_base) = (1 << i);
314+
if (*((uint32_t *)mem_base) != (1 << i)) {
315+
#if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
316+
snprintf(error_buffer, sizeof(error_buffer),
317+
"Data bus test failed at 0x%p expected 0x%x found 0x%lx",
318+
&mem_base[0], (1 << i), ((uint32_t *)mem_base)[0]);
319+
__fatal_error(error_buffer);
320+
#endif
296321
return false;
297322
}
298323
}
299324

300-
/* test address bus */
301-
/* Check individual address lines */
325+
// Test address bus
302326
for (uint32_t i = 1; i < MICROPY_HW_SDRAM_SIZE; i <<= 1) {
303327
mem_base[i] = pattern;
304328
if (mem_base[i] != pattern) {
305-
printf("address bus lines test failed! address (%p)\n", &mem_base[i]);
329+
#if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
330+
snprintf(error_buffer, sizeof(error_buffer),
331+
"Address bus test failed at 0x%p expected 0x%x found 0x%x",
332+
&mem_base[i], pattern, mem_base[i]);
333+
__fatal_error(error_buffer);
334+
#endif
306335
return false;
307336
}
308337
}
309338

310-
/* Check for aliasing (overlaping addresses) */
339+
// Check for aliasing (overlaping addresses)
311340
mem_base[0] = antipattern;
312341
for (uint32_t i = 1; i < MICROPY_HW_SDRAM_SIZE; i <<= 1) {
313342
if (mem_base[i] != pattern) {
314-
printf("address bus overlap %p\n", &mem_base[i]);
343+
#if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
344+
snprintf(error_buffer, sizeof(error_buffer),
345+
"Address bus overlap at 0x%p expected 0x%x found 0x%x",
346+
&mem_base[i], pattern, mem_base[i]);
347+
__fatal_error(error_buffer);
348+
#endif
315349
return false;
316350
}
317351
}
318352

319-
/* test all ram cells */
320-
if (!fast) {
321-
for (uint32_t i = 0; i < MICROPY_HW_SDRAM_SIZE; ++i) {
353+
// Test all RAM cells
354+
if (exhaustive) {
355+
// Write all memory first then compare, so even if the cache
356+
// is enabled, it's not just writing and reading from cache.
357+
// Note: This test should also detect refresh rate issues.
358+
for (uint32_t i = 0; i < MICROPY_HW_SDRAM_SIZE; i++) {
322359
mem_base[i] = pattern;
360+
}
361+
362+
for (uint32_t i = 0; i < MICROPY_HW_SDRAM_SIZE; i++) {
323363
if (mem_base[i] != pattern) {
324-
printf("address bus test failed! address (%p)\n", &mem_base[i]);
364+
#if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
365+
snprintf(error_buffer, sizeof(error_buffer),
366+
"Address bus slow test failed at 0x%p expected 0x%x found 0x%x",
367+
&mem_base[i], pattern, mem_base[i]);
368+
__fatal_error(error_buffer);
369+
#endif
325370
return false;
326371
}
327372
}
328-
} else {
329-
memset(mem_base, pattern, MICROPY_HW_SDRAM_SIZE);
330373
}
331374

375+
#if (__DCACHE_PRESENT == 1)
376+
// Re-enable caches if they were enabled before the test started.
377+
if (i_cache_disabled) {
378+
SCB_EnableICache();
379+
}
380+
381+
if (d_cache_disabled) {
382+
SCB_EnableDCache();
383+
}
384+
#endif
385+
332386
return true;
333387
}
334388

ports/stm32/sdram.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ void *sdram_start(void);
1313
void *sdram_end(void);
1414
void sdram_enter_low_power(void);
1515
void sdram_leave_low_power(void);
16-
bool sdram_test(bool fast);
16+
bool sdram_test(bool exhaustive);
1717
#endif // __SDRAM_H__

0 commit comments

Comments
 (0)