Page 1 of 1

SD card write errors with hardware timer?

Posted: Thu May 27, 2021 1:18 pm
by Bambo
Hi, i'm trying to write a program that must write to the SD card 30000 bytes at a time, while the hardware timer collects samples at 16,000Hz. The problem is that the SD card write function returns an error when writing. But it seems that the Sd card fails to write when its interrupted? Does anyone know what to do? Thanks!

Board: STM32L452RE

Here's is the code:

Code: Select all

#include "PeripheralPins.h"
#include "Sysclock_Config.h"

#include <STM32SD.h>
#include <HardwareTimer.h>

#include "stm32l4xx_hal.h"
#include "stm32l4xx_hal_sd.h"

#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line) 
{
	/* Infinite loop /
	/ Use GDB to find out why we're here */
	while (1);
}
#endif

void _Error_Handler(const char* filename, int line)
{
    Serial2.println(F("*** [ERROR HANDLED] ***"));
    Serial2.printf("%s\r\n", filename);
    Serial2.printf("%i\r\n", line);
}

uint32_t SD_CMD = PD2;
uint32_t SD_CLK = PC12;
uint32_t SD_D3 = PC11;
uint32_t SD_D2 = PC10;
uint32_t SD_D1 = PC9;
uint32_t SD_D0 = PC8;

uint32_t SD1 = PA15;

uint32_t DEBUG_RX = PA3;
uint32_t DEBUG_TX = PA2;

Sd2Card card;
SdFatFs fatFs; 
File testFile;

uint8_t dataStack[30000] = { 0 };
int dataStackTop = 0;

HardwareTimer timer(TIM2);

void setup() 
{
	Serial2.begin(115200);  // print starting notification
    Serial2.println("Started");

    pinMode(SD1, OUTPUT); // turn the sd card on
    digitalWrite(SD1, HIGH);

    delay(5000); // wait for the debugger

    Serial2.print("Initializing SD card...");

    if (!SD.begin()) // start the Sd card library
    {
        Serial2.println("initialization failed!");

        while (1) {};
    }

    testFile = SD.open("T.TXT", FILE_WRITE); // create a new file called T.txt

    timer.setMode(1, TIMER_OUTPUT_COMPARE, NC); // setup a 16,000Hz timer to simulate sampling an ADC
    timer.setOverflow(16000, HERTZ_FORMAT);
    timer.detachInterrupt();
    timer.attachInterrupt(timerCallback);
    timer.resume();
}

void timerCallback()
{
    dataStack[dataStackTop] = 1; // push 3 bytes to the stack.
    dataStackTop++;
    dataStack[dataStackTop] = 1;
    dataStackTop++;
    dataStack[dataStackTop] = 1;
    dataStackTop++;

    if (dataStackTop == 30000) // stack is full reset the top to overwrite.
    {
        dataStackTop = 0;
    }
}

void loop()
{
    size_t bytes_wrote;

    bytes_wrote = testFile.write(dataStack, 30000); // empty the data stack to the sd card.

    if (bytes_wrote == 0) // if the write command failed to write any data then print an error message.
    {
        Serial2.println("Error writing to the SD card.");
        Serial2.flush();
        while (1) {}
    }
}
Notes:
I have found that changing the SD write size to 512 bytes resolves the error. And also if i remove the hardware timer then the error is resolved and the write() can write more than 512 bytes. Perhaps the interrupt is breaking the SD card if it is raised while a write is being performed?

Re: SD card write errors with hardware timer?

Posted: Thu May 27, 2021 3:47 pm
by Bambo
Looks like i must try to use DMA instead of polling.

Does anyone know how to switch STM32SD to DMA mode?

Re: SD card write errors with hardware timer?

Posted: Fri May 28, 2021 4:30 pm
by ag123
SD cards can take like 200 milliseconds to write some stuff (say a 512 bytes sector), u'd need buffers to allow time for that.