USBMSC writing 1st sector data to SD, then writing zeros

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
fcohen
 
Posts: 53
Joined: Mon Jan 06, 2014 5:14 am

USBMSC writing 1st sector data to SD, then writing zeros

Post by fcohen »

I wrote an Arduino sketch to mount a SD card connected to an ESP32-S3 over SPI as a USB MSC volume. This uses the ESP32 SD library (and not SdFat, nor the Adafruit branch of SdFat). I plug the ESP32-S3 USB into my Mac laptop (MacOS Monterey 12.5) and the volume appears mounted correctly. I copy a text file to the volume, the original file is 2,526 bytes. The file on the ESP32 volume is also 2,526 bytes. However, only the first 512 bytes are copied from the original file, the additional bytes are zeroes.

I am reading and writing the data using:
return SD.writeRAW( (uint8_t*) buffer, lba) ? bufsize : -1 ;
and
return SD.readRAW( (uint8_t*) buffer, lba) ? bufsize : -1 ;

Perhaps I should be returning bufsize/512?

Wiring is at:
https://github.com/frankcohen/Reflectio ... -Guide.jpg

Sketch I wrote is:
[Codebox]#include "SD.h"
#include "SPI.h"
#include "USB.h"
#include "USBMSC.h"

USBMSC msc;

#define NAND_SPI_MOSI 11
#define NAND_SPI_MISO 13
#define NAND_SPI_SCK 12
#define NAND_SPI_CS 42

bool sd_changed = false;
bool sd_inited = false;

static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
{
Serial.printf("MSC WRITE: lba: %u, offset: %u, bufsize: %u\n", lba, offset, bufsize);
return SD.writeRAW( (uint8_t*) buffer, lba) ? bufsize : -1 ;
}

static int32_t onRead(uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
{
Serial.printf("MSC READ: lba: %u, offset: %u, bufsize: %u\n", lba, offset, bufsize);
return SD.readRAW( (uint8_t*) buffer, lba) ? bufsize : -1 ;
}

static bool onStartStop(uint8_t power_condition, bool start, bool load_eject){
Serial.printf("MSC START/STOP: power: %u, start: %u, eject: %u\n", power_condition, start, load_eject);
return true;
}

void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
long time = millis();
while (!Serial && ( millis() < time + 5000) ); // wait up to 5 seconds for Arduino Serial Monitor
Serial.println("");
Serial.println("MSC research for Hoober");

pinMode(NAND_SPI_CS, OUTPUT);
digitalWrite(NAND_SPI_CS, LOW);

static SPIClass* spi = NULL;
spi = new SPIClass(FSPI);
spi->begin(NAND_SPI_SCK, NAND_SPI_MISO, NAND_SPI_MOSI, NAND_SPI_CS);

if ( !SD.begin( NAND_SPI_CS, *spi, 20000000 ) )
{
Serial.println(F("Storage initialization failed"));
Serial.println("Stopped");
while(1);
}
else
{
Serial.println(F("Storage initialization success"));
}

Serial.print( "card size = " );
Serial.print( SD.cardSize() );
Serial.print( ", numSectors = " );
Serial.print( SD.numSectors() );
Serial.print( ", bytes per sector = " );
Serial.print( SD.cardSize() / SD.numSectors() );
Serial.print( ", total bytes = " );
Serial.print( SD.totalBytes() );
Serial.print( ", usedBytes = " );
Serial.print( SD.usedBytes() );

Serial.print(", SD Card Type: ");
if(SD.cardType() == CARD_MMC){
Serial.println("MMC");
} else if(SD.cardType() == CARD_SD){
Serial.println("SDSC");
} else if(SD.cardType() == CARD_SDHC){
Serial.println("SDHC");
} else if(SD.cardType() == CARD_NONE){
Serial.println("No SD card attached");
}else {
Serial.println("UNKNOWN");
}

msc.vendorID("REF32");
msc.productID("USB_MSC");
msc.productRevision("1.0");
msc.onRead(onRead);
msc.onWrite(onWrite);
msc.onStartStop(onStartStop);
msc.mediaPresent(true);
msc.begin(SD.numSectors(), SD.cardSize() / SD.numSectors() );

USB.begin();

sd_changed = true; // to print contents initially
}

void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\n", dirname);

File root = fs.open(dirname);
if(!root){
Serial.println("Failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println("Not a directory");
return;
}

File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
Serial.println(file.name());
if(levels){
listDir(fs, file.path(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}

void loop() {
if ( sd_changed )
{
Serial.println("SD contents:");
listDir(SD, "/", 0);
Serial.println();
sd_changed = false;
}

delay(1000); // refresh every 1 second
}[/Codebox]

Serial Monitor shows these log entries:
[Codebox]. . .
MSC READ: lba: 432, offset: 0, bufsize: 512
MSC READ: lba: 432, offset: 0, bufsize: 4096
MSC READ: lba: 440, offset: 0, bufsize: 4096
MSC WRITE: lba: 432, offset: 0, bufsize: 4096
MSC WRITE: lba: 440, offset: 0, bufsize: 4096
MSC READ: lba: 448, offset: 0, bufsize: 4096
MSC READ: lba: 456, offset: 0, bufsize: 4096
MSC WRITE: lba: 448, offset: 0, bufsize: 4096
MSC WRITE: lba: 456, offset: 0, bufsize: 4096
MSC READ: lba: 432, offset: 0, bufsize: 4096
MSC READ: lba: 440, offset: 0, bufsize: 4096
MSC WRITE: lba: 432, offset: 0, bufsize: 4096 . . .[/Codebox]

Locked
Please be positive and constructive with your questions and comments.

Return to “Feather - Adafruit's lightweight platform”