STM32F405 SD DMA only works once, no matter what
Hello,
I am currently trying to get an Adafruit Feather STM32F405 board to write to files on an SD card using DMA. I'm using CubeIDE, not STM32duino, and I have tried DMA configurations with both a single stream and two streams (one RX and one TX). No matter how I have the hardware configured, I am unable to ever complete more than one operation with the SD card.
For example, if I try writing or reading blocks with the raw HAL_SD_ReadBlocks_DMA or WriteBlocks_DMA function, only one call will ever succeed. All the following calls will return an error, usually that the "card is not ready". The same happens when I try to use FatFs: I can open a file (including creating it if necessary), but I can never write to it.
I need SD DMA because I'm using ADC DMA to capture multiple channels at high speed, and I think using polling mode interferes with the ADC HalfCplt and Cplt interrupts.
I do know that the SD card and SD peripheral work, because I can configure CubeIDE to generate code for polling mode.
This is my DMA stream configuration. I have also tried using a single stream and modifying the BSP code (for FatFs) to change the direction of the streams before calling Read/Write_DMA() functions, with no effect. I have the clock divider bypass, the clock power save, and the hardware flow control on the peripheral all disabled, and my clock divide factor is set to 8 (which seems to be a reliable value based on my own polling mode reliability tests). The pins themselves are configured pull-up at medium speed.
What am I doing wrong? I have seen numerous examples where SD DMA "just works", and yet I have had no success ever.
This is the FatFs code I'm trying to run which always fails at the f_write() call (blink() is a function I wrote that just blinks the built-in LED on the Feather board, because I haven't gotten USB set up yet):
FATFS fs = {0};
FRESULT res;
FIL fil;
UINT written;
res = f_mount(&fs, "", 0);
if (res != FR_OK) {
blink(100);
}
res = f_open(&fil, "speed.bin", FA_WRITE|FA_CREATE_ALWAYS);
if (res != FR_OK) {
blink(500);
}
const char data[512] = {0};
res = f_write(&fil, data, sizeof(data), &written);
if (res != FR_OK) {
// it's blinking 1 sec, and error 1 means FatFs error "low level disk error"
blink(res*1000);
}
if (written != sizeof(data)) {
blink(1500);
}
res = f_sync(&fil);
if (res != FR_OK) {
blink(2000);
}
res = f_close(&fil);
if (res != FR_OK) {
blink(3000);
}