Call to arms | Teensy + SDRAM = true

@KurtE - @Rezo
Was playing with your teensy-dev sketch method so decided to see if I could get EXTRAM working like @Rezo did with platform.io.

First I change the build flag to:
Code:
teensyDevBrd4.build.flags.ld=-Wl,--gc-sections,--relax "-T{build.variant.path}/imxrt1062_mm_sdram.ld"

which points to the custom .ld file.

Then I ran the @Rezo's sketch and it worked:

Code:
No Crash Data To Report
  Hopefully all is well, but certain types of crashes can't be reported:
    stuck in an infinite loop (technically, hardware still running properly)
    remaining in a low power sleep mode
    access to certain peripherals without their clock enabled (eg, FlexIO)
    change of CPU or bus clock speed without use of glitchless mux
SDRAM WORKING :).....
buffer1: 0x80232800, buffer2: 0x80000000
buffer1[0]: 1042, buffer2[11652]: 1707

But still have to use the library as well. But you do get your extmem.

Note: files in the core would still have to be modified per post #472 dont know if that would be possible, also additional files would have to be moded as well - hopefully @KurtE can figure out a way to maybe override the files in the core and use the ones in the variant folder without having to mod the core. Don't know if that is possible.
 
Note: files in the core would still have to be modified per post #472 dont know if that would be possible, also additional files would have to be moded as well - hopefully @KurtE can figure out a way to maybe override the files in the core and use the ones in the variant folder without having to mod the core. Don't know if that is possible.
I am not sure if we can currently do everything without some mods to the current core.

That is you would need some simple hook in to for example overwrite the settings for the pin definitions. Currently I have it simply looking for the existence of the file variant.h... I probably need to define it to overwrite more of the core_pins.h file to handle the different potential number of pins defined. The current way for example in digitalToggleFast is way to specific to the 3 different standard boards.
Code:
#if CORE_NUM_DIGITAL > 40
        } else if (pin == 40) {
            CORE_PIN40_PORTTOGGLE = CORE_PIN40_BITMASK;
        } else if (pin == 41) {
            CORE_PIN41_PORTTOGGLE = CORE_PIN41_BITMASK;
        } else if (pin == 42) {
            CORE_PIN42_PORTTOGGLE = CORE_PIN42_BITMASK;
        } else if (pin == 43) {
            CORE_PIN43_PORTTOGGLE = CORE_PIN43_BITMASK;
        } else if (pin == 44) {
            CORE_PIN44_PORTTOGGLE = CORE_PIN44_BITMASK;
        } else if (pin == 45) {
            CORE_PIN45_PORTTOGGLE = CORE_PIN45_BITMASK;
#endif
#if CORE_NUM_DIGITAL > 46
        } else if (pin == 46) {
            CORE_PIN46_PORTTOGGLE = CORE_PIN46_BITMASK;
Could potentially hack it like:
Code:
#if CORE_NUM_DIGITAL > 40
        } else if (pin == 40) {
            CORE_PIN40_PORTTOGGLE = CORE_PIN40_BITMASK;
#endif
#if CORE_NUM_DIGITAL > 41
        } else if (pin == 41) {
            CORE_PIN41_PORTTOGGLE = CORE_PIN41_BITMASK;
#endif
#if CORE_NUM_DIGITAL > 42
        } else if (pin == 42) {
            CORE_PIN42_PORTTOGGLE = CORE_PIN42_BITMASK;
#endif
#if CORE_NUM_DIGITAL > 43
        } else if (pin == 43) {
            CORE_PIN43_PORTTOGGLE = CORE_PIN43_BITMASK;
...
Or reimplement it in a simpler way, like:
Code:
static inline void digitalToggleFast(uint8_t pin) {
  if (__builtin_constant_p(pin)) {
      if (pin >= CORE_NUM_DIGITAL) return;
    *portToggleRegister(pin) = digital_pin_to_info_PGM[pin].mask;
  } else {
    digitalToggle(pin);
  }
}
Example sketch to see difference in generated code:
Code:
void setup() {
}

static inline void digitalToggleFastArray(uint8_t pin) {
  if (__builtin_constant_p(pin)) {
      if (pin >= CORE_NUM_DIGITAL) return;
    *portToggleRegister(pin) = digital_pin_to_info_PGM[pin].mask;
  } else {
    digitalToggle(pin);
  }
}

void loop() {
  digitalToggleFast(1);
  digitalToggleFast(2);
  digitalToggleFast(3);
  digitalToggleFast(3);
  digitalToggleFast(2);
  digitalToggleFast(1);
  digitalToggle(4);
  digitalToggleFastArray(3);
  digitalToggleFastArray(2);
  digitalToggleFastArray(1);
  digitalToggleFastArray(1);
  digitalToggleFastArray(2);
  digitalToggleFastArray(3);
}

Generated ...
Code:
void loop() {
      6c:    b538          push    {r3, r4, r5, lr}
            CORE_PIN1_PORTTOGGLE = CORE_PIN1_BITMASK;
      6e:    2004          movs    r0, #4
            CORE_PIN2_PORTTOGGLE = CORE_PIN2_BITMASK;
      70:    4b13          ldr    r3, [pc, #76]    ; (c0 <loop+0x54>)
            CORE_PIN1_PORTTOGGLE = CORE_PIN1_BITMASK;
      72:    f04f 4284     mov.w    r2, #1107296256    ; 0x42000000
            CORE_PIN2_PORTTOGGLE = CORE_PIN2_BITMASK;
      76:    2110          movs    r1, #16
            CORE_PIN3_PORTTOGGLE = CORE_PIN3_BITMASK;
      78:    2420          movs    r4, #32
            CORE_PIN1_PORTTOGGLE = CORE_PIN1_BITMASK;
      7a:    f8c2 008c     str.w    r0, [r2, #140]    ; 0x8c
            CORE_PIN2_PORTTOGGLE = CORE_PIN2_BITMASK;
      7e:    f8c3 108c     str.w    r1, [r3, #140]    ; 0x8c
            CORE_PIN3_PORTTOGGLE = CORE_PIN3_BITMASK;
      82:    f8c3 408c     str.w    r4, [r3, #140]    ; 0x8c
      86:    f8c3 408c     str.w    r4, [r3, #140]    ; 0x8c
            CORE_PIN2_PORTTOGGLE = CORE_PIN2_BITMASK;
      8a:    f8c3 108c     str.w    r1, [r3, #140]    ; 0x8c
            CORE_PIN1_PORTTOGGLE = CORE_PIN1_BITMASK;
      8e:    f8c2 008c     str.w    r0, [r2, #140]    ; 0x8c
  digitalToggleFast(2);
  digitalToggleFast(3);
  digitalToggleFast(3);
  digitalToggleFast(2);
  digitalToggleFast(1);
  digitalToggle(4);
      92:    f000 f819     bl    c8 <digitalToggle>
    *portToggleRegister(pin) = digital_pin_to_info_PGM[pin].mask;
      96:    4b0b          ldr    r3, [pc, #44]    ; (c4 <loop+0x58>)
      98:    6b1a          ldr    r2, [r3, #48]    ; 0x30
      9a:    6bd9          ldr    r1, [r3, #60]    ; 0x3c
      9c:    6a18          ldr    r0, [r3, #32]
      9e:    f8c2 108c     str.w    r1, [r2, #140]    ; 0x8c
      a2:    6adc          ldr    r4, [r3, #44]    ; 0x2c
      a4:    691d          ldr    r5, [r3, #16]
      a6:    f8c0 408c     str.w    r4, [r0, #140]    ; 0x8c
      aa:    69db          ldr    r3, [r3, #28]
      ac:    f8c5 308c     str.w    r3, [r5, #140]    ; 0x8c
      b0:    f8c5 308c     str.w    r3, [r5, #140]    ; 0x8c
      b4:    f8c0 408c     str.w    r4, [r0, #140]    ; 0x8c
      b8:    f8c2 108c     str.w    r1, [r2, #140]    ; 0x8c
  digitalToggleFastArray(2);
  digitalToggleFastArray(1);
  digitalToggleFastArray(1);
  digitalToggleFastArray(2);
  digitalToggleFastArray(3);
      bc:    bd38          pop    {r3, r4, r5, pc}
      be:    bf00          nop
      c0:    4200c000     .word    0x4200c000
      c4:    20000280     .word    0x20000280

000000c8 <digitalToggle>:
    p->SM[submodule].CTRL = FLEXPWM_SMCTRL_FULL | FLEXPWM_SMCTRL_PRSC(prescale);
    p->SM[submodule].VAL1 = newdiv - 1;
    p->SM[submodule].VAL0 = (p->SM[submodule].VAL0 * newdiv) / olddiv;
Similar issue with table in digital.c
Could add a lot more #if like I showed above.
Or move array to own file. Or check for some define that if exists, don't define the table here...

bootdata.c, eeprom.c = don't compile unless one of these defines are defined:
Code:
#if defined(ARDUINO_TEENSY40)
    0x00200000,        // sflashA1Size            0x50
#elif defined(ARDUINO_TEENSY41)
    0x00800000,        // sflashA1Size            0x50
#elif defined(ARDUINO_TEENSY_MICROMOD)
    0x01000000,        // sflashA1Size            0x50
#else
#error "Unknow flash chip size";
#endif

could potentially define ARDUINO_TEENSY_MICROMOD on the command line to get around it...
in the boards.txt
 
There is a way to override functions provided by the core, without modifying the core files - provided they're defined in .c/.cpp files and not inlined from headers. Hopefully I can have some example code up later today.
 
could potentially define ARDUINO_TEENSY_MICROMOD on the command line to get around it...
in the boards.txt
I tried the above:
Code:
teensyDevBrd4.build.flags.defs=-D__IMXRT1062__ -DTEENSYDUINO=159 -DARDUINO_TEENSY_MICROMOD

And it worked, such that I no longer needed to update bootdata.c nor eeprom.c files.
I have also mucked up the copy of variant.h to define some new pins... The ones in RED.

I have not fixed issue with things like digital.c yet so only pins up to 54 are in the table...

I also brought in the changes that @mjs513 mentioned for ld file...
Current PIP (play in progress included here)


1705774717156.png
 

Attachments

  • teensy-dev.zip
    8.1 KB · Views: 559
Quick update: from last update
I created a file in the variant directory: variant.c
Code:
#include "core_pins.h"
const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
    {&CORE_PIN0_PORTREG, &CORE_PIN0_CONFIG, &CORE_PIN0_PADCONFIG, CORE_PIN0_BITMASK},
    {&CORE_PIN1_PORTREG, &CORE_PIN1_CONFIG, &CORE_PIN1_PADCONFIG, CORE_PIN1_BITMASK},
    {&CORE_PIN2_PORTREG, &CORE_PIN2_CONFIG, &CORE_PIN2_PADCONFIG, CORE_PIN2_BITMASK},
    {&CORE_PIN3_PORTREG, &CORE_PIN3_CONFIG, &CORE_PIN3_PADCONFIG, CORE_PIN3_BITMASK},
    {&CORE_PIN4_PORTREG, &CORE_PIN4_CONFIG, &CORE_PIN4_PADCONFIG, CORE_PIN4_BITMASK},
    {&CORE_PIN5_PORTREG, &CORE_PIN5_CONFIG, &CORE_PIN5_PADCONFIG, CORE_PIN5_BITMASK},
    {&CORE_PIN6_PORTREG, &CORE_PIN6_CONFIG, &CORE_PIN6_PADCONFIG, CORE_PIN6_BITMASK},
    {&CORE_PIN7_PORTREG, &CORE_PIN7_CONFIG, &CORE_PIN7_PADCONFIG, CORE_PIN7_BITMASK},
    {&CORE_PIN8_PORTREG, &CORE_PIN8_CONFIG, &CORE_PIN8_PADCONFIG, CORE_PIN8_BITMASK},
    {&CORE_PIN9_PORTREG, &CORE_PIN9_CONFIG, &CORE_PIN9_PADCONFIG, CORE_PIN9_BITMASK},
    {&CORE_PIN10_PORTREG, &CORE_PIN10_CONFIG, &CORE_PIN10_PADCONFIG, CORE_PIN10_BITMASK},
    {&CORE_PIN11_PORTREG, &CORE_PIN11_CONFIG, &CORE_PIN11_PADCONFIG, CORE_PIN11_BITMASK},
    {&CORE_PIN12_PORTREG, &CORE_PIN12_CONFIG, &CORE_PIN12_PADCONFIG, CORE_PIN12_BITMASK},
    {&CORE_PIN13_PORTREG, &CORE_PIN13_CONFIG, &CORE_PIN13_PADCONFIG, CORE_PIN13_BITMASK},
    {&CORE_PIN14_PORTREG, &CORE_PIN14_CONFIG, &CORE_PIN14_PADCONFIG, CORE_PIN14_BITMASK},
    {&CORE_PIN15_PORTREG, &CORE_PIN15_CONFIG, &CORE_PIN15_PADCONFIG, CORE_PIN15_BITMASK},
    {&CORE_PIN16_PORTREG, &CORE_PIN16_CONFIG, &CORE_PIN16_PADCONFIG, CORE_PIN16_BITMASK},
    {&CORE_PIN17_PORTREG, &CORE_PIN17_CONFIG, &CORE_PIN17_PADCONFIG, CORE_PIN17_BITMASK},
    {&CORE_PIN18_PORTREG, &CORE_PIN18_CONFIG, &CORE_PIN18_PADCONFIG, CORE_PIN18_BITMASK},
    {&CORE_PIN19_PORTREG, &CORE_PIN19_CONFIG, &CORE_PIN19_PADCONFIG, CORE_PIN19_BITMASK},
    {&CORE_PIN20_PORTREG, &CORE_PIN20_CONFIG, &CORE_PIN20_PADCONFIG, CORE_PIN20_BITMASK},
    {&CORE_PIN21_PORTREG, &CORE_PIN21_CONFIG, &CORE_PIN21_PADCONFIG, CORE_PIN21_BITMASK},
    {&CORE_PIN22_PORTREG, &CORE_PIN22_CONFIG, &CORE_PIN22_PADCONFIG, CORE_PIN22_BITMASK},
    {&CORE_PIN23_PORTREG, &CORE_PIN23_CONFIG, &CORE_PIN23_PADCONFIG, CORE_PIN23_BITMASK},
    {&CORE_PIN24_PORTREG, &CORE_PIN24_CONFIG, &CORE_PIN24_PADCONFIG, CORE_PIN24_BITMASK},
    {&CORE_PIN25_PORTREG, &CORE_PIN25_CONFIG, &CORE_PIN25_PADCONFIG, CORE_PIN25_BITMASK},
    {&CORE_PIN26_PORTREG, &CORE_PIN26_CONFIG, &CORE_PIN26_PADCONFIG, CORE_PIN26_BITMASK},
    {&CORE_PIN27_PORTREG, &CORE_PIN27_CONFIG, &CORE_PIN27_PADCONFIG, CORE_PIN27_BITMASK},
    {&CORE_PIN28_PORTREG, &CORE_PIN28_CONFIG, &CORE_PIN28_PADCONFIG, CORE_PIN28_BITMASK},
    {&CORE_PIN29_PORTREG, &CORE_PIN29_CONFIG, &CORE_PIN29_PADCONFIG, CORE_PIN29_BITMASK},
    {&CORE_PIN30_PORTREG, &CORE_PIN30_CONFIG, &CORE_PIN30_PADCONFIG, CORE_PIN30_BITMASK},
    {&CORE_PIN31_PORTREG, &CORE_PIN31_CONFIG, &CORE_PIN31_PADCONFIG, CORE_PIN31_BITMASK},
    {&CORE_PIN32_PORTREG, &CORE_PIN32_CONFIG, &CORE_PIN32_PADCONFIG, CORE_PIN32_BITMASK},
    {&CORE_PIN33_PORTREG, &CORE_PIN33_CONFIG, &CORE_PIN33_PADCONFIG, CORE_PIN33_BITMASK},
    {&CORE_PIN34_PORTREG, &CORE_PIN34_CONFIG, &CORE_PIN34_PADCONFIG, CORE_PIN34_BITMASK},
    {&CORE_PIN35_PORTREG, &CORE_PIN35_CONFIG, &CORE_PIN35_PADCONFIG, CORE_PIN35_BITMASK},
    {&CORE_PIN36_PORTREG, &CORE_PIN36_CONFIG, &CORE_PIN36_PADCONFIG, CORE_PIN36_BITMASK},
    {&CORE_PIN37_PORTREG, &CORE_PIN37_CONFIG, &CORE_PIN37_PADCONFIG, CORE_PIN37_BITMASK},
    {&CORE_PIN38_PORTREG, &CORE_PIN38_CONFIG, &CORE_PIN38_PADCONFIG, CORE_PIN38_BITMASK},
    {&CORE_PIN39_PORTREG, &CORE_PIN39_CONFIG, &CORE_PIN39_PADCONFIG, CORE_PIN39_BITMASK},
    {&CORE_PIN40_PORTREG, &CORE_PIN40_CONFIG, &CORE_PIN40_PADCONFIG, CORE_PIN40_BITMASK},
    {&CORE_PIN41_PORTREG, &CORE_PIN41_CONFIG, &CORE_PIN41_PADCONFIG, CORE_PIN41_BITMASK},
    {&CORE_PIN42_PORTREG, &CORE_PIN42_CONFIG, &CORE_PIN42_PADCONFIG, CORE_PIN42_BITMASK},
    {&CORE_PIN43_PORTREG, &CORE_PIN43_CONFIG, &CORE_PIN43_PADCONFIG, CORE_PIN43_BITMASK},
    {&CORE_PIN44_PORTREG, &CORE_PIN44_CONFIG, &CORE_PIN44_PADCONFIG, CORE_PIN44_BITMASK},
    {&CORE_PIN45_PORTREG, &CORE_PIN45_CONFIG, &CORE_PIN45_PADCONFIG, CORE_PIN45_BITMASK},
    {&CORE_PIN46_PORTREG, &CORE_PIN46_CONFIG, &CORE_PIN46_PADCONFIG, CORE_PIN46_BITMASK},
    {&CORE_PIN47_PORTREG, &CORE_PIN47_CONFIG, &CORE_PIN47_PADCONFIG, CORE_PIN47_BITMASK},
    {&CORE_PIN48_PORTREG, &CORE_PIN48_CONFIG, &CORE_PIN48_PADCONFIG, CORE_PIN48_BITMASK},
    {&CORE_PIN49_PORTREG, &CORE_PIN49_CONFIG, &CORE_PIN49_PADCONFIG, CORE_PIN49_BITMASK},
    {&CORE_PIN50_PORTREG, &CORE_PIN50_CONFIG, &CORE_PIN50_PADCONFIG, CORE_PIN50_BITMASK},
    {&CORE_PIN51_PORTREG, &CORE_PIN51_CONFIG, &CORE_PIN51_PADCONFIG, CORE_PIN51_BITMASK},
    {&CORE_PIN52_PORTREG, &CORE_PIN52_CONFIG, &CORE_PIN52_PADCONFIG, CORE_PIN52_BITMASK},
    {&CORE_PIN53_PORTREG, &CORE_PIN53_CONFIG, &CORE_PIN53_PADCONFIG, CORE_PIN53_BITMASK},
    {&CORE_PIN54_PORTREG, &CORE_PIN54_CONFIG, &CORE_PIN54_PADCONFIG, CORE_PIN54_BITMASK},
    {&CORE_PIN55_PORTREG, &CORE_PIN55_CONFIG, &CORE_PIN55_PADCONFIG, CORE_PIN55_BITMASK},
    {&CORE_PIN56_PORTREG, &CORE_PIN56_CONFIG, &CORE_PIN56_PADCONFIG, CORE_PIN56_BITMASK},
    {&CORE_PIN57_PORTREG, &CORE_PIN57_CONFIG, &CORE_PIN57_PADCONFIG, CORE_PIN57_BITMASK},
    {&CORE_PIN58_PORTREG, &CORE_PIN58_CONFIG, &CORE_PIN58_PADCONFIG, CORE_PIN58_BITMASK},
    {&CORE_PIN59_PORTREG, &CORE_PIN59_CONFIG, &CORE_PIN59_PADCONFIG, CORE_PIN59_BITMASK},
    {&CORE_PIN60_PORTREG, &CORE_PIN60_CONFIG, &CORE_PIN60_PADCONFIG, CORE_PIN60_BITMASK},
    {&CORE_PIN61_PORTREG, &CORE_PIN61_CONFIG, &CORE_PIN61_PADCONFIG, CORE_PIN61_BITMASK},
    {&CORE_PIN62_PORTREG, &CORE_PIN62_CONFIG, &CORE_PIN62_PADCONFIG, CORE_PIN62_BITMASK},
    {&CORE_PIN63_PORTREG, &CORE_PIN63_CONFIG, &CORE_PIN63_PADCONFIG, CORE_PIN63_BITMASK},   
};

It properly compiled. Side note: I first had it as variant.cpp, but received a few warning messages of converting
int to uint32_t. Has to do with the pin index of 31, like:
#define CORE_PIN27_BIT 31
Then used with:
#define CORE_PIN27_BITMASK (1<<(CORE_PIN27_BIT))

It failed to link with duplicate... So current simple fix, in digital.c
Code:
const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[]  __attribute__((weak)) = {
    {&CORE_PIN0_PORTREG, &CORE_PIN0_CONFIG, &CORE_PIN0_PADCONFIG, CORE_PIN0_BITMASK},
    {&CORE_PIN1_PORTREG, &CORE_PIN1_CONFIG, &CORE_PIN1_PADCONFIG, CORE_PIN1_BITMASK},

define the table using the weak attribute.
 
It failed to link with duplicate... So current simple fix, in digital.c
Code:
const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[]  __attribute__((weak)) = {
    {&CORE_PIN0_PORTREG, &CORE_PIN0_CONFIG, &CORE_PIN0_PADCONFIG, CORE_PIN0_BITMASK},
    {&CORE_PIN1_PORTREG, &CORE_PIN1_CONFIG, &CORE_PIN1_PADCONFIG, CORE_PIN1_BITMASK},

define the table using the weak attribute.
That's the sort of thing I was hinting at earlier...
Since the linker will only include an .obj file when it provides one or more previously unresolved symbols, if you override all external symbols from an original (cores) file it will be discarded and your implementation will be used instead - no weak symbols necessary. This is what I've done with extmem.c to make a library that works with both SDRAM and PSRAM using the extmem_* functions.
 
@KurtE - @Rezo
Was playing with your teensy-dev sketch method so decided to see if I could get EXTRAM working like @Rezo did with platform.io.
@mjs513 @defragster can we possibly add a description of the two methods to use the library into the readme?
Option 1 is to include the library, init the sdram and use malloc, free functions etc
Option 2 is to use custom linker file and EXTMEM macro - then describe how to point to the customer linker file in Arduino 1.x and 2.x as well as PlatformIO.

What do you think?
 
Hopefully I can have some example code up later today.
Initial work available here: https://github.com/A-Dunstan/SDRAM_EXTMEM

The two main ideas here are:
- make it easy for existing/new code to support either PSRAM or SDRAM by using the existing extmem_* functions
- initialize SDRAM automatically
The tricky part is achieving this without any modifications to the core files...

The first objective is done by reimplementing all of the external functions exposed by cores extmem.c. Since the cores obj archive is passed after any libraries on the linker command line, it will discard the cores copy of extmem.o and we don't get any duplicate symbol errors.

The second objective is easy, just "#include <SDRAM.h>" and the library overrides startup_middle_hook() to attempt SDRAM initialization if PSRAM hasn't already been initialized. There's a couple of minor issues still to be solved with this approach; the SDRAM setup sets the mux for a bunch of pins to SEMC, and I'm not sure exactly how it will behave if there's a flash chip attached to the flexSPI pins rather than a PSRAM. I'm also not super happy about overriding startup_middle_hook(), since other libraries may also want to do that... but that's more of a generic issue with Teensyduino (how to run multiple startup function hooks) rather than being SDRAM related, which I know a fix for and may send a pull request at some point.

The SDRAM speed can be adjusted by redefining SEMC_CLOCK. You can run it at 204Mhz by overclocking the CPU to 816MHz and using SEMC_CLOCK_CPU_DIV_4 but it's unstable; running at 200MHz by using the standard CPU speed of 600MHz and SEMC_CLOCK_CPU_DIV_3 on the other hand seems very stable.

I've only added a couple of examples so far, extmem_test.ino is obviously based on the existing PSRAM test code with additions to monitor timing (I'm pretty sure I found those in this forum somewhere so can't take credit for them) and "worst-case" random access testing. The LittleFS example has been modified to dynamically allocate a large-ish RAM filesystem (6MB) so it will fail on a device with neither PSRAM nor SDRAM - it's mostly just to demonstrate that existing code (i.e. LittleFS) can use extmem_malloc() without modifications or knowledge about which underlying type of memory is used.

SDRAM test results @ 200MHz:
Code:
EXTMEM Memory Test, 32 Mbyte
EXTMEM frequency: 200.00 MHz
Beginning sequential access tests
testing with fixed pattern 5A698421             fill us:167782 MB/s:190.72              test us:348201 MB/s:91.90
testing with fixed pattern 55555555             fill us:167783 MB/s:190.72              test us:348201 MB/s:91.90
testing with fixed pattern 33333333             fill us:167782 MB/s:190.72              test us:348203 MB/s:91.90
testing with fixed pattern 0F0F0F0F             fill us:167783 MB/s:190.72              test us:348200 MB/s:91.90
testing with fixed pattern 00FF00FF             fill us:167783 MB/s:190.72              test us:348200 MB/s:91.90
testing with fixed pattern 0000FFFF             fill us:168302 MB/s:190.13              test us:348202 MB/s:91.90
testing with fixed pattern AAAAAAAA             fill us:167782 MB/s:190.72              test us:348206 MB/s:91.90
testing with fixed pattern CCCCCCCC             fill us:167782 MB/s:190.72              test us:348201 MB/s:91.90
testing with fixed pattern F0F0F0F0             fill us:167782 MB/s:190.72              test us:348207 MB/s:91.90
testing with fixed pattern FF00FF00             fill us:167782 MB/s:190.72              test us:348202 MB/s:91.90
testing with fixed pattern FFFF0000             fill us:167783 MB/s:190.72              test us:348200 MB/s:91.90
testing with fixed pattern FFFFFFFF             fill us:167783 MB/s:190.72              test us:348206 MB/s:91.90
testing with fixed pattern 00000000             fill us:167783 MB/s:190.72              test us:348202 MB/s:91.90
testing with pseudo-random sequence, seed=2976674124            fill us:391490 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=1438200953            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=3413783263            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=1900517911            fill us:391490 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=1227909400            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=276562754             fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=146878114             fill us:391490 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=615545407             fill us:391490 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=110497896             fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=74539250              fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=4197336575            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=2280382233            fill us:391490 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=542894183             fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=3978544245            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=2315909796            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=3736286001            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=2876690683            fill us:391490 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=215559886             fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=539179291             fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=537678650             fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=4001405270            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=2169216599            fill us:391490 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=4036891097            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=1535452389            fill us:391490 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=2959727213            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=4219363395            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=1036929753            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=2125248865            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=3177905864            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=2399307098            fill us:391490 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=3847634607            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=27467969              fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=520563506             fill us:391490 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=381313790             fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=4174769276            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=3932189449            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=4079717394            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=868357076             fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=2474062993            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=1502682190            fill us:391490 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=2471230478            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
testing with pseudo-random sequence, seed=85016565              fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=1427530695            fill us:391489 MB/s:81.74               test us:589632 MB/s:54.27
testing with pseudo-random sequence, seed=1100533073            fill us:391489 MB/s:81.74               test us:589631 MB/s:54.27
 test ran for 50.58 seconds
 3648 MBs test ran at 72.12 MB/sec overall
Beginning random access tests
testing with fixed pattern 5A698421             fill us:606564 MB/s:52.76               test us:1875767 MB/s:17.06
testing with fixed pattern 55555555             fill us:607757 MB/s:52.65               test us:1875764 MB/s:17.06
testing with fixed pattern 33333333             fill us:605276 MB/s:52.87               test us:1875768 MB/s:17.06
testing with fixed pattern 0F0F0F0F             fill us:605598 MB/s:52.84               test us:1875760 MB/s:17.06
testing with fixed pattern 00FF00FF             fill us:606028 MB/s:52.80               test us:1875760 MB/s:17.06
testing with fixed pattern 0000FFFF             fill us:605280 MB/s:52.87               test us:1875771 MB/s:17.06
testing with fixed pattern AAAAAAAA             fill us:604851 MB/s:52.91               test us:1875755 MB/s:17.06
testing with fixed pattern CCCCCCCC             fill us:605601 MB/s:52.84               test us:1875765 MB/s:17.06
testing with fixed pattern F0F0F0F0             fill us:606242 MB/s:52.78               test us:1875769 MB/s:17.06
testing with fixed pattern FF00FF00             fill us:607357 MB/s:52.69               test us:1875759 MB/s:17.06
testing with fixed pattern FFFF0000             fill us:606997 MB/s:52.72               test us:1875759 MB/s:17.06
testing with fixed pattern FFFFFFFF             fill us:605283 MB/s:52.87               test us:1875764 MB/s:17.06
testing with fixed pattern 00000000             fill us:605606 MB/s:52.84               test us:1875756 MB/s:17.06
testing with pseudo-random sequence, seed=2976674124            fill us:605105 MB/s:52.88               test us:2091146 MB/s:15.30
testing with pseudo-random sequence, seed=1438200953            fill us:605023 MB/s:52.89               test us:2091127 MB/s:15.30
testing with pseudo-random sequence, seed=3413783263            fill us:605043 MB/s:52.89               test us:2091130 MB/s:15.30
testing with pseudo-random sequence, seed=1900517911            fill us:610421 MB/s:52.42               test us:2091139 MB/s:15.30
testing with pseudo-random sequence, seed=1227909400            fill us:605040 MB/s:52.89               test us:2091145 MB/s:15.30
testing with pseudo-random sequence, seed=276562754             fill us:605892 MB/s:52.81               test us:2091177 MB/s:15.30
testing with pseudo-random sequence, seed=146878114             fill us:608300 MB/s:52.61               test us:2091136 MB/s:15.30
testing with pseudo-random sequence, seed=615545407             fill us:605038 MB/s:52.89               test us:2091156 MB/s:15.30
testing with pseudo-random sequence, seed=110497896             fill us:605341 MB/s:52.86               test us:2091128 MB/s:15.30
testing with pseudo-random sequence, seed=74539250              fill us:604845 MB/s:52.91               test us:2091146 MB/s:15.30
testing with pseudo-random sequence, seed=4197336575            fill us:605334 MB/s:52.86               test us:2091160 MB/s:15.30
testing with pseudo-random sequence, seed=2280382233            fill us:611945 MB/s:52.29               test us:2091155 MB/s:15.30
testing with pseudo-random sequence, seed=542894183             fill us:611922 MB/s:52.29               test us:2091134 MB/s:15.30
testing with pseudo-random sequence, seed=3978544245            fill us:605635 MB/s:52.84               test us:2091145 MB/s:15.30
testing with pseudo-random sequence, seed=2315909796            fill us:610635 MB/s:52.40               test us:2091146 MB/s:15.30
testing with pseudo-random sequence, seed=3736286001            fill us:605433 MB/s:52.85               test us:2091128 MB/s:15.30
testing with pseudo-random sequence, seed=2876690683            fill us:606608 MB/s:52.75               test us:2091148 MB/s:15.30
testing with pseudo-random sequence, seed=215559886             fill us:605241 MB/s:52.87               test us:2091148 MB/s:15.30
testing with pseudo-random sequence, seed=539179291             fill us:605341 MB/s:52.86               test us:2091107 MB/s:15.30
testing with pseudo-random sequence, seed=537678650             fill us:605942 MB/s:52.81               test us:2091125 MB/s:15.30
testing with pseudo-random sequence, seed=4001405270            fill us:605837 MB/s:52.82               test us:2091117 MB/s:15.30
testing with pseudo-random sequence, seed=2169216599            fill us:605298 MB/s:52.87               test us:2091155 MB/s:15.30
testing with pseudo-random sequence, seed=4036891097            fill us:605049 MB/s:52.89               test us:2091139 MB/s:15.30
testing with pseudo-random sequence, seed=1535452389            fill us:609902 MB/s:52.47               test us:2091146 MB/s:15.30
testing with pseudo-random sequence, seed=2959727213            fill us:605043 MB/s:52.89               test us:2091122 MB/s:15.30
testing with pseudo-random sequence, seed=4219363395            fill us:606195 MB/s:52.79               test us:2091174 MB/s:15.30
testing with pseudo-random sequence, seed=1036929753            fill us:605038 MB/s:52.89               test us:2091144 MB/s:15.30
testing with pseudo-random sequence, seed=2125248865            fill us:608684 MB/s:52.57               test us:2091118 MB/s:15.30
testing with pseudo-random sequence, seed=3177905864            fill us:609211 MB/s:52.53               test us:2091134 MB/s:15.30
testing with pseudo-random sequence, seed=2399307098            fill us:606475 MB/s:52.76               test us:2091132 MB/s:15.30
testing with pseudo-random sequence, seed=3847634607            fill us:610150 MB/s:52.45               test us:2091163 MB/s:15.30
testing with pseudo-random sequence, seed=27467969              fill us:610420 MB/s:52.42               test us:2091143 MB/s:15.30
testing with pseudo-random sequence, seed=520563506             fill us:605068 MB/s:52.89               test us:2091152 MB/s:15.30
testing with pseudo-random sequence, seed=381313790             fill us:604902 MB/s:52.90               test us:2091137 MB/s:15.30
testing with pseudo-random sequence, seed=4174769276            fill us:605786 MB/s:52.82               test us:2091156 MB/s:15.30
testing with pseudo-random sequence, seed=3932189449            fill us:604844 MB/s:52.91               test us:2091146 MB/s:15.30
testing with pseudo-random sequence, seed=4079717394            fill us:605043 MB/s:52.89               test us:2091131 MB/s:15.30
testing with pseudo-random sequence, seed=868357076             fill us:606849 MB/s:52.73               test us:2091159 MB/s:15.30
testing with pseudo-random sequence, seed=2474062993            fill us:613768 MB/s:52.14               test us:2091146 MB/s:15.30
testing with pseudo-random sequence, seed=1502682190            fill us:610297 MB/s:52.43               test us:2091162 MB/s:15.30
testing with pseudo-random sequence, seed=2471230478            fill us:605045 MB/s:52.89               test us:2091155 MB/s:15.30
testing with pseudo-random sequence, seed=85016565              fill us:610451 MB/s:52.42               test us:2091143 MB/s:15.30
testing with pseudo-random sequence, seed=1427530695            fill us:605338 MB/s:52.86               test us:2091096 MB/s:15.30
testing with pseudo-random sequence, seed=1100533073            fill us:605240 MB/s:52.87               test us:2091120 MB/s:15.30
 test ran for 151.68 seconds
 3648 MBs test ran at 24.05 MB/sec overall
All memory tests passed :-)

Compared to the same test using a Teensy 4.1 with 8MB PSRAM @ 120MHz:
Code:
EXTMEM Memory Test, 8 Mbyte
EXTMEM frequency: 120.00 MHz
Beginning sequential access tests
testing with fixed pattern 5A698421             fill us:249857 MB/s:32.02               test us:227194 MB/s:35.21
testing with fixed pattern 55555555             fill us:249182 MB/s:32.11               test us:227195 MB/s:35.21
testing with fixed pattern 33333333             fill us:248503 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern 0F0F0F0F             fill us:248499 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern 00FF00FF             fill us:248502 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern 0000FFFF             fill us:248509 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern AAAAAAAA             fill us:248504 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern CCCCCCCC             fill us:248510 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern F0F0F0F0             fill us:248507 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern FF00FF00             fill us:248501 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern FFFF0000             fill us:248497 MB/s:32.19               test us:227195 MB/s:35.21
testing with fixed pattern FFFFFFFF             fill us:248734 MB/s:32.16               test us:227195 MB/s:35.21
testing with fixed pattern 00000000             fill us:248508 MB/s:32.19               test us:227195 MB/s:35.21
testing with pseudo-random sequence, seed=2976674124            fill us:249917 MB/s:32.01               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=1438200953            fill us:249915 MB/s:32.01               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=3413783263            fill us:250260 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=1900517911            fill us:249348 MB/s:32.08               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=1227909400            fill us:250142 MB/s:31.98               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=276562754             fill us:250257 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=146878114             fill us:250250 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=615545407             fill us:250257 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=110497896             fill us:250069 MB/s:31.99               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=74539250              fill us:250256 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=4197336575            fill us:250249 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=2280382233            fill us:250259 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=542894183             fill us:249915 MB/s:32.01               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=3978544245            fill us:250257 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=2315909796            fill us:250259 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=3736286001            fill us:250256 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=2876690683            fill us:250256 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=215559886             fill us:249343 MB/s:32.08               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=539179291             fill us:250253 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=537678650             fill us:250247 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=4001405270            fill us:249915 MB/s:32.01               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=2169216599            fill us:250262 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=4036891097            fill us:250257 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=1535452389            fill us:250069 MB/s:31.99               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=2959727213            fill us:250253 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=4219363395            fill us:249350 MB/s:32.08               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=1036929753            fill us:250255 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=2125248865            fill us:250253 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=3177905864            fill us:249921 MB/s:32.01               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=2399307098            fill us:249756 MB/s:32.03               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=3847634607            fill us:250135 MB/s:31.98               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=27467969              fill us:250260 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=520563506             fill us:250256 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=381313790             fill us:250255 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=4174769276            fill us:250257 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=3932189449            fill us:250263 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=4079717394            fill us:248789 MB/s:32.16               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=868357076             fill us:250256 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=2474062993            fill us:250256 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=1502682190            fill us:250254 MB/s:31.97               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=2471230478            fill us:250259 MB/s:31.97               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=85016565              fill us:250070 MB/s:31.99               test us:242487 MB/s:32.99
testing with pseudo-random sequence, seed=1427530695            fill us:250118 MB/s:31.98               test us:242488 MB/s:32.99
testing with pseudo-random sequence, seed=1100533073            fill us:250265 MB/s:31.97               test us:242488 MB/s:32.99
 test ran for 28.08 seconds
 912 MBs test ran at 32.48 MB/sec overall
Beginning random access tests
testing with fixed pattern 5A698421             fill us:943144 MB/s:8.48                test us:1745381 MB/s:4.58
testing with fixed pattern 55555555             fill us:584118 MB/s:13.70               test us:1745363 MB/s:4.58
testing with fixed pattern 33333333             fill us:1276890 MB/s:6.27               test us:1745381 MB/s:4.58
testing with fixed pattern 0F0F0F0F             fill us:584130 MB/s:13.70               test us:1745451 MB/s:4.58
testing with fixed pattern 00FF00FF             fill us:1615514 MB/s:4.95               test us:1745350 MB/s:4.58
testing with fixed pattern 0000FFFF             fill us:624444 MB/s:12.81               test us:1745372 MB/s:4.58
testing with fixed pattern AAAAAAAA             fill us:1276879 MB/s:6.27               test us:1745377 MB/s:4.58
testing with fixed pattern CCCCCCCC             fill us:602800 MB/s:13.27               test us:1745438 MB/s:4.58
testing with fixed pattern F0F0F0F0             fill us:1615519 MB/s:4.95               test us:1745478 MB/s:4.58
testing with fixed pattern FF00FF00             fill us:941547 MB/s:8.50                test us:1745380 MB/s:4.58
testing with fixed pattern FFFF0000             fill us:883516 MB/s:9.05                test us:1745375 MB/s:4.58
testing with fixed pattern FFFFFFFF             fill us:894210 MB/s:8.95                test us:1745405 MB/s:4.58
testing with fixed pattern 00000000             fill us:1276890 MB/s:6.27               test us:1745404 MB/s:4.58
testing with pseudo-random sequence, seed=2976674124            fill us:716012 MB/s:11.17               test us:1758575 MB/s:4.55
testing with pseudo-random sequence, seed=1438200953            fill us:2384940 MB/s:3.35               test us:1758560 MB/s:4.55
testing with pseudo-random sequence, seed=3413783263            fill us:980973 MB/s:8.16                test us:1758626 MB/s:4.55
testing with pseudo-random sequence, seed=1900517911            fill us:1822240 MB/s:4.39               test us:1758689 MB/s:4.55
testing with pseudo-random sequence, seed=1227909400            fill us:1838702 MB/s:4.35               test us:1758616 MB/s:4.55
testing with pseudo-random sequence, seed=276562754             fill us:945898 MB/s:8.46                test us:1758649 MB/s:4.55
testing with pseudo-random sequence, seed=146878114             fill us:602809 MB/s:13.27               test us:1758570 MB/s:4.55
testing with pseudo-random sequence, seed=615545407             fill us:2805284 MB/s:2.85               test us:1758596 MB/s:4.55
testing with pseudo-random sequence, seed=110497896             fill us:716019 MB/s:11.17               test us:1758556 MB/s:4.55
testing with pseudo-random sequence, seed=74539250              fill us:2108872 MB/s:3.79               test us:1758648 MB/s:4.55
testing with pseudo-random sequence, seed=4197336575            fill us:1277725 MB/s:6.26               test us:1758572 MB/s:4.55
testing with pseudo-random sequence, seed=2280382233            fill us:2108866 MB/s:3.79               test us:1758644 MB/s:4.55
testing with pseudo-random sequence, seed=542894183             fill us:1137521 MB/s:7.03               test us:1758667 MB/s:4.55
testing with pseudo-random sequence, seed=3978544245            fill us:1412410 MB/s:5.66               test us:1758636 MB/s:4.55
testing with pseudo-random sequence, seed=2315909796            fill us:1831056 MB/s:4.37               test us:1758620 MB/s:4.55
testing with pseudo-random sequence, seed=3736286001            fill us:2405139 MB/s:3.33               test us:1758572 MB/s:4.55
testing with pseudo-random sequence, seed=2876690683            fill us:1259758 MB/s:6.35               test us:1758526 MB/s:4.55
testing with pseudo-random sequence, seed=215559886             fill us:2428593 MB/s:3.29               test us:1758569 MB/s:4.55
testing with pseudo-random sequence, seed=539179291             fill us:2845729 MB/s:2.81               test us:1758624 MB/s:4.55
testing with pseudo-random sequence, seed=537678650             fill us:1220581 MB/s:6.55               test us:1758636 MB/s:4.55
testing with pseudo-random sequence, seed=4001405270            fill us:1330937 MB/s:6.01               test us:1758623 MB/s:4.55
testing with pseudo-random sequence, seed=2169216599            fill us:2108868 MB/s:3.79               test us:1758659 MB/s:4.55
testing with pseudo-random sequence, seed=4036891097            fill us:2805290 MB/s:2.85               test us:1758568 MB/s:4.55
testing with pseudo-random sequence, seed=1535452389            fill us:919087 MB/s:8.70                test us:1758580 MB/s:4.55
testing with pseudo-random sequence, seed=2959727213            fill us:1453218 MB/s:5.51               test us:1758651 MB/s:4.55
testing with pseudo-random sequence, seed=4219363395            fill us:1847938 MB/s:4.33               test us:1758637 MB/s:4.55
testing with pseudo-random sequence, seed=1036929753            fill us:1785089 MB/s:4.48               test us:1758596 MB/s:4.55
testing with pseudo-random sequence, seed=2125248865            fill us:1654450 MB/s:4.84               test us:1758650 MB/s:4.55
testing with pseudo-random sequence, seed=3177905864            fill us:2384929 MB/s:3.35               test us:1758611 MB/s:4.55
testing with pseudo-random sequence, seed=2399307098            fill us:2805290 MB/s:2.85               test us:1758619 MB/s:4.55
testing with pseudo-random sequence, seed=3847634607            fill us:1049863 MB/s:7.62               test us:1758618 MB/s:4.55
testing with pseudo-random sequence, seed=27467969              fill us:2805289 MB/s:2.85               test us:1758607 MB/s:4.55
testing with pseudo-random sequence, seed=520563506             fill us:2805295 MB/s:2.85               test us:1758667 MB/s:4.55
testing with pseudo-random sequence, seed=381313790             fill us:1662989 MB/s:4.81               test us:1758621 MB/s:4.55
testing with pseudo-random sequence, seed=4174769276            fill us:1065237 MB/s:7.51               test us:1758569 MB/s:4.55
testing with pseudo-random sequence, seed=3932189449            fill us:2409095 MB/s:3.32               test us:1758549 MB/s:4.55
testing with pseudo-random sequence, seed=4079717394            fill us:2805289 MB/s:2.85               test us:1758597 MB/s:4.55
testing with pseudo-random sequence, seed=868357076             fill us:1588967 MB/s:5.03               test us:1758611 MB/s:4.55
testing with pseudo-random sequence, seed=2474062993            fill us:1785090 MB/s:4.48               test us:1758675 MB/s:4.55
testing with pseudo-random sequence, seed=1502682190            fill us:2805289 MB/s:2.85               test us:1758620 MB/s:4.55
testing with pseudo-random sequence, seed=2471230478            fill us:602797 MB/s:13.27               test us:1758520 MB/s:4.55
testing with pseudo-random sequence, seed=85016565              fill us:2805305 MB/s:2.85               test us:1758550 MB/s:4.55
testing with pseudo-random sequence, seed=1427530695            fill us:895092 MB/s:8.94                test us:1758610 MB/s:4.55
testing with pseudo-random sequence, seed=1100533073            fill us:1847949 MB/s:4.33               test us:1758595 MB/s:4.55
 test ran for 192.24 seconds
 912 MBs test ran at 4.74 MB/sec overall
All memory tests passed :-)
 
You can run it at 204Mhz by overclocking the CPU to 816MHz and using SEMC_CLOCK_CPU_DIV_4 but it's unstable; running at 200MHz by using the standard CPU speed of 600MHz and SEMC_CLOCK_CPU_DIV_3 on the other hand seems very stable.

Sounds like a perfect test case for evaluating whether C29 helps. Or at least identify a range that helps. Then find another step up where the range presumably narrows, until we get a good idea of what the best capacitor is for C29.
 
Sounds like a perfect test case for evaluating whether C29 helps. Or at least identify a range that helps. Then find another step up where the range presumably narrows, until we get a good idea of what the best capacitor is for C29.
I don't have the means for testing out different caps in that position. I managed to get the old one off but that's about the best I can do.

(I'm also not sure if it's just the RAM that is unstable at that speed, sometimes the sketch just freezes rather than failing the test... Maybe it would be feasible to bump the CPU up a little bit over 600MHz and use SEMC_CLOCK_CPU_DIV_3 to achieve it.)
 
1.0 pF 81-GRM1555C1H1R0WA1D
1.5 pF 81-GRM1555C1H1R5WA1D
2.2 pF 81-GJM1555C1H2R2GB1D
2.7 pF 81-GJM1555C1H2R7GB1D
3.3 pF 81-GJM1555C1H3R3WB1D
3.9 pF 81-GJM1555C1H3R9GB1D
4.3 pF 81-GJM1555C1H4R3GB1D
4.7 pF 81-GJM1555C1H4R7GB1D
5.6 pF 81-GJM1555C1H5R6FB1D
6.8 pF 81-GJM1555C1H6R8FB1D
7.5 pF 81-GJM1555C1H7R5WB1D
8.2 pF 81-GJM1555C1H8R2FB1D
9.1 pF 81-GJM1555C1H9R1FB1D
10 pF 81-GRM1555C1H100FA1D
11 pF 81-GCM1555C1H110FA6D
12 pF 81-GRM1555C1H120GA1D
13 pF 81-GRT1555C1H130FA2D
15 pF 81-GRM1555C1H150GA1D
18 pF 81-GRM1555C1H180GA1D
22 pF 81-GRM1555C1E220GA1D
@Paul, seems like it's almost time to start testing these. I got 10pcs of each capacitor in this list.

@defragster Can you and I join forces on testing it? Basically, you send me a code file and I'll run it, if that's okay with you?
My idea is that perhaps there can be one or several defines at the top which we edit depending on what capacitor is there. In other words, making the test simple and structured. I guess what Paul wants is to find out is what the highest speed we can reach is.
Next weekend will be good for me to do it, I got a crazy workload this upcoming week.
 
While I am curious about the capacitor, results from real testing are mainly to benefit everyone who will make a custom PCB. And for your PCB, assuming you make more of them, you'll have a definitive answer about what capacitor to use.

Even if you would never consider overclocking, I believe it's pretty conventional wisdom to believe overclocking capability demonstrates the design has more timing margin when run at the rated speed.

Ultimately everyone making their own PCB needs to decide whether to use C29 and which specific value is optimal. Today we simply don't know much. NXP's advice that is works without a capacitor so don't use one isn't wrong, but it also really lacks clarity. Today we do have a pretty strong indication adding some small capacitance improves timing, based on Defragster's early test, but it's still nearly impossible to make a good call on what should be done with new PCB designs.

Better testing those candidate capacitors with good SMD solder and with various overclocking will (hopefully) give everyone designing a PCB in the future much better info. And for me personally, probably won't satisfy my curiosity about how NXP really designed SEMC, but even a little more info might be good.
 
@r can we possibly add a description of the two methods to use the library into the readme?
Option 1 is to include the library, init the sdram and use malloc, free functions etc
Option 2 is to use custom linker file and EXTMEM macro - then describe how to point to the customer linker file in Arduino 1.x and 2.x as well as PlatformIO.

What do you think?
@Rezo
Distinct possibility. Right now playing with @KurtE's changes and seeing what else we can do. Now unless @Paul is willing to make some minor changes to core it may be moot and we would still have to make a standalone core.
 
Note: already works here with NO CAPS overclocked to 198 MHz. Hacking caps did suggest 221 might get close to working with proper parts properly installed.
@defragster Can you and I join forces on testing it? Basically, you send me a code file and I'll run it, if that's okay with you?
My idea is that perhaps there can be one or several defines at the top which we edit depending on what capacitor is there. In other words, making the test simple and structured. I guess what Paul wants is to find out is what the highest speed we can reach is.
Next weekend will be good for me to do it, I got a crazy workload this upcoming week.
Yes, that can work with the code at hand AFAIK. Posted on Wednesday: p#470 {now updated as below)

Yes, I can tweek some as needed - as seen here on upload it makes 3 re-read passes on each of the 57 tests in 93 secs at 166 MHZ - so a bit faster than that at 200+ MHz. The FIXED pattern tests complete fastest and come first - if they don't work then nothing works.

Given a power down between CAP solder/change it could startup in Fixed only test - report results.. Then run the 3 Pass test. Just did this and it looks like this after 106 seconds { SEND prompt appears - but it continues from 13 to 57 tests without stopping }:
SUCCESS sdram.init()

SEND USB to repeat test after completion
Send '1' for 100 or 'k' gives 1K read repeats and 's' returns to start short test value.
Progress:: '#'=fixed pattern, '.'=PsuedoRand patterns, and 'F' shows Failed test pattern
If built with DUAL Serial second SerMon will show details.

Compile Time:: C:\Users\defr\Documents\GitHub\SDRAM_t4\examples\CapReadSDRAM\CapReadSDRAM.ino Jan 21 2024 03:36:21
EXTMEM Memory Test, 32 Mbyte begin, 80000000 end, 82000000

--- START 13 test patterns ------ with 3 reReads ... wait ...
#############
No Errors. All memory tests passed :) (time 12.70 secs)

Send to restart. '1' or 'k' for 100 or 1,000 reReads and 's' for start fast test.
--- START 57 test patterns ------ with 3 reReads ... wait ...
#############............................................
No Errors. All memory tests passed :) (time 93.38 secs)

Send to restart. '1' or 'k' for 100 or 1,000 reReads and 's' for start fast test.
Based on trial and error here that would give needed feedback to quickly chart progress and get toward the needed value seeing reduced errors. If that doesn't get to a CAP value with no errors then the 166 MHz part and PCB won't support it. If those tests pass, then hit '1 + Enter' and wait 45 minutes to see if 100 ReReads passes.

And at 198 Mhz about 99 seconds:
--- START 13 test patterns ------ with 3 reReads ... wait ...
#############
No Errors. All memory tests passed :) (time 11.04 secs)
Send to restart. '1' or 'k' for 100 or 1,000 reReads and 's' for start fast test.
--- START 57 test patterns ------ with 3 reReads ... wait ...
#############............................................
No Errors. All memory tests passed :) (time 87.40 secs)
 
Been hacking away at @KurtE's updated variant method for the sdram board and was able to get SDRAM (extmem and malloc) using the code from the library. Basically added in
Code:
void startup_middle_hook(void)
{
    begin(32, 166, 1);
}
so defaults to 32mb, 166Mhz and no cap.

Here are the mods to variant.h/c. So no more needing to add the library or additional code.

Will take a look at what @jmarsh did to see if there is anything I want to update.
 

Attachments

  • variant.zip
    8.4 KB · Views: 94
Thanks @mjs513 - synced up my version. I also update my cores variants_override branch to only have the current minimal stuff.
Not sure how much farther to take this, as not sure what approach that will be accepted, if any,

Currently the pin table in the variant zip file - adds all of the new pins to the end of the table and has left all of the MicroMod pins in it.
Which needless to say will cause issues: for example I want to run the Pin test (HILowTest), which does things like:
Code:
for ( ii = 0; ii < NUM_DIGITAL_PINS; ii++) {
    pinMode( ii, INPUT_PULLDOWN );
...

Which will set many of your EMC pins (2-5, 28-31, 33) to INPUT_PULLDOWN
So if you are building some more general-purpose boards, you probably need to take some time and work through
what order makes sense...

So I am just dinking around with seeing how one could reasonably facilitate updating the different pins/capabilities, and some
may be different for different reasons. In most cases personally would prefer more surgical changes versus having to copy whole
files out of core. as if they change...

Analog - currently in analog.c - may not matter in this case.

PWM - Need to update table in pwm.c... Sometimes wish we would have defined a more complete table of pins... i.e. this could have
been combined with the pin information in digital.c... (Probably weak linkage)

SerialX - could copy the files for each one like HardwareSerial2.cpp and edit, as it only contains the definitions. HOWEVER, they are setup as individual files and the like knowing that cores build using archive file, which only brings in the object if someone references it. So if you don't use Serial2, its object and buffers are not brought in to your sketch... If however you define all of them in the variant or the like, all of them will be included in your sketch...

XBar Table - in HardwareSerial.cpp - (probably weak linkage)

FlexIO - in library flexio_t4 in the .cpp file - probably see about weak linkage. Will experiment. The good part is I own the library ;)

SPI -

Wire -

<And lots of others... >
 
fixed in library - and local copy of variants.h - planning on making more changes so will leave it for now
What happened to: examples\CapReadSDRAM\CapReadSDRAM.ino? - tons of diffs - anything other than whitespace?
Have been doing the IDE Ctrl+T for uniform formatting - it changes things - consistently - drops the '*' from start of multi quote lines it seems.
but last update over written with stuff all over -
 
What happened to: examples\CapReadSDRAM\CapReadSDRAM.ino? - tons of diffs - anything other than whitespace?
Good question - I didn't touch it - i pulled the changes the pushed my changes?

EDIT: This is what I am seeing in github desktop
1705871465752.png
 
This is whats there now - unless you forgot to push changes:

Code:
#include "SDRAM_t4.h"
uint32_t readRepeat = 3;  // Writes once to Test memory, will repeat Reads and Test compare 'readRepeat' times
uint32_t readFixed = 1; // start loop and run only Fixed Patterns once
uint32_t speed = 166; // 133, 166, 198, 221
/********************************************************************
   Example that does extensive pattern write and (re)Read to test memory integrity:

   This example does direct memory addressing from memory_begin to memory_end
   Lists of patterns Random and Fixed that are written and then Read and tested to be as expected

   Successful output below, if a progress indicator "#" or "." shows "F" that test pattern failed.
   If built with Dual Serial a second SerMon can show added in progress output

   Expected Output:
     --- START 57 test patterns ------ with 3 reReads ... wait ...
   #############............................................
   No Errors. All memory tests passed :-)    (time 93.38 secs)
 *****************************************************************************/

// constructor for SDRAM - though here the memory pool is accessed by direct address
SDRAM_t4 sdram;
uint size = 32;  // SDRAM 32MB Size
uint32_t *memory_begin = (uint32_t *)(0x80000000);
uint32_t *memory_end = (uint32_t *)(0x80000000 + size * 1048576);

uint32_t check_lfsr_pattern(uint32_t seed);
uint32_t check_fixed_pattern(uint32_t pattern);
uint32_t doTest(uint do_one);

// These are the tested PsuedoRandom and FIXED patterns loists to be tested:
static uint32_t lfsrPatt[44] = { 2976674124ul, 1438200953ul, 3413783263ul, 1900517911ul, 1227909400ul, 276562754ul, 146878114ul, 615545407ul, 110497896ul, 74539250ul, 4197336575ul, 2280382233ul, 542894183ul, 3978544245ul, 2315909796ul, 3736286001ul, 2876690683ul, 215559886ul, 539179291ul, 537678650ul, 4001405270ul, 2169216599ul, 4036891097ul, 1535452389ul, 2959727213ul, 4219363395ul, 1036929753ul, 2125248865ul, 3177905864ul, 2399307098ul, 3847634607ul, 27467969ul, 520563506ul, 381313790ul, 4174769276ul, 3932189449ul, 4079717394ul, 868357076ul, 2474062993ul, 1502682190ul, 2471230478ul, 85016565ul, 1427530695ul, 1100533073ul };
const uint32_t lfsrCnt = sizeof(lfsrPatt) / sizeof(lfsrPatt[0]);
static uint32_t fixPatt[13] = { 0x5A698421, 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF, 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000, 0xFFFFFFFF, 0x00000000 };
const uint32_t fixPCnt = sizeof(fixPatt) / sizeof(fixPatt[0]);

void loop() {
  uint32_t totErrs = 0;

  static bool inputSer = true;
  char chIn;
  while (Serial.available()) {  // send usb TO REPEAT TEST
    chIn = Serial.read();
    if ( '1' == chIn ) readRepeat = 100;
    if ( 'K' == chIn ) readRepeat = 1000;
    if ( 's' == chIn ) readRepeat = 3; // Fast test
    inputSer = true;
  }
  if (inputSer && size > 0) {
    uint32_t testmsec;
    uint32_t testCnt = fixPCnt;
    if ( 0 == readFixed ) testCnt += lfsrCnt;

    Serial.printf("\n  --- START %u test patterns ------ with %u reReads ... wait ...\n", testCnt, readRepeat);
#ifdef USB_DUAL_SERIAL
    SerialUSB1.printf("\n  --- START %u test patterns ------ with %u reReads ... wait ...\n", testCnt, readRepeat);
#endif

    testmsec = millis();
    for (uint ii = 0; ii < fixPCnt; ii++) {
      digitalToggle(13);
#ifdef USB_DUAL_SERIAL
      SerialUSB1.printf("\n\t>>**>> FixedPatt(%u) pattern %08X with readRepeat %u  ...", ii, fixPatt[ii], readRepeat);
#endif
      totErrs += check_fixed_pattern(fixPatt[ii]);
    }
    for (uint ii = 0; 0==readFixed && ii < lfsrCnt; ii++) {
      digitalToggle(13);
#ifdef USB_DUAL_SERIAL
      SerialUSB1.printf("\n\t>>**>> PseudoRand(%u) Seed %u with readRepeat %u  ...", ii, lfsrPatt[ii], readRepeat);
#endif
      totErrs += check_lfsr_pattern(lfsrPatt[ii]);
    }
    testmsec = millis() - testmsec;
    if (0 == totErrs)
      Serial.printf("\nNo Errors. All memory tests passed :-)\t(time %.2f secs)\n", testmsec / 1000.0);
    else
      Serial.printf("\nTotal errors found %u\t(time %.2f secs)\n", totErrs, testmsec / 1000.0);
    Serial.print("\n Send to restart. '1' or 'k' for 100 or 1,000 reReads and 's' for start fast test.");
#ifdef USB_DUAL_SERIAL
    SerialUSB1.printf("\nDone with total errors found %u\t(time %.2f secs)\n", totErrs, testmsec / 1000.0);
#endif
  }
  digitalWrite(13, HIGH);
  if ( 1 == readFixed ) {
    readFixed = 0;
    inputSer = true;
  }
  else {
    inputSer = false;
  }
}

void setup() {
  while (!Serial)
    ;  // wait
  pinMode(13, OUTPUT);
  if (CrashReport) Serial.print(CrashReport);

  /**********************************************************
       sdram.begin initializes the available SDRAM Module
        Here >> begin(SIZE, SPEED, NOCAP);:
       begin(32, 166, 1);
       See library readme for more info.
     *********************************************************/
  if (sdram.begin(size, speed, 1)) {
    Serial.print("\n\tSUCCESS sdram.init()\n");
    Serial.print("\n\tSEND USB to repeat test after completion");
    Serial.print("\n\tSend '1' for 100 or 'k' gives 1K read repeats and 's' returns to start short test value.");
    Serial.print("\n\tProgress:: '#'=fixed pattern, '.'=PsuedoRand patterns, and 'F' shows Failed test pattern");
    Serial.print("\n\tIf built with DUAL Serial second SerMon will show details.\n\n");
  }
  Serial.printf("Compile Time:: " __FILE__ " " __DATE__ " " __TIME__ "\n");
  Serial.printf("EXTMEM Memory Test, %d Mbyte\t", size);
  Serial.printf("begin, %08X \t", memory_begin);
  Serial.printf("end, %08X \n", memory_end);
  readFixed = 1; // start loop and run only Fixed Patterns once
}

// fill the Low half of RAM with a pseudo-random sequence, then check it against copy made to Upper half
// Test: Write same Psuedo Random values to Lower and Upper (16MB of 32MB SDRAM)
//
uint32_t check_lfsr_pattern(uint32_t seed) {
  volatile uint32_t *p;
  uint32_t testMsec;
  uint32_t reg;
  uint32_t MemResSum, MemRes;
  char cRes = '.';

  reg = seed;
  testMsec = micros();
  for (p = memory_begin; p < memory_end; p++) {
    *p = reg;
    for (int i = 0; i < 3; i++) {
      if (reg & 1) {
        reg >>= 1;
        reg ^= 0x7A5BC2E3;
      } else {
        reg >>= 1;
      }
    }
  }
  MemResSum = 0;
  MemRes = 0;

  for (uint32_t ii = 0; ii < readRepeat; ii++) {
    // validate the expected value are still read as expected
    arm_dcache_flush_delete((void *)memory_begin, (uint32_t)memory_end - (uint32_t)memory_begin);
    reg = seed;
    for (p = memory_begin; p < memory_end; p++) {
      if (*p != reg) MemRes++;
      for (int i = 0; i < 3; i++) {
        if (reg & 1) {
          reg >>= 1;
          reg ^= 0x7A5BC2E3;
        } else {
          reg >>= 1;
        }
      }
    }
    MemResSum += MemRes;
  }

  testMsec = micros() - testMsec;
  if (0 != MemResSum) {
    cRes = 'F';
#ifdef USB_DUAL_SERIAL
    SerialUSB1.printf("\n\tFail pseuRand seq. not same with seed=%u", seed);
#endif
  }
  Serial.printf("%c", cRes);
#ifdef USB_DUAL_SERIAL
  SerialUSB1.printf("\nTest pseudo-random sequence Compare time secs %.2f with \tError Cnt %u\n", testMsec / 1000000.0, MemResSum);
#endif
  return MemResSum;
}

// fill the entire RAM with a fixed pattern, then check it
uint32_t check_fixed_pattern(uint32_t pattern) {
  volatile uint32_t *p;
  uint32_t testMsec;
  uint32_t MemResSum = 0, MemRes;
  char cRes = '#';

  testMsec = micros();
  for (p = memory_begin; p < memory_end; p++) {
    *p = pattern;
  }
  arm_dcache_flush_delete((void *)memory_begin,
                          (uint32_t)memory_end - (uint32_t)memory_begin);
  for (uint ii = 0; ii < readRepeat; ii++) {
    for (p = memory_begin; p < memory_end; p++) {
      uint32_t actual = *p;
      if (actual != pattern) MemRes++;
    }
    MemResSum += MemRes;
  }
  testMsec = micros() - testMsec;
  if (0 != MemResSum) {
    cRes = 'F';
#ifdef USB_DUAL_SERIAL
    SerialUSB1.printf("\n\tFail fixed pattern not same with seed=%u", pattern);
#endif
  }
  Serial.printf("%c", cRes);
#ifdef USB_DUAL_SERIAL
  SerialUSB1.printf("\nTest fixed pattern Compare time secs %.2f with \tError Cnt %u\n", testMsec / 1000000.0, MemResSum);
#endif
  return MemResSum;
}
 
Nope - this was pushed just before posting 12 minutes ago:
@@ -2,6 +2,7 @@
22

uint32_t readRepeat = 3; // Writes once to Test memory, will repeat Reads and Test compare 'readRepeat' times
33

uint32_t readFixed = 1; // start loop and run only Fixed Patterns once
44

uint32_t speed = 166; // 133, 166, 198, 221
5
+
uint32_t noCap = false; // if a capacitor is present on pin EMC_39
56
Show on the web too - 19 mins ago
#include "SDRAM_t4.h" uint32_t readRepeat = 3; // Writes once to Test memory, will repeat Reads and Test compare 'readRepeat' times uint32_t readFixed = 1; // start loop and run only Fixed Patterns once uint32_t speed = 166; // 133, 166, 198, 221 uint32_t noCap = false; // if a capacitor is present on pin EMC_39
 
Last edited:
No clue what went wrong we must have pushed close to same time again. Can you push your copy. I didn’t touch your example so something went wrong with GitHub. Desktop won’t let me push until I pull any previous changes.
 
Github - noted before - has not done us any favors on this - not sure why that is?
Windows Desktop version in use here and it is in sync with the www.github copy?
 
@mjs513 Github example Updated
EXTMEM Memory Test, 32 Mbyte SDRAM speed 166 Mhz begin@ 80000000 end@ 82000000
--- START 13 test patterns ------ with 3 reReads ... wait ...
#############
No Errors. All memory tests passed :) (time 12.70 secs)
--- START 57 test patterns ------ with 3 reReads ... wait ...
#############............................................
No Errors. All memory tests passed :) (time 93.38 secs)
Send to restart. '1' or 'k' for 100 or 1,000 reReads and 's' for start fast test.
INO starts:
#include "SDRAM_t4.h"
uint32_t readRepeat = 3; // Writes once to Test memory, will repeat Reads and Test compare 'readRepeat' times
uint32_t readFixed = 1; // start loop and run only Fixed Patterns once
uint32_t speed = 166; // 133, 166, 198, 221
uint32_t noCap = true; // "false" if a capacitor is present on pin EMC_39
...
Noted that wrong NoCap value gives errors like this:
--- START 57 test patterns ------ with 3 reReads ... wait ...
#############FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Total errors found 2214590452 (time 93.38 secs)

opps: meant to also print the F_CPU_ACTUAL in case edited for clock change
 
Back
Top