LCD Driver, some teensy code, SDCard code, MBR/FAT32
This commit is contained in:
100
ext/sd/fat32/FS.h
Normal file
100
ext/sd/fat32/FS.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Structs.h"
|
||||
|
||||
// https://www.pjrc.com/tech/8051/ide/fat32.html
|
||||
namespace FAT32 {
|
||||
|
||||
template <typename BlockDev> class FS {
|
||||
|
||||
static constexpr const char* NAME = "FAT32";
|
||||
|
||||
BlockDev& dev;
|
||||
AbsOffset offset;
|
||||
|
||||
|
||||
FSDesc desc;
|
||||
Precomputed tmp;
|
||||
bool valid = false;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
#include "File.h"
|
||||
#include "DirIterator.h"
|
||||
|
||||
/** ctor with the absolute offset addr (in bytes) */
|
||||
FS(BlockDev& dev, AbsOffset offset) : dev(dev), offset(offset) {
|
||||
init();
|
||||
}
|
||||
|
||||
/** is the detected FS valid? */
|
||||
bool isValid() const {
|
||||
return valid;
|
||||
}
|
||||
|
||||
/** get an iterator for the root directory */
|
||||
DirIterator getRoot() {
|
||||
return DirIterator(*this, desc.rootDirFirstCluster);
|
||||
}
|
||||
|
||||
/** open the given file for reading*/
|
||||
File open(const DirEntry& de) {
|
||||
return File(*this, de.getFirstCluster(), de.size);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init() {
|
||||
|
||||
debugMod3(NAME")
|
||||
uint8_t buf[512];
|
||||
dev.read(offset, 512, buf);
|
||||
|
||||
desc.bytesPerSector = getU16(&buf[0x0B]);
|
||||
desc.sectorsPerCluster = getU8(&buf[0x0D]);
|
||||
desc.numReservedSectors = getU16(&buf[0x0E]);
|
||||
desc.numberOfFATs = getU8(&buf[0x10]);
|
||||
desc.sectorsPerFAT = getU32(&buf[0x24]);
|
||||
desc.rootDirFirstCluster = getU32(&buf[0x2C]);
|
||||
|
||||
// basic sanity check based on constants
|
||||
valid = (desc.bytesPerSector == 512) && (desc.numberOfFATs == 2) && (getU16(&buf[0x1FE]) == 0xAA55);
|
||||
|
||||
tmp.bytesPerCluster = desc.sectorsPerCluster * desc.bytesPerSector;
|
||||
tmp.startOfFAT = offset + (desc.numReservedSectors * desc.bytesPerSector);
|
||||
tmp.startOfFirstDataCluster = offset + (desc.numReservedSectors * desc.bytesPerSector) + (desc.numberOfFATs * desc.sectorsPerFAT * desc.bytesPerSector);
|
||||
tmp.startOfFirstRootDirCluster = clusterToAbsPos(desc.rootDirFirstCluster);
|
||||
tmp.dirEntriesPerSector = desc.bytesPerSector / sizeof(DirEntry);
|
||||
|
||||
/*
|
||||
std::cout << (int)desc.bytesPerSector << std::endl;
|
||||
std::cout << (int)desc.sectorsPerCluster << std::endl;
|
||||
std::cout << (int)desc.numReservedSectors << std::endl;
|
||||
std::cout << (int)desc.numberOfFATs << std::endl;
|
||||
std::cout << (int)desc.sectorsPerFAT << std::endl;
|
||||
std::cout << (int)desc.rootDirFirstCluster << std::endl;
|
||||
|
||||
std::cout << tmp.startOfFAT << std::endl;
|
||||
std::cout << tmp.startOfFirstDataCluster << std::endl;
|
||||
std::cout << tmp.startOfFirstRootDirCluster << std::endl;
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/** determine the ClusterNr following the given ClusterNr */
|
||||
ClusterNr getNextCluster(ClusterNr clusterNr) {
|
||||
const AbsPos pos = tmp.startOfFAT + ((clusterNr) * sizeof(uint32_t));
|
||||
ClusterNr next;
|
||||
int read = dev.read(pos, 4, reinterpret_cast<uint8_t*>(&next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/** convert ClusterNr into an absolute position on disk */
|
||||
AbsPos clusterToAbsPos(ClusterNr clusterNr) {
|
||||
return tmp.startOfFirstDataCluster + ((clusterNr - 2) * desc.sectorsPerCluster * desc.bytesPerSector);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user