From eaa9bfdaa571ea2b2ef54b50ec5bac5b9d7a28da Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 30 May 2025 19:59:27 +0700 Subject: [PATCH 1/3] update msc_sdfat.ino and msc_external_flash_sdcard.ino to - use SDIO (pio) for rp2040/rp2350 - remove printing flash/sdcard contents to Serial since it conflict with host, which can cause conflict in spi/sdio transport and/or correupt cache,sector --- .../msc_external_flash_sdcard.ino | 136 +++++------------- examples/MassStorage/msc_sdfat/msc_sdfat.ino | 108 +++++--------- 2 files changed, 67 insertions(+), 177 deletions(-) diff --git a/examples/MassStorage/msc_external_flash_sdcard/msc_external_flash_sdcard.ino b/examples/MassStorage/msc_external_flash_sdcard/msc_external_flash_sdcard.ino index 4b7b6e1..e61a163 100644 --- a/examples/MassStorage/msc_external_flash_sdcard/msc_external_flash_sdcard.ino +++ b/examples/MassStorage/msc_external_flash_sdcard/msc_external_flash_sdcard.ino @@ -33,43 +33,54 @@ // for flashTransport definition #include "flash_config.h" - Adafruit_SPIFlash flash(&flashTransport); -// External Flash File system -FatVolume fatfs; - //--------------------------------------------------------------------+ // SDCard Config //--------------------------------------------------------------------+ - #if defined(ARDUINO_PYPORTAL_M4) || defined(ARDUINO_PYPORTAL_M4_TITANO) // PyPortal has on-board card reader #define SDCARD_CS 32 #define SDCARD_DETECT 33 #define SDCARD_DETECT_ACTIVE HIGH + #elif defined(ARDUINO_ADAFRUIT_METRO_RP2040) - #define SDCARD_CS 23 + #define SDIO_CLK_PIN 18 + #define SDIO_CMD_PIN 19 // MOSI + #define SDIO_DAT0_PIN 20 // DAT1: 21, DAT2: 22, DAT3: 23 + #define SDCARD_DETECT 15 #define SDCARD_DETECT_ACTIVE LOW + +#elif defined(ARDUINO_ADAFRUIT_METRO_RP2350) + // Note: not working yet (need troubleshoot later) + #define SDIO_CLK_PIN 34 + #define SDIO_CMD_PIN 35 // MOSI + #define SDIO_DAT0_PIN 36 // DAT1: 37, DAT2: 38, DAT3: 39 + + #define SDCARD_DETECT 40 + #define SDCARD_DETECT_ACTIVE LOW + #else + // Use SPI, no detect #define SDCARD_CS 10 - // no detect #endif -// SDCard File system +#if defined(SDIO_CLK_PIN) && defined(SDIO_CMD_PIN) && defined(SDIO_DAT0_PIN) + #define SD_CONFIG SdioConfig(SDIO_CLK_PIN, SDIO_CMD_PIN, SDIO_DAT0_PIN) +#else + #define SD_CONFIG SdSpiConfig(SDCARD_CS, SHARED_SPI, SD_SCK_MHZ(50)) +#endif + +// File system on SD Card SdFat sd; // USB Mass Storage object Adafruit_USBD_MSC usb_msc; // Set to true when PC write to flash -bool sd_changed = false; bool sd_inited = false; -bool flash_formatted = false; -bool flash_changed = false; - // the setup function runs once when you press reset or power the board void setup() { #ifdef LED_BUILTIN @@ -98,14 +109,11 @@ void setup() { //------------- Lun 0 for external flash -------------// flash.begin(); - flash_formatted = fatfs.begin(&flash); usb_msc.setCapacity(0, flash.size()/512, 512); usb_msc.setReadWriteCallback(0, external_flash_read_cb, external_flash_write_cb, external_flash_flush_cb); usb_msc.setUnitReady(0, true); - flash_changed = true; // to print contents initially - //------------- Lun 1 for SD card -------------// #ifdef SDCARD_DETECT // DETECT pin is available, detect card present on the fly with test unit ready @@ -126,26 +134,18 @@ void setup() { bool init_sdcard(void) { Serial.print("Init SDCard ... "); - if (!sd.begin(SDCARD_CS, SD_SCK_MHZ(50))) { - Serial.print("Failed "); - sd.errorPrint("sd.begin() failed"); - + if (!sd.begin(SD_CONFIG)) { + Serial.println("initialization failed. Things to check:"); + Serial.println("- is a card inserted?"); + Serial.println("- is your wiring correct?"); + Serial.println("- did you change the SDCARD_CS or SDIO pin to match your shield or module?"); return false; } - uint32_t block_count; - -#if SD_FAT_VERSION >= 20000 - block_count = sd.card()->sectorCount(); -#else - block_count = sd.card()->cardSize(); -#endif - + uint32_t block_count = sd.card()->sectorCount(); usb_msc.setCapacity(1, block_count, 512); usb_msc.setReadWriteCallback(1, sdcard_read_cb, sdcard_write_cb, sdcard_flush_cb); - sd_changed = true; // to print contents initially - Serial.print("OK, Card size = "); Serial.print((block_count / (1024 * 1024)) * 512); Serial.println(" MB"); @@ -173,40 +173,7 @@ void print_rootdir(File32* rdir) { } void loop() { - if (flash_changed) { - if (!flash_formatted) { - flash_formatted = fatfs.begin(&flash); - } - - // skip if still not formatted - if (flash_formatted) { - File32 root; - root = fatfs.open("/"); - - Serial.println("Flash contents:"); - print_rootdir(&root); - Serial.println(); - - root.close(); - } - - flash_changed = false; - } - - if (sd_changed) { - File32 root; - root = sd.open("/"); - - Serial.println("SD contents:"); - print_rootdir(&root); - Serial.println(); - - root.close(); - - sd_changed = false; - } - - delay(1000); // refresh every 1 second + // nothing to do } @@ -214,16 +181,8 @@ void loop() { // SD Card callbacks //--------------------------------------------------------------------+ -int32_t sdcard_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) -{ - bool rc; - -#if SD_FAT_VERSION >= 20000 - rc = sd.card()->readSectors(lba, (uint8_t*) buffer, bufsize/512); -#else - rc = sd.card()->readBlocks(lba, (uint8_t*) buffer, bufsize/512); -#endif - +int32_t sdcard_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) { + bool rc = sd.card()->readSectors(lba, (uint8_t*) buffer, bufsize/512); return rc ? bufsize : -1; } @@ -231,35 +190,18 @@ int32_t sdcard_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) // Process data in buffer to disk's storage and // return number of written bytes (must be multiple of block size) int32_t sdcard_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize) { - bool rc; - #ifdef LED_BUILTIN digitalWrite(LED_BUILTIN, HIGH); #endif - -#if SD_FAT_VERSION >= 20000 - rc = sd.card()->writeSectors(lba, buffer, bufsize/512); -#else - rc = sd.card()->writeBlocks(lba, buffer, bufsize/512); -#endif - + bool rc = sd.card()->writeSectors(lba, buffer, bufsize/512); return rc ? bufsize : -1; } // Callback invoked when WRITE10 command is completed (status received and accepted by host). // used to flush any pending cache. -void sdcard_flush_cb (void) -{ -#if SD_FAT_VERSION >= 20000 +void sdcard_flush_cb (void) { sd.card()->syncDevice(); -#else - sd.card()->syncBlocks(); -#endif - - // clear file system's cache to force refresh - sd.cacheClear(); - - sd_changed = true; + sd.cacheClear(); // clear file system's cache to force refresh #ifdef LED_BUILTIN digitalWrite(LED_BUILTIN, LOW); @@ -281,8 +223,6 @@ bool sdcard_ready_callback(void) { usb_msc.setReadWriteCallback(1, NULL, NULL, NULL); } - Serial.println(sd_inited); - return sd_inited; } #endif @@ -317,12 +257,6 @@ int32_t external_flash_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize // used to flush any pending cache. void external_flash_flush_cb (void) { flash.syncBlocks(); - - // clear file system's cache to force refresh - fatfs.cacheClear(); - - flash_changed = true; - #ifdef LED_BUILTIN digitalWrite(LED_BUILTIN, LOW); #endif diff --git a/examples/MassStorage/msc_sdfat/msc_sdfat.ino b/examples/MassStorage/msc_sdfat/msc_sdfat.ino index 619971e..3045c19 100644 --- a/examples/MassStorage/msc_sdfat/msc_sdfat.ino +++ b/examples/MassStorage/msc_sdfat/msc_sdfat.ino @@ -20,40 +20,52 @@ //--------------------------------------------------------------------+ // SDCard Config //--------------------------------------------------------------------+ - #if defined(ARDUINO_PYPORTAL_M4) || defined(ARDUINO_PYPORTAL_M4_TITANO) // PyPortal has on-board card reader #define SDCARD_CS 32 #define SDCARD_DETECT 33 #define SDCARD_DETECT_ACTIVE HIGH + #elif defined(ARDUINO_ADAFRUIT_METRO_RP2040) - #define SDCARD_CS 23 + #define SDIO_CLK_PIN 18 + #define SDIO_CMD_PIN 19 // MOSI + #define SDIO_DAT0_PIN 20 // DAT1: 21, DAT2: 22, DAT3: 23 + #define SDCARD_DETECT 15 #define SDCARD_DETECT_ACTIVE LOW + +#elif defined(ARDUINO_ADAFRUIT_METRO_RP2350) + // Note: not working yet (need troubleshoot later) + #define SDIO_CLK_PIN 34 + #define SDIO_CMD_PIN 35 // MOSI + #define SDIO_DAT0_PIN 36 // DAT1: 37, DAT2: 38, DAT3: 39 + + #define SDCARD_DETECT 40 + #define SDCARD_DETECT_ACTIVE LOW + #else + // Use SPI, no detect #define SDCARD_CS 10 - // no detect +#endif + +#if defined(SDIO_CLK_PIN) && defined(SDIO_CMD_PIN) && defined(SDIO_DAT0_PIN) + #define SD_CONFIG SdioConfig(SDIO_CLK_PIN, SDIO_CMD_PIN, SDIO_DAT0_PIN) +#else + #define SD_CONFIG SdSpiConfig(SDCARD_CS, SHARED_SPI, SD_SCK_MHZ(50)) #endif // File system on SD Card SdFat sd; -SdFile root; -SdFile file; - // USB Mass Storage object Adafruit_USBD_MSC usb_msc; -// Set to true when PC write to flash -bool fs_changed; - // the setup function runs once when you press reset or power the board void setup() { - Serial.begin(115200); - #ifdef LED_BUILTIN pinMode(LED_BUILTIN, OUTPUT); #endif + Serial.begin(115200); // Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively usb_msc.setID("Adafruit", "SD Card", "1.0"); @@ -73,26 +85,20 @@ void setup() { TinyUSBDevice.attach(); } - while ( !Serial ) delay(10); // wait for native usb + //while ( !Serial ) delay(10); // wait for native usb Serial.println("Adafruit TinyUSB Mass Storage SD Card example"); Serial.print("\nInitializing SD card ... "); - Serial.print("CS = "); Serial.println(SDCARD_CS); - if ( !sd.begin(SDCARD_CS, SD_SCK_MHZ(50)) ) { + if (!sd.begin(SD_CONFIG)) { Serial.println("initialization failed. Things to check:"); - Serial.println("* is a card inserted?"); - Serial.println("* is your wiring correct?"); - Serial.println("* did you change the SDCARD_CS pin to match your shield or module?"); + Serial.println("- is a card inserted?"); + Serial.println("- is your wiring correct?"); + Serial.println("- did you change the SDCARD_CS or SDIO pin to match your shield or module?"); while (1) delay(1); } // Size in blocks (512 bytes) -#if SD_FAT_VERSION >= 20000 uint32_t block_count = sd.card()->sectorCount(); -#else - uint32_t block_count = sd.card()->cardSize(); -#endif - Serial.print("Volume size (MB): "); Serial.println((block_count/2) / 1024); @@ -101,51 +107,17 @@ void setup() { // MSC is ready for read/write usb_msc.setUnitReady(true); - - fs_changed = true; // to print contents initially } void loop() { - if ( fs_changed ) { - root.open("/"); - Serial.println("SD contents:"); - - // Open next file in root. - // Warning, openNext starts at the current directory position - // so a rewind of the directory may be required. - while ( file.openNext(&root, O_RDONLY) ) { - file.printFileSize(&Serial); - Serial.write(' '); - file.printName(&Serial); - if ( file.isDir() ) { - // Indicate a directory. - Serial.write('/'); - } - Serial.println(); - file.close(); - } - - root.close(); - - Serial.println(); - - fs_changed = false; - delay(1000); // refresh every 0.5 second - } + // noting to do } // Callback invoked when received READ10 command. // Copy disk's data to buffer (up to bufsize) and // return number of copied bytes (must be multiple of block size) int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) { - bool rc; - -#if SD_FAT_VERSION >= 20000 - rc = sd.card()->readSectors(lba, (uint8_t*) buffer, bufsize/512); -#else - rc = sd.card()->readBlocks(lba, (uint8_t*) buffer, bufsize/512); -#endif - + bool rc = sd.card()->readSectors(lba, (uint8_t*) buffer, bufsize/512); return rc ? bufsize : -1; } @@ -153,34 +125,18 @@ int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) { // Process data in buffer to disk's storage and // return number of written bytes (must be multiple of block size) int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize) { - bool rc; - #ifdef LED_BUILTIN digitalWrite(LED_BUILTIN, HIGH); #endif - -#if SD_FAT_VERSION >= 20000 - rc = sd.card()->writeSectors(lba, buffer, bufsize/512); -#else - rc = sd.card()->writeBlocks(lba, buffer, bufsize/512); -#endif - + bool rc = sd.card()->writeSectors(lba, buffer, bufsize/512); return rc ? bufsize : -1; } // Callback invoked when WRITE10 command is completed (status received and accepted by host). // used to flush any pending cache. void msc_flush_cb (void) { -#if SD_FAT_VERSION >= 20000 sd.card()->syncDevice(); -#else - sd.card()->syncBlocks(); -#endif - - // clear file system's cache to force refresh - sd.cacheClear(); - - fs_changed = true; + sd.cacheClear(); // clear file system's cache to force refresh #ifdef LED_BUILTIN digitalWrite(LED_BUILTIN, LOW); From 4daede374443aedc2d2669eaad643c494e9b44cf Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 3 Jun 2025 18:53:46 +0100 Subject: [PATCH 2/3] Update library.properties - bump version to 3.6.1 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 96c7c37..1b32fc7 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit TinyUSB Library -version=3.6.0 +version=3.6.1 author=Adafruit maintainer=Adafruit sentence=TinyUSB library for Arduino From d4071f5abe0c2560cd2dbdd7652a35122a9dac69 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 3 Jun 2025 18:53:58 +0100 Subject: [PATCH 3/3] Update library.json - bump version to 3.6.1 --- library.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.json b/library.json index b421434..017015d 100644 --- a/library.json +++ b/library.json @@ -2,7 +2,7 @@ "name": "Adafruit TinyUSB Library", "keywords": "usb, arduino, tinyusb", "description": "Arduino library for TinyUSB", - "version": "3.6.0", + "version": "3.6.1", "repository": { "type": "git", "url": "https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git"