chegewara / EspTinyUSB

ESP32S2 native USB library. Implemented few common classes, like MIDI, CDC, HID or DFU (update).
MIT License
473 stars 70 forks source link

sd_msc bad usb data transfer with systematic error #118

Closed Steffen-W closed 1 year ago

Steffen-W commented 1 year ago

Hi,

I have currently played the sample code sd_msc.ino on an ESP32-S2 and connected it directly to a Linux coputer via USB. My problem is that the data transfer in both directions from computer and SD cart is error related.

I have tested with a text file. When the microcontroller writes the file itself and reads it again at some point, no errors occur. But when the USB connection is used for data transfer, errors occur.

The error is as follows: The first 512 characters are transferred correctly. The following 7*512 characters are transmitted as \0. This is repeated again and is reproducible in both data transfer directions.

I suspect an error in the code. Can you give me a hint where to look?

chegewara commented 1 year ago

I remember it was reported earlier, but i dont remember where (forum or esp32-arduino). This code is assuming sector size 512 bytes, and you probably do have 4096. The problem is with arduino SD library, which is not providing good API to handle this: https://github.com/chegewara/EspTinyUSB/blob/master/src/device/msc/sdcard.cpp#L63-L78

Maybe i should use different API, but ive been trying to make library compatible with SD class to let access also from code to sd card.

Steffen-W commented 1 year ago

Hi thanks for the tip. I think that this could also be the problem. The buffer size is also not taken into account.

My solution idea is the following:

int32_t onRead(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize)
{
    (void)lun;
    for (int i = 0; m_parent->block_size * i < bufsize; i++)
            SD.readRAW((uint8_t *)buffer, lba + i);

    return bufsize;
}

only sadly, the device is then no longer identified ;)

Steffen-W commented 1 year ago

https://github.com/chegewara/EspTinyUSB/blob/master/src/device/msc/sdcard.cpp#L63-L78

The following solution works very well for me. The problem is completely solved with it.

int32_t onRead(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize)
{
    log_v("default onread lba (%u) bufsize (%u)", lba, bufsize);
    (void)lun;
    for (int i = 0; m_parent->block_size * i < bufsize; i++)
    {
        SD.readRAW((uint8_t *)buffer + m_parent->block_size * i, lba + i);
    }

    return bufsize;
}
int32_t onWrite(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize)
{
    log_v("default onwrite lba (%u) bufsize (%u)", lba, bufsize);
    (void)lun;
    for (int i = 0; m_parent->block_size * i < bufsize; i++)
        SD.writeRAW((uint8_t *)buffer + m_parent->block_size * i, lba + i);

    return bufsize;
}