Skip to content

Commit d294b93

Browse files
committed
add msc internal flash samd example
1 parent 681d4ef commit d294b93

File tree

3 files changed

+145
-1
lines changed

3 files changed

+145
-1
lines changed

examples/MassStorage/msc_external_flash/msc_external_flash.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ void loop()
137137
root.close();
138138

139139
Serial.println();
140-
delay(1000); // refresh every 0.5 second
140+
delay(1000); // refresh every 1 second
141141
}
142142
}
143143

examples/MassStorage/msc_internal_flash_samd/.proxlighttrinkey_m0.test.only

Whitespace-only changes.
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*********************************************************************
2+
Adafruit invests time and resources providing this open source code,
3+
please support Adafruit and open-source hardware by purchasing
4+
products from Adafruit!
5+
6+
MIT license, check LICENSE for more information
7+
Copyright (c) 2019 Ha Thach for Adafruit Industries
8+
All text above, and the splash screen below must be included in
9+
any redistribution
10+
*********************************************************************/
11+
12+
#include "SPI.h"
13+
#include "SdFat.h"
14+
#include "Adafruit_InternalFlash.h"
15+
#include "Adafruit_TinyUSB.h"
16+
17+
// Start address and size should matches value in the CircuitPython (INTERNAL_FLASH_FILESYSTEM = 1)
18+
// to make it easier to switch between Arduino and CircuitPython
19+
#define INTERNAL_FLASH_FILESYSTEM_START_ADDR (0x00040000 - 256 - 0 - INTERNAL_FLASH_FILESYSTEM_SIZE)
20+
#define INTERNAL_FLASH_FILESYSTEM_SIZE (64*1024)
21+
22+
// Internal Flash object
23+
Adafruit_InternalFlash flash(INTERNAL_FLASH_FILESYSTEM_START_ADDR, INTERNAL_FLASH_FILESYSTEM_SIZE);
24+
25+
// file system object from SdFat
26+
FatFileSystem fatfs;
27+
28+
FatFile root;
29+
FatFile file;
30+
31+
// USB MSC object
32+
Adafruit_USBD_MSC usb_msc;
33+
34+
// Set to true when PC write to flash
35+
bool fs_changed;
36+
37+
// the setup function runs once when you press reset or power the board
38+
void setup()
39+
{
40+
// Initialize internal flash
41+
flash.begin();
42+
43+
// Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively
44+
usb_msc.setID("Adafruit", "Internal Flash", "1.0");
45+
46+
// Set callback
47+
usb_msc.setReadWriteCallback(msc_read_callback, msc_write_callback, msc_flush_callback);
48+
usb_msc.setWritableCallback(msc_writable_callback);
49+
50+
// Set disk size, block size should be 512 regardless of flash page size
51+
usb_msc.setCapacity(flash.size()/512, 512);
52+
53+
// Set Lun ready
54+
usb_msc.setUnitReady(true);
55+
56+
usb_msc.begin();
57+
58+
// Init file system on the flash
59+
fatfs.begin(&flash);
60+
61+
Serial.begin(115200);
62+
//while ( !Serial ) delay(10); // wait for native usb
63+
64+
fs_changed = true; // to print contents initially
65+
}
66+
67+
void loop()
68+
{
69+
if ( fs_changed )
70+
{
71+
fs_changed = false;
72+
73+
if ( !root.open("/") )
74+
{
75+
Serial.println("open root failed");
76+
return;
77+
}
78+
79+
Serial.println("Flash contents:");
80+
81+
// Open next file in root.
82+
// Warning, openNext starts at the current directory position
83+
// so a rewind of the directory may be required.
84+
while ( file.openNext(&root, O_RDONLY) )
85+
{
86+
file.printFileSize(&Serial);
87+
Serial.write(' ');
88+
file.printName(&Serial);
89+
if ( file.isDir() )
90+
{
91+
// Indicate a directory.
92+
Serial.write('/');
93+
}
94+
Serial.println();
95+
file.close();
96+
}
97+
98+
root.close();
99+
100+
Serial.println();
101+
delay(1000); // refresh every 1 second
102+
}
103+
}
104+
105+
// Callback invoked when received READ10 command.
106+
// Copy disk's data to buffer (up to bufsize) and
107+
// return number of copied bytes (must be multiple of block size)
108+
int32_t msc_read_callback (uint32_t lba, void* buffer, uint32_t bufsize)
109+
{
110+
// Note: InternalFlash Block API: readBlocks/writeBlocks/syncBlocks
111+
// already include sector caching (if needed). We don't need to cache it, yahhhh!!
112+
return flash.readBlocks(lba, (uint8_t*) buffer, bufsize/512) ? bufsize : -1;
113+
}
114+
115+
// Callback invoked when received WRITE10 command.
116+
// Process data in buffer to disk's storage and
117+
// return number of written bytes (must be multiple of block size)
118+
int32_t msc_write_callback (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
119+
{
120+
// Note: InternalFlash Block API: readBlocks/writeBlocks/syncBlocks
121+
// already include sector caching (if needed). We don't need to cache it, yahhhh!!
122+
return flash.writeBlocks(lba, buffer, bufsize/512) ? bufsize : -1;
123+
}
124+
125+
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
126+
// used to flush any pending cache.
127+
void msc_flush_callback (void)
128+
{
129+
// sync with flash
130+
flash.syncBlocks();
131+
132+
// clear file system's cache to force refresh
133+
fatfs.cacheClear();
134+
135+
fs_changed = true;
136+
}
137+
138+
// Invoked to check if device is writable as part of SCSI WRITE10
139+
// Default mode is writable
140+
bool msc_writable_callback(void)
141+
{
142+
// true for writable, false for read-only
143+
return true;
144+
}

0 commit comments

Comments
 (0)