Problem with SDRAM on Portenta H7, red light blinks 4 long 4 short

I'm new to Arduino and am encountering an issue with my Arduino Portenta H7. I've written a sketch to sample analog signals from three sensors at a 25kHz sampling rate, using external SDRAM for data storage. The sketch manages dynamic memory allocation to store the sensor data in arrays until a specified data point count (data_len) is reached, and checks for allocation errors, stopping the program if any occur.

My problem arises when executing the free_memory function, where the program crashes, indicated by a red light blinking in a pattern of 4 long and 4 short blinks.

I've tried freeing each buffer individually, but the issue persists. Here's my code:

#include "Arduino_PortentaBreakout.h"
#include "SDRAM.h"

REDIRECT_STDOUT_TO(Serial);

// Constants for ADC warm-up and sampling interval
const int ADC_WARMUP_READS = 1000;  // Number of reads to stabilize ADC readings
const long interval = 40;           // Sampling interval in microseconds (40 microseconds for 25kHz sampling rate)

// Reference voltage
const float VREF = 3.10;  // Reference voltage in volts

// Definitions of analog pins used
const breakoutPin PHASE_1 = ANALOG_A0;
const breakoutPin PHASE_2 = ANALOG_A1;
const breakoutPin CURRENT = ANALOG_A3;

// Array containing the analog pins for easy access
const breakoutPin PIN_Array[] = { PHASE_1, PHASE_2, CURRENT };
const char* PIN_Names[] = { "PHASE_1", "PHASE_2", "CURRENT" };

// Number of data points to sample
const long data_len = 250000;
// Buffers to store sampled values
uint16_t* data_PHASE_1;
uint16_t* data_PHASE_2;
uint16_t* data_CURRENT;

// Function to fill data arrays
void fillArrays() {
    // ADC warm-up to stabilize the sensor signal
    for (int i = 0; i < ADC_WARMUP_READS; i++) {
        Breakout.analogRead(PHASE_1);
        Breakout.analogRead(PHASE_2);
        Breakout.analogRead(CURRENT);
    }

    // Time preparation to measure buffer fill duration
    unsigned long timeStart = micros();
    long i = 0;
    unsigned long previousMicros = 0;
    while (i < data_len) {
        unsigned long currentMicros = micros();
        if (currentMicros - previousMicros >= interval) {
            previousMicros = currentMicros;
            data_PHASE_1[i] = Breakout.analogRead(PHASE_1);
            data_PHASE_2[i] = Breakout.analogRead(PHASE_2);
            data_CURRENT[i] = Breakout.analogRead(CURRENT);
            i++;
        }
    }
    unsigned long timeEnd = micros();
    Serial.print("Total loops completed: ");
    Serial.println(i);
}

void free_memory() {
    SDRAM.free(data_PHASE_1); data_PHASE_1 = NULL;
    SDRAM.free(data_PHASE_2); data_PHASE_2 = NULL;
    SDRAM.free(data_CURRENT); data_CURRENT = NULL;
}

void setup() {
    Serial.begin(115200);
    while (!Serial);  // Wait for the serial connection to be established

    analogReadResolution(16);
    SDRAM.begin();

    data_PHASE_1 = (uint16_t*)SDRAM.malloc(data_len * sizeof(uint16_t));
    data_PHASE_2 = (uint16_t*)SDRAM.malloc(data_len * sizeof(uint16_t));
    data_CURRENT = (uint16_t*)SDRAM.malloc(data_len * sizeof(uint16_t));

    if (data_PHASE_1 == NULL || data_PHASE_2 == NULL || data_CURRENT == NULL) {
        Serial.println("Error: Failed to allocate memory, halting execution.");
        while (1);  // Halt further execution
    }

    if (SDRAM.test()) {
        Serial.println("SDRAM is completely functional");
    }
}

void loop() {
    fillArrays();
    for (int i = 0; i < 3; ++i) {
        delay(2000);
        const char* PIN_NAME = PIN_Names[i];
        uint16_t* data = (i == 0) ? data_PHASE_1 : (i == 1) ? data_PHASE_2 : data_CURRENT;

        Serial.print("Transmitting data for ");
        Serial.println(PIN_NAME);
        for (long j = 0; j < data_len; j++) {
            Serial.println(data[j]);
        }
        Serial.print("End of data transmission for ");
        Serial.println(PIN_NAME);
    }
    free_memory();
    Serial.println("Click on reset to restart.");
    while (1);  // Pause 
}

Getting lucky on Stack Overflow?

Any blinking red LEDs mean a firmware crash or out-of-bounds read/write error.

I couldn’t find anything helpful on Stack Overflow. However, I discovered a workaround that resolved the issue, even though I don’t fully understand why it worked. Essentially, I removed a specific part from the setup function, and that solved the problem.

if (SDRAM.test()) {
        Serial.println("SDRAM is completely functional");
    }