From d294b93e81b2a207ce28bd9f0d615ff268e37d82 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 12 Jan 2022 21:00:44 +0700 Subject: [PATCH] add msc internal flash samd example --- .../msc_external_flash/msc_external_flash.ino | 2 +- .../.proxlighttrinkey_m0.test.only | 0 .../msc_internal_flash_samd.ino | 144 ++++++++++++++++++ 3 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 examples/MassStorage/msc_internal_flash_samd/.proxlighttrinkey_m0.test.only create mode 100644 examples/MassStorage/msc_internal_flash_samd/msc_internal_flash_samd.ino diff --git a/examples/MassStorage/msc_external_flash/msc_external_flash.ino b/examples/MassStorage/msc_external_flash/msc_external_flash.ino index aafbc320..a29f18c0 100644 --- a/examples/MassStorage/msc_external_flash/msc_external_flash.ino +++ b/examples/MassStorage/msc_external_flash/msc_external_flash.ino @@ -137,7 +137,7 @@ void loop() root.close(); Serial.println(); - delay(1000); // refresh every 0.5 second + delay(1000); // refresh every 1 second } } diff --git a/examples/MassStorage/msc_internal_flash_samd/.proxlighttrinkey_m0.test.only b/examples/MassStorage/msc_internal_flash_samd/.proxlighttrinkey_m0.test.only new file mode 100644 index 00000000..e69de29b diff --git a/examples/MassStorage/msc_internal_flash_samd/msc_internal_flash_samd.ino b/examples/MassStorage/msc_internal_flash_samd/msc_internal_flash_samd.ino new file mode 100644 index 00000000..3b7a9e48 --- /dev/null +++ b/examples/MassStorage/msc_internal_flash_samd/msc_internal_flash_samd.ino @@ -0,0 +1,144 @@ +/********************************************************************* + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + MIT license, check LICENSE for more information + Copyright (c) 2019 Ha Thach for Adafruit Industries + All text above, and the splash screen below must be included in + any redistribution +*********************************************************************/ + +#include "SPI.h" +#include "SdFat.h" +#include "Adafruit_InternalFlash.h" +#include "Adafruit_TinyUSB.h" + +// Start address and size should matches value in the CircuitPython (INTERNAL_FLASH_FILESYSTEM = 1) +// to make it easier to switch between Arduino and CircuitPython +#define INTERNAL_FLASH_FILESYSTEM_START_ADDR (0x00040000 - 256 - 0 - INTERNAL_FLASH_FILESYSTEM_SIZE) +#define INTERNAL_FLASH_FILESYSTEM_SIZE (64*1024) + +// Internal Flash object +Adafruit_InternalFlash flash(INTERNAL_FLASH_FILESYSTEM_START_ADDR, INTERNAL_FLASH_FILESYSTEM_SIZE); + +// file system object from SdFat +FatFileSystem fatfs; + +FatFile root; +FatFile file; + +// USB MSC 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() +{ + // Initialize internal flash + flash.begin(); + + // Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively + usb_msc.setID("Adafruit", "Internal Flash", "1.0"); + + // Set callback + usb_msc.setReadWriteCallback(msc_read_callback, msc_write_callback, msc_flush_callback); + usb_msc.setWritableCallback(msc_writable_callback); + + // Set disk size, block size should be 512 regardless of flash page size + usb_msc.setCapacity(flash.size()/512, 512); + + // Set Lun ready + usb_msc.setUnitReady(true); + + usb_msc.begin(); + + // Init file system on the flash + fatfs.begin(&flash); + + Serial.begin(115200); + //while ( !Serial ) delay(10); // wait for native usb + + fs_changed = true; // to print contents initially +} + +void loop() +{ + if ( fs_changed ) + { + fs_changed = false; + + if ( !root.open("/") ) + { + Serial.println("open root failed"); + return; + } + + Serial.println("Flash 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(); + delay(1000); // refresh every 1 second + } +} + +// 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_callback (uint32_t lba, void* buffer, uint32_t bufsize) +{ + // Note: InternalFlash Block API: readBlocks/writeBlocks/syncBlocks + // already include sector caching (if needed). We don't need to cache it, yahhhh!! + return flash.readBlocks(lba, (uint8_t*) buffer, bufsize/512) ? bufsize : -1; +} + +// Callback invoked when received WRITE10 command. +// Process data in buffer to disk's storage and +// return number of written bytes (must be multiple of block size) +int32_t msc_write_callback (uint32_t lba, uint8_t* buffer, uint32_t bufsize) +{ + // Note: InternalFlash Block API: readBlocks/writeBlocks/syncBlocks + // already include sector caching (if needed). We don't need to cache it, yahhhh!! + return flash.writeBlocks(lba, buffer, bufsize/512) ? bufsize : -1; +} + +// Callback invoked when WRITE10 command is completed (status received and accepted by host). +// used to flush any pending cache. +void msc_flush_callback (void) +{ + // sync with flash + flash.syncBlocks(); + + // clear file system's cache to force refresh + fatfs.cacheClear(); + + fs_changed = true; +} + +// Invoked to check if device is writable as part of SCSI WRITE10 +// Default mode is writable +bool msc_writable_callback(void) +{ + // true for writable, false for read-only + return true; +}