2
2
// Copyright (c) 2019 Ha Thach for Adafruit Industries
3
3
4
4
/* This example demo how to expose on-board external Flash as USB Mass Storage.
5
- * - For M0 express series with SPI flash device
6
- * follow library is required
5
+ * Following library is required
7
6
* https://github.com/adafruit/Adafruit_SPIFlash
8
- *
9
- * - For M4 expres series and nRF52840 with QSPI flash, additional library is reuiqred
10
- * https://github.com/adafruit/Adafruit_QSPI
11
7
*/
12
8
13
9
#include " Adafruit_TinyUSB.h"
14
10
#include " Adafruit_SPIFlash.h"
15
11
16
12
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
17
- #include " Adafruit_QSPI.h"
18
- #include " Adafruit_QSPI_Flash.h"
19
-
20
- Adafruit_QSPI_Flash flash;
13
+ Adafruit_FlashTransport_QSPI flashTransport (PIN_QSPI_SCK, PIN_QSPI_CS, PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
21
14
#else
22
- // Configuration of the flash chip pins and flash fatfs object.
23
- // You don't normally need to change these if using a Feather/Metro
24
- // M0 express board.
25
-
26
- // Flash chip type. If you change this be sure to change the fatfs to match as well
27
- #define FLASH_TYPE SPIFLASHTYPE_W25Q16BV
28
-
29
15
#if (SPI_INTERFACES_COUNT == 1)
30
- #define FLASH_SS SS // Flash chip SS pin.
31
- #define FLASH_SPI_PORT SPI // What SPI port is Flash on?
16
+ Adafruit_FlashTransport_SPI flashTransport (SS0, &SPI);
32
17
#else
33
- #define FLASH_SS SS1 // Flash chip SS pin.
34
- #define FLASH_SPI_PORT SPI1 // What SPI port is Flash on?
18
+ Adafruit_FlashTransport_SPI flashTransport (SS1, &SPI1);
35
19
#endif
36
-
37
- Adafruit_SPIFlash flash (FLASH_SS, &FLASH_SPI_PORT); // Use hardware SPI
38
20
#endif
39
21
22
+ Adafruit_SPIFlash flash (&flashTransport);
23
+
40
24
Adafruit_USBD_MSC usb_msc;
41
25
42
26
// the setup function runs once when you press reset or power the board
43
27
void setup ()
44
28
{
45
- #if defined(__SAMD51__) || defined(NRF52840_XXAA)
46
29
flash.begin ();
47
- #else
48
- flash.begin (FLASH_TYPE);
49
- #endif
50
30
51
31
pinMode (LED_BUILTIN, OUTPUT);
52
32
@@ -68,9 +48,8 @@ void setup()
68
48
while ( !Serial ) delay (10 ); // wait for native usb
69
49
70
50
Serial.println (" Adafruit TinyUSB Mass Storage SPI Flash example" );
71
- Serial.print (" Page size: " ); Serial.println (flash.pageSize ());
72
- Serial.print (" Page num : " ); Serial.println (flash.numPages ());
73
- Serial.print (" JEDEC ID: " ); Serial.println (flash.GetJEDECID (), HEX);
51
+ Serial.print (" JEDEC ID: " ); Serial.println (flash.getJEDECID (), HEX);
52
+ Serial.print (" Flash size: " ); Serial.println (flash.size ());
74
53
}
75
54
76
55
void loop ()
@@ -83,8 +62,9 @@ void loop()
83
62
// return number of copied bytes (must be multiple of block size)
84
63
int32_t msc_read_cb (uint32_t lba, void * buffer, uint32_t bufsize)
85
64
{
86
- const uint32_t addr = lba*512 ;
87
- flash_cache_read ((uint8_t *) buffer, addr, bufsize);
65
+ // Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks
66
+ // already include 4K sector caching internally. We don't need to cache it, yahhhh!!
67
+ flash.readBlocks (lba, (uint8_t *) buffer, bufsize/512 );
88
68
return bufsize;
89
69
}
90
70
@@ -93,118 +73,15 @@ int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
93
73
// return number of written bytes (must be multiple of block size)
94
74
int32_t msc_write_cb (uint32_t lba, uint8_t * buffer, uint32_t bufsize)
95
75
{
96
- // need to erase & caching write back
97
- const uint32_t addr = lba* 512 ;
98
- flash_cache_write (addr , buffer, bufsize);
76
+ // Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks
77
+ // already include 4K sector caching internally. We don't need to cache it, yahhhh!!
78
+ flash. writeBlocks (lba , buffer, bufsize/ 512 );
99
79
return bufsize;
100
80
}
101
81
102
82
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
103
83
// used to flush any pending cache.
104
84
void msc_flush_cb (void )
105
85
{
106
- flash_cache_flush ();
107
- }
108
-
109
- // --------------------------------------------------------------------+
110
- // Flash Caching
111
- // --------------------------------------------------------------------+
112
- #define FLASH_CACHE_SIZE 4096 // must be a erasable page size
113
- #define FLASH_CACHE_INVALID_ADDR 0xffffffff
114
-
115
- uint32_t cache_addr = FLASH_CACHE_INVALID_ADDR;
116
- uint8_t cache_buf[FLASH_CACHE_SIZE];
117
-
118
- static inline uint32_t page_addr_of (uint32_t addr)
119
- {
120
- return addr & ~(FLASH_CACHE_SIZE - 1 );
121
- }
122
-
123
- static inline uint32_t page_offset_of (uint32_t addr)
124
- {
125
- return addr & (FLASH_CACHE_SIZE - 1 );
126
- }
127
-
128
- void flash_cache_flush (void )
129
- {
130
- if ( cache_addr == FLASH_CACHE_INVALID_ADDR ) return ;
131
-
132
- // indicator
133
- digitalWrite (LED_BUILTIN, HIGH);
134
-
135
- flash.eraseSector (cache_addr/FLASH_CACHE_SIZE);
136
- flash.writeBuffer (cache_addr, cache_buf, FLASH_CACHE_SIZE);
137
-
138
- digitalWrite (LED_BUILTIN, LOW);
139
-
140
- cache_addr = FLASH_CACHE_INVALID_ADDR;
141
- }
142
-
143
- uint32_t flash_cache_write (uint32_t dst, void const * src, uint32_t len)
144
- {
145
- uint8_t const * src8 = (uint8_t const *) src;
146
- uint32_t remain = len;
147
-
148
- // Program up to page boundary each loop
149
- while ( remain )
150
- {
151
- uint32_t const page_addr = page_addr_of (dst);
152
- uint32_t const offset = page_offset_of (dst);
153
-
154
- uint32_t wr_bytes = FLASH_CACHE_SIZE - offset;
155
- wr_bytes = min (remain, wr_bytes);
156
-
157
- // Page changes, flush old and update new cache
158
- if ( page_addr != cache_addr )
159
- {
160
- flash_cache_flush ();
161
- cache_addr = page_addr;
162
-
163
- // read a whole page from flash
164
- flash.readBuffer (page_addr, cache_buf, FLASH_CACHE_SIZE);
165
- }
166
-
167
- memcpy (cache_buf + offset, src8, wr_bytes);
168
-
169
- // adjust for next run
170
- src8 += wr_bytes;
171
- remain -= wr_bytes;
172
- dst += wr_bytes;
173
- }
174
-
175
- return len - remain;
176
- }
177
-
178
- void flash_cache_read (uint8_t * dst, uint32_t addr, uint32_t count)
179
- {
180
- // overwrite with cache value if available
181
- if ( (cache_addr != FLASH_CACHE_INVALID_ADDR) &&
182
- !(addr < cache_addr && addr + count <= cache_addr) &&
183
- !(addr >= cache_addr + FLASH_CACHE_SIZE) )
184
- {
185
- int dst_off = cache_addr - addr;
186
- int src_off = 0 ;
187
-
188
- if ( dst_off < 0 )
189
- {
190
- src_off = -dst_off;
191
- dst_off = 0 ;
192
- }
193
-
194
- int cache_bytes = min (FLASH_CACHE_SIZE-src_off, count - dst_off);
195
-
196
- // start to cached
197
- if ( dst_off ) flash.readBuffer (addr, dst, dst_off);
198
-
199
- // cached
200
- memcpy (dst + dst_off, cache_buf + src_off, cache_bytes);
201
-
202
- // cached to end
203
- int copied = dst_off + cache_bytes;
204
- if ( copied < count ) flash.readBuffer (addr + copied, dst + copied, count - copied);
205
- }
206
- else
207
- {
208
- flash.readBuffer (addr, dst, count);
209
- }
86
+ flash.syncBlocks ();
210
87
}
0 commit comments