EspTinyUSB icon indicating copy to clipboard operation
EspTinyUSB copied to clipboard

sd_msc bad usb data transfer with systematic error

Open Steffen-W opened this issue 1 year ago • 3 comments

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?

Steffen-W avatar Sep 14 '22 08:09 Steffen-W

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.

chegewara avatar Sep 14 '22 09:09 chegewara

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 avatar Sep 14 '22 14:09 Steffen-W

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;
}

Steffen-W avatar Sep 14 '22 14:09 Steffen-W