@@ -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
0 commit comments