greiman / SdFat-beta

Beta SdFat for test of new features

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Writing volatile buffers to the SD card error

JanIIISobieski opened this issue · comments

I have a volatile buffer of size 4096 defined as: DMAMEM static volatile uint16_t buffer[4096] (from example code in the <ADC.h> library)

To test, I wrote to each element of the buffer its index, and then tried to pass the pointer to the buffer to the SD card to write and then read back from the file to see what was written. I cannot get the original buffer to agree with what was read. What was written to the SD card was much different than the buffer that was passed.

Normal arrays (uint16_t normal_buffer[4096]) work fine, so I suspect it has something to do with the volatile nature of the buffer.

I'm using a Teensy 4.0.

Here is the program I was using:

#include "SdFat.h"

#ifndef SDCARD_SS_PIN
const uint8_t SD_CS_PIN = SS;
#else  // SDCARD_SS_PIN
// Assume built-in SD is used.
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
#endif  // SDCARD_SS_PIN

SdFs sd;
FsFile file;

uint32_t buffer_size = 4096;
DMAMEM static volatile uint16_t __attribute__((aligned(16))) dma_adc_buff1[4096];

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);

    Serial.begin(9600);
    while (!Serial) {
        delay(100);
    }

    if (!sd.begin(SdioConfig(DMA_SDIO))) { 
        Serial.println("Could not start SD");
    } 

    uint16_t buffer_read[buffer_size] = {0};

    for (uint16_t i = 0; i < buffer_size; i++) {
    dma_adc_buff1[i] = i;
    }

    size_t written_size = 2*buffer_size;

    if (dma_adc_buff1[0] == 0 && dma_adc_buff1[10] == 10)
        Serial.println("Successful initalization of DMA Buffer 1");
    else
        Serial.println("Bad initailization of DMA Buffer 1");
    
    if (!file.open("test_sd_write_buffer.bin", O_RDWR | O_CREAT | O_TRUNC))
        Serial.println("Could not open file");

    //write the vectors on the SD card
    if (written_size != file.write((void *)dma_adc_buff1, written_size))
        Serial.println("Could not write first block");

    if (!file.close())
        Serial.println("Could not close file");

    if (!file.open("test_sd_write_buffer.bin", O_RDONLY))
        Serial.println("Could not reopen file");

    //read the vector back from the SD card
    if (written_size != file.read(buffer_read, written_size))
        Serial.println("Unsuccessful read of first block from SD card");
    
    if (buffer_read[1] == dma_adc_buff1[1]) {
        Serial.println("Looks like file was written to successfully");
    }
    else
        Serial.println("Error in writing and then reading from file");
        Serial.println("Intended: " + String((uint16_t)dma_adc_buff1[1]));
        Serial.println("Read: " + String((uint16_t)buffer_read[1]));
        Serial.println("1st : " + String((uint16_t)buffer_read[0]));
    
    file.close();
}

void loop() {
    delay(1000);
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

I didn't see this post earlier. Did you solve the problem?

I ran your program with with the current release version of SdFat on a Teensy 4.1.

I modified the final part of the test like this:

   //read the vector back from the SD card
    if (written_size != file.read(buffer_read, written_size))
        Serial.println("Unsuccessful read of first block from SD card");

   for (uint16_t i = 0; i < buffer_size; i++) {
      if (buffer_read[i] != dma_adc_buff1[i]) {
        Serial.println("cmp error: " + String((uint16_t)i));
        break;
      }
    }
    if (buffer_read[1] == dma_adc_buff1[1]) {
        Serial.println("Looks like file was written to successfully");
    }
    else
   {
        Serial.println("Error in writing and then reading from file");
        Serial.println("Intended: " + String((uint16_t)dma_adc_buff1[1]));
        Serial.println("Read: " + String((uint16_t)buffer_read[1]));
        Serial.println("1st : " + String((uint16_t)buffer_read[0]));
    }
    file.close();

Here is the output:

Successful initalization of DMA Buffer 1
Looks like file was written to successfully