Raises file limit from 14 to 62 files.
Enable all four sectors of root directory to contain files.
This commit is contained in:
parent
8def8aee53
commit
53a99195bf
@ -9,6 +9,8 @@
|
||||
#include "bootloader_settings.h"
|
||||
#include "bootloader.h"
|
||||
|
||||
// #define CREATE_MANY_FILES
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t JumpInstruction[3];
|
||||
@ -48,7 +50,6 @@ typedef struct {
|
||||
uint16_t startCluster;
|
||||
uint32_t size;
|
||||
} __attribute__((packed)) DirEntry;
|
||||
|
||||
STATIC_ASSERT(sizeof(DirEntry) == 32);
|
||||
|
||||
struct TextFile {
|
||||
@ -78,9 +79,56 @@ const char indexFile[] = //
|
||||
"</body>"
|
||||
"</html>\n";
|
||||
|
||||
#ifdef CREATE_MANY_FILES
|
||||
const char dataFile00[] = "This is the data for File 00\r\n";
|
||||
const char dataFile01[] = "This is the data for File 01\r\n";
|
||||
const char dataFile02[] = "This is the data for File 02\r\n";
|
||||
const char dataFile03[] = "This is the data for File 03\r\n";
|
||||
const char dataFile04[] = "This is the data for File 04\r\n";
|
||||
const char dataFile05[] = "This is the data for File 05\r\n";
|
||||
const char dataFile06[] = "This is the data for File 06\r\n";
|
||||
const char dataFile07[] = "This is the data for File 07\r\n";
|
||||
const char dataFile08[] = "This is the data for File 08\r\n";
|
||||
const char dataFile09[] = "This is the data for File 09\r\n";
|
||||
const char dataFile10[] = "This is the data for File 10\r\n";
|
||||
const char dataFile11[] = "This is the data for File 11\r\n";
|
||||
const char dataFile12[] = "This is the data for File 12\r\n";
|
||||
const char dataFile13[] = "This is the data for File 13\r\n";
|
||||
const char dataFile14[] = "This is the data for File 14\r\n";
|
||||
const char dataFile15[] = "This is the data for File 15\r\n";
|
||||
const char dataFile16[] = "This is the data for File 16\r\n";
|
||||
const char dataFile17[] = "This is the data for File 17\r\n";
|
||||
const char dataFile18[] = "This is the data for File 18\r\n";
|
||||
const char dataFile19[] = "This is the data for File 19\r\n";
|
||||
#endif // CREATE_MANY_FILES
|
||||
|
||||
// WARNING -- code presumes only one NULL .content for .UF2 file
|
||||
// and requires it be the last element of the array
|
||||
static struct TextFile const info[] = {
|
||||
{.name = "INFO_UF2TXT", .content = infoUf2File},
|
||||
{.name = "INDEX HTM", .content = indexFile},
|
||||
#ifdef CREATE_MANY_FILES
|
||||
{.name = "FILE00 TXT", .content = dataFile00},
|
||||
{.name = "FILE01 TXT", .content = dataFile01},
|
||||
{.name = "FILE02 TXT", .content = dataFile02},
|
||||
{.name = "FILE03 TXT", .content = dataFile03},
|
||||
{.name = "FILE04 TXT", .content = dataFile04},
|
||||
{.name = "FILE05 TXT", .content = dataFile05},
|
||||
{.name = "FILE06 TXT", .content = dataFile06},
|
||||
{.name = "FILE07 TXT", .content = dataFile07},
|
||||
{.name = "FILE08 TXT", .content = dataFile08},
|
||||
{.name = "FILE09 TXT", .content = dataFile09},
|
||||
{.name = "FILE10 TXT", .content = dataFile10},
|
||||
{.name = "FILE11 TXT", .content = dataFile11},
|
||||
{.name = "FILE12 TXT", .content = dataFile12},
|
||||
{.name = "FILE13 TXT", .content = dataFile13},
|
||||
{.name = "FILE14 TXT", .content = dataFile14},
|
||||
{.name = "FILE15 TXT", .content = dataFile15},
|
||||
{.name = "FILE16 TXT", .content = dataFile16},
|
||||
{.name = "FILE17 TXT", .content = dataFile17},
|
||||
{.name = "FILE18 TXT", .content = dataFile18},
|
||||
{.name = "FILE19 TXT", .content = dataFile19},
|
||||
#endif
|
||||
{.name = "CURRENT UF2"},
|
||||
};
|
||||
|
||||
@ -110,8 +158,9 @@ STATIC_ASSERT(ARRAY_SIZE2(indexFile) < 512);
|
||||
|
||||
// all directory entries must fit in a single sector
|
||||
// because otherwise current code overflows buffer
|
||||
STATIC_ASSERT(NUM_DIRENTRIES < (512 / sizeof(DirEntry)));
|
||||
// STATIC_ASSERT(NUM_DIRENTRIES < (512 / sizeof(DirEntry)) * ROOT_DIR_SECTORS);
|
||||
#define DIRENTRIES_PER_SECTOR (512/sizeof(DirEntry))
|
||||
|
||||
STATIC_ASSERT(NUM_DIRENTRIES < DIRENTRIES_PER_SECTOR * ROOT_DIR_SECTORS);
|
||||
|
||||
|
||||
static FAT_BootBlock const BootBlock = {
|
||||
@ -121,7 +170,7 @@ static FAT_BootBlock const BootBlock = {
|
||||
.SectorsPerCluster = 1,
|
||||
.ReservedSectors = RESERVED_SECTORS,
|
||||
.FATCopies = 2,
|
||||
.RootDirectoryEntries = (ROOT_DIR_SECTORS * 512 / 32),
|
||||
.RootDirectoryEntries = (ROOT_DIR_SECTORS * DIRENTRIES_PER_SECTOR),
|
||||
.TotalSectors16 = NUM_FAT_BLOCKS - 2,
|
||||
.MediaDescriptor = 0xF8,
|
||||
.SectorsPerFAT = SECTORS_PER_FAT,
|
||||
@ -205,8 +254,11 @@ void read_block(uint32_t block_no, uint8_t *data) {
|
||||
sectionIdx -= SECTORS_PER_FAT;
|
||||
if (sectionIdx == 0) {
|
||||
data[0] = 0xf0;
|
||||
// WARNING -- code presumes only one NULL .content for .UF2 file
|
||||
// and all non-NULL .content fit in one sector
|
||||
// and requires it be the last element of the array
|
||||
for (int i = 1; i < NUM_FILES * 2 + 4; ++i) {
|
||||
data[i] = 0xff; // WARNING -- code presumes each non-UF2 file content fits in single sector
|
||||
data[i] = 0xff;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
@ -215,20 +267,33 @@ void read_block(uint32_t block_no, uint8_t *data) {
|
||||
((uint16_t *)(void *)data)[i] = v == UF2_LAST_SECTOR ? 0xffff : v + 1;
|
||||
}
|
||||
} else if (block_no < START_CLUSTERS) {
|
||||
// Use STATIC_ASSERT() above to ensure only first sector has entries
|
||||
|
||||
sectionIdx -= START_ROOTDIR;
|
||||
if (sectionIdx == 0) {
|
||||
|
||||
DirEntry *d = (void *)data;
|
||||
int remainingEntries = DIRENTRIES_PER_SECTOR;
|
||||
if (sectionIdx == 0) { // volume label first
|
||||
// volume label is first directory entry
|
||||
padded_memcpy(d->name, (char const *) BootBlock.VolumeLabel, 11);
|
||||
d->attrs = 0x28;
|
||||
for (int i = 0; i < NUM_FILES; ++i) {
|
||||
d++;
|
||||
struct TextFile const *inf = &info[i];
|
||||
remainingEntries--;
|
||||
}
|
||||
|
||||
for (int i = DIRENTRIES_PER_SECTOR * sectionIdx;
|
||||
remainingEntries > 0 && i < NUM_FILES;
|
||||
i++, d++) {
|
||||
struct TextFile const * inf = &info[i];
|
||||
// WARNING -- code presumes only one NULL .content for .UF2 file
|
||||
// and requires it be the last element of the array
|
||||
d->size = inf->content ? strlen(inf->content) : UF2_SIZE;
|
||||
d->startCluster = i + 2;
|
||||
padded_memcpy(d->name, inf->name, 11);
|
||||
// DIR_WrtTime and DIR_WrtDate must be supported
|
||||
d->updateDate = __DOSDATE__;
|
||||
d->lastAccessDate = __DOSDATE__;
|
||||
d->createDate = __DOSDATE__;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
sectionIdx -= START_CLUSTERS;
|
||||
if (sectionIdx < NUM_FILES - 1) {
|
||||
|
@ -296,3 +296,38 @@ static inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining
|
||||
#endif // ARRAYSIZE2_H
|
||||
|
||||
|
||||
#ifndef COMPILE_DATE_H
|
||||
#define COMPILE_DATE_H
|
||||
|
||||
#define __YEAR_INT__ ((( \
|
||||
(__DATE__ [ 7u] - '0') * 10u + \
|
||||
(__DATE__ [ 8u] - '0')) * 10u + \
|
||||
(__DATE__ [ 9u] - '0')) * 10u + \
|
||||
(__DATE__ [10u] - '0'))
|
||||
|
||||
#define __MONTH_INT__ ( \
|
||||
(__DATE__ [2u] == 'n' && __DATE__ [1u] == 'a') ? 1u /*Jan*/ \
|
||||
: (__DATE__ [2u] == 'b' ) ? 2u /*Feb*/ \
|
||||
: (__DATE__ [2u] == 'r' && __DATE__ [1u] == 'a') ? 3u /*Mar*/ \
|
||||
: (__DATE__ [2u] == 'r' ) ? 4u /*Apr*/ \
|
||||
: (__DATE__ [2u] == 'y' ) ? 5u /*May*/ \
|
||||
: (__DATE__ [2u] == 'n' ) ? 6u /*Jun*/ \
|
||||
: (__DATE__ [2u] == 'l' ) ? 7u /*Jul*/ \
|
||||
: (__DATE__ [2u] == 'g' ) ? 8u /*Jul*/ \
|
||||
: (__DATE__ [2u] == 'p' ) ? 9u /*Jul*/ \
|
||||
: (__DATE__ [2u] == 't' ) ? 10u /*Jul*/ \
|
||||
: (__DATE__ [2u] == 'v' ) ? 11u /*Jul*/ \
|
||||
: 12u /*Dec*/ )
|
||||
|
||||
#define __DAY_INT__ ( \
|
||||
(__DATE__ [4u] == ' ' ? 0u : __DATE__ [4u] - '0') * 10u \
|
||||
+ (__DATE__ [5u] - '0') )
|
||||
|
||||
#define __DOSDATE__ ( \
|
||||
((__YEAR_INT__ - 1980u) << 9u) | \
|
||||
( __MONTH_INT__ << 5u) | \
|
||||
( __DAY_INT__ << 0u) )
|
||||
|
||||
|
||||
#endif // COMPILE_DATE_H
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user