Skip to content

Commit 53a9919

Browse files
committed
Raises file limit from 14 to 62 files.
Enable all four sectors of root directory to contain files.
1 parent 8def8ae commit 53a9919

File tree

2 files changed

+115
-15
lines changed

2 files changed

+115
-15
lines changed

src/usb/uf2/ghostfat.c

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "bootloader_settings.h"
1010
#include "bootloader.h"
1111

12+
// #define CREATE_MANY_FILES
13+
1214

1315
typedef struct {
1416
uint8_t JumpInstruction[3];
@@ -48,7 +50,6 @@ typedef struct {
4850
uint16_t startCluster;
4951
uint32_t size;
5052
} __attribute__((packed)) DirEntry;
51-
5253
STATIC_ASSERT(sizeof(DirEntry) == 32);
5354

5455
struct TextFile {
@@ -78,9 +79,56 @@ const char indexFile[] = //
7879
"</body>"
7980
"</html>\n";
8081

82+
#ifdef CREATE_MANY_FILES
83+
const char dataFile00[] = "This is the data for File 00\r\n";
84+
const char dataFile01[] = "This is the data for File 01\r\n";
85+
const char dataFile02[] = "This is the data for File 02\r\n";
86+
const char dataFile03[] = "This is the data for File 03\r\n";
87+
const char dataFile04[] = "This is the data for File 04\r\n";
88+
const char dataFile05[] = "This is the data for File 05\r\n";
89+
const char dataFile06[] = "This is the data for File 06\r\n";
90+
const char dataFile07[] = "This is the data for File 07\r\n";
91+
const char dataFile08[] = "This is the data for File 08\r\n";
92+
const char dataFile09[] = "This is the data for File 09\r\n";
93+
const char dataFile10[] = "This is the data for File 10\r\n";
94+
const char dataFile11[] = "This is the data for File 11\r\n";
95+
const char dataFile12[] = "This is the data for File 12\r\n";
96+
const char dataFile13[] = "This is the data for File 13\r\n";
97+
const char dataFile14[] = "This is the data for File 14\r\n";
98+
const char dataFile15[] = "This is the data for File 15\r\n";
99+
const char dataFile16[] = "This is the data for File 16\r\n";
100+
const char dataFile17[] = "This is the data for File 17\r\n";
101+
const char dataFile18[] = "This is the data for File 18\r\n";
102+
const char dataFile19[] = "This is the data for File 19\r\n";
103+
#endif // CREATE_MANY_FILES
104+
105+
// WARNING -- code presumes only one NULL .content for .UF2 file
106+
// and requires it be the last element of the array
81107
static struct TextFile const info[] = {
82108
{.name = "INFO_UF2TXT", .content = infoUf2File},
83109
{.name = "INDEX HTM", .content = indexFile},
110+
#ifdef CREATE_MANY_FILES
111+
{.name = "FILE00 TXT", .content = dataFile00},
112+
{.name = "FILE01 TXT", .content = dataFile01},
113+
{.name = "FILE02 TXT", .content = dataFile02},
114+
{.name = "FILE03 TXT", .content = dataFile03},
115+
{.name = "FILE04 TXT", .content = dataFile04},
116+
{.name = "FILE05 TXT", .content = dataFile05},
117+
{.name = "FILE06 TXT", .content = dataFile06},
118+
{.name = "FILE07 TXT", .content = dataFile07},
119+
{.name = "FILE08 TXT", .content = dataFile08},
120+
{.name = "FILE09 TXT", .content = dataFile09},
121+
{.name = "FILE10 TXT", .content = dataFile10},
122+
{.name = "FILE11 TXT", .content = dataFile11},
123+
{.name = "FILE12 TXT", .content = dataFile12},
124+
{.name = "FILE13 TXT", .content = dataFile13},
125+
{.name = "FILE14 TXT", .content = dataFile14},
126+
{.name = "FILE15 TXT", .content = dataFile15},
127+
{.name = "FILE16 TXT", .content = dataFile16},
128+
{.name = "FILE17 TXT", .content = dataFile17},
129+
{.name = "FILE18 TXT", .content = dataFile18},
130+
{.name = "FILE19 TXT", .content = dataFile19},
131+
#endif
84132
{.name = "CURRENT UF2"},
85133
};
86134

@@ -110,8 +158,9 @@ STATIC_ASSERT(ARRAY_SIZE2(indexFile) < 512);
110158

111159
// all directory entries must fit in a single sector
112160
// because otherwise current code overflows buffer
113-
STATIC_ASSERT(NUM_DIRENTRIES < (512 / sizeof(DirEntry)));
114-
// STATIC_ASSERT(NUM_DIRENTRIES < (512 / sizeof(DirEntry)) * ROOT_DIR_SECTORS);
161+
#define DIRENTRIES_PER_SECTOR (512/sizeof(DirEntry))
162+
163+
STATIC_ASSERT(NUM_DIRENTRIES < DIRENTRIES_PER_SECTOR * ROOT_DIR_SECTORS);
115164

116165

117166
static FAT_BootBlock const BootBlock = {
@@ -121,7 +170,7 @@ static FAT_BootBlock const BootBlock = {
121170
.SectorsPerCluster = 1,
122171
.ReservedSectors = RESERVED_SECTORS,
123172
.FATCopies = 2,
124-
.RootDirectoryEntries = (ROOT_DIR_SECTORS * 512 / 32),
173+
.RootDirectoryEntries = (ROOT_DIR_SECTORS * DIRENTRIES_PER_SECTOR),
125174
.TotalSectors16 = NUM_FAT_BLOCKS - 2,
126175
.MediaDescriptor = 0xF8,
127176
.SectorsPerFAT = SECTORS_PER_FAT,
@@ -205,8 +254,11 @@ void read_block(uint32_t block_no, uint8_t *data) {
205254
sectionIdx -= SECTORS_PER_FAT;
206255
if (sectionIdx == 0) {
207256
data[0] = 0xf0;
257+
// WARNING -- code presumes only one NULL .content for .UF2 file
258+
// and all non-NULL .content fit in one sector
259+
// and requires it be the last element of the array
208260
for (int i = 1; i < NUM_FILES * 2 + 4; ++i) {
209-
data[i] = 0xff; // WARNING -- code presumes each non-UF2 file content fits in single sector
261+
data[i] = 0xff;
210262
}
211263
}
212264
for (int i = 0; i < 256; ++i) {
@@ -215,20 +267,33 @@ void read_block(uint32_t block_no, uint8_t *data) {
215267
((uint16_t *)(void *)data)[i] = v == UF2_LAST_SECTOR ? 0xffff : v + 1;
216268
}
217269
} else if (block_no < START_CLUSTERS) {
218-
// Use STATIC_ASSERT() above to ensure only first sector has entries
270+
219271
sectionIdx -= START_ROOTDIR;
220-
if (sectionIdx == 0) {
221-
DirEntry *d = (void *)data;
272+
273+
DirEntry *d = (void *)data;
274+
int remainingEntries = DIRENTRIES_PER_SECTOR;
275+
if (sectionIdx == 0) { // volume label first
276+
// volume label is first directory entry
222277
padded_memcpy(d->name, (char const *) BootBlock.VolumeLabel, 11);
223278
d->attrs = 0x28;
224-
for (int i = 0; i < NUM_FILES; ++i) {
225-
d++;
226-
struct TextFile const *inf = &info[i];
227-
d->size = inf->content ? strlen(inf->content) : UF2_SIZE;
228-
d->startCluster = i + 2;
229-
padded_memcpy(d->name, inf->name, 11);
230-
}
279+
remainingEntries--;
231280
}
281+
282+
for (int i = DIRENTRIES_PER_SECTOR * sectionIdx;
283+
remainingEntries > 0 && i < NUM_FILES;
284+
i++, d++) {
285+
struct TextFile const * inf = &info[i];
286+
// WARNING -- code presumes only one NULL .content for .UF2 file
287+
// and requires it be the last element of the array
288+
d->size = inf->content ? strlen(inf->content) : UF2_SIZE;
289+
d->startCluster = i + 2;
290+
padded_memcpy(d->name, inf->name, 11);
291+
// DIR_WrtTime and DIR_WrtDate must be supported
292+
d->updateDate = __DOSDATE__;
293+
d->lastAccessDate = __DOSDATE__;
294+
d->createDate = __DOSDATE__;
295+
}
296+
232297
} else {
233298
sectionIdx -= START_CLUSTERS;
234299
if (sectionIdx < NUM_FILES - 1) {

src/usb/uf2/uf2.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,3 +296,38 @@ static inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining
296296
#endif // ARRAYSIZE2_H
297297

298298

299+
#ifndef COMPILE_DATE_H
300+
#define COMPILE_DATE_H
301+
302+
#define __YEAR_INT__ ((( \
303+
(__DATE__ [ 7u] - '0') * 10u + \
304+
(__DATE__ [ 8u] - '0')) * 10u + \
305+
(__DATE__ [ 9u] - '0')) * 10u + \
306+
(__DATE__ [10u] - '0'))
307+
308+
#define __MONTH_INT__ ( \
309+
(__DATE__ [2u] == 'n' && __DATE__ [1u] == 'a') ? 1u /*Jan*/ \
310+
: (__DATE__ [2u] == 'b' ) ? 2u /*Feb*/ \
311+
: (__DATE__ [2u] == 'r' && __DATE__ [1u] == 'a') ? 3u /*Mar*/ \
312+
: (__DATE__ [2u] == 'r' ) ? 4u /*Apr*/ \
313+
: (__DATE__ [2u] == 'y' ) ? 5u /*May*/ \
314+
: (__DATE__ [2u] == 'n' ) ? 6u /*Jun*/ \
315+
: (__DATE__ [2u] == 'l' ) ? 7u /*Jul*/ \
316+
: (__DATE__ [2u] == 'g' ) ? 8u /*Jul*/ \
317+
: (__DATE__ [2u] == 'p' ) ? 9u /*Jul*/ \
318+
: (__DATE__ [2u] == 't' ) ? 10u /*Jul*/ \
319+
: (__DATE__ [2u] == 'v' ) ? 11u /*Jul*/ \
320+
: 12u /*Dec*/ )
321+
322+
#define __DAY_INT__ ( \
323+
(__DATE__ [4u] == ' ' ? 0u : __DATE__ [4u] - '0') * 10u \
324+
+ (__DATE__ [5u] - '0') )
325+
326+
#define __DOSDATE__ ( \
327+
((__YEAR_INT__ - 1980u) << 9u) | \
328+
( __MONTH_INT__ << 5u) | \
329+
( __DAY_INT__ << 0u) )
330+
331+
332+
#endif // COMPILE_DATE_H
333+

0 commit comments

Comments
 (0)