X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/169f21fbb158a07ee628d86f3c20339fcf490939..3642ea0b9715cdf0196b10c9fc97898940eaefa6:/Bootloaders/MassStorage/Lib/VirtualFAT.h diff --git a/Bootloaders/MassStorage/Lib/VirtualFAT.h b/Bootloaders/MassStorage/Lib/VirtualFAT.h index 440b65d1a..cc4d69260 100644 --- a/Bootloaders/MassStorage/Lib/VirtualFAT.h +++ b/Bootloaders/MassStorage/Lib/VirtualFAT.h @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2013. + Copyright (C) Dean Camera, 2015. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* - Copyright 2013 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -40,8 +40,11 @@ #include "../BootloaderAPI.h" /* Macros: */ - /** Size of the virtual FIRMWARE.BIN file in bytes. */ - #define FIRMWARE_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR) - AUX_BOOT_SECTION_SIZE) + /** Size of the virtual FLASH.BIN file in bytes. */ + #define FLASH_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR) - AUX_BOOT_SECTION_SIZE) + + /** Size of the virtual EEPROM.BIN file in bytes. */ + #define EEPROM_FILE_SIZE_BYTES E2END /** Number of sectors that comprise a single logical disk cluster. */ #define SECTOR_PER_CLUSTER 4 @@ -69,7 +72,7 @@ #define FILE_CLUSTERS(size) ((size / CLUSTER_SIZE_BYTES) + ((size % CLUSTER_SIZE_BYTES) ? 1 : 0)) /** Total number of logical sectors/blocks on the disk. */ - #define LUN_MEDIA_BLOCKS (FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES) + 32) + #define LUN_MEDIA_BLOCKS (FILE_SECTORS(FLASH_FILE_SIZE_BYTES) + FILE_SECTORS(EEPROM_FILE_SIZE_BYTES) + 32) /** Converts a given time in HH:MM:SS format to a FAT filesystem time. * @@ -94,6 +97,34 @@ */ #define FAT_DATE(dd, mm, yyyy) (((yyyy - 1980) << 9) | (mm << 5) | (dd << 0)) + /** Bit-rotates a given 8-bit value once to the right. + * + * \param[in] x Value to rotate right once + * + * \return Bit-rotated input value, rotated once to the right. + */ + #define ROT8(x) ((((x) & 0xFE) >> 1) | (((x) & 1) ? 0x80 : 0x00)) + + /** Computes the LFN entry checksum of a MSDOS 8.3 format file entry, + * to associate a LFN entry with its short file entry. + * + * \param[in] n0 MSDOS Filename character 1 + * \param[in] n1 MSDOS Filename character 2 + * \param[in] n2 MSDOS Filename character 3 + * \param[in] n3 MSDOS Filename character 4 + * \param[in] n4 MSDOS Filename character 5 + * \param[in] n5 MSDOS Filename character 6 + * \param[in] n6 MSDOS Filename character 7 + * \param[in] n7 MSDOS Filename character 8 + * \param[in] e0 MSDOS Extension character 1 + * \param[in] e1 MSDOS Extension character 2 + * \param[in] e2 MSDOS Extension character 3 + * + * \return LFN checksum of the given MSDOS 8.3 filename. + */ + #define FAT_CHECKSUM(n0, n1, n2, n3, n4, n5, n6, n7, e0, e1, e2) \ + (uint8_t)(ROT8(ROT8(ROT8(ROT8(ROT8(ROT8(ROT8(ROT8(ROT8(ROT8(n0)+n1)+n2)+n3)+n4)+n5)+n6)+n7)+e0)+e1)+e2) + /** \name FAT Filesystem Flags */ //@{ /** FAT attribute flag to indicate a read-only file. */ @@ -121,13 +152,46 @@ #define FAT_ORDINAL_LAST_ENTRY (1 << 6) //@} + /* Enums: */ + /** Enum for the Root FAT file entry indexes on the disk. This can be used + * to retrieve the current contents of a known directory entry. + */ + enum + { + /** Volume ID directory entry, giving the name of the virtual disk. */ + DISK_FILE_ENTRY_VolumeID = 0, + /** Long File Name FAT file entry of the virtual FLASH.BIN image file. */ + DISK_FILE_ENTRY_FLASH_LFN = 1, + /** Legacy MSDOS FAT file entry of the virtual FLASH.BIN image file. */ + DISK_FILE_ENTRY_FLASH_MSDOS = 2, + /** Long File Name FAT file entry of the virtual EEPROM.BIN image file. */ + DISK_FILE_ENTRY_EEPROM_LFN = 3, + /** Legacy MSDOS FAT file entry of the virtual EEPROM.BIN image file. */ + DISK_FILE_ENTRY_EEPROM_MSDOS = 4, + }; + + /** Enum for the physical disk blocks of the virtual disk. */ + enum + { + /** Boot sector disk block. */ + DISK_BLOCK_BootBlock = 0, + /** First copy of the FAT table block. */ + DISK_BLOCK_FATBlock1 = 1, + /** Second copy of the FAT table block. */ + DISK_BLOCK_FATBlock2 = 2, + /** Root file and directory entries block. */ + DISK_BLOCK_RootFilesBlock = 3, + /** Start block of the disk data section. */ + DISK_BLOCK_DataStartBlock = 4, + }; + /* Type Definitions: */ /** FAT boot block structure definition, used to identify the core - * parameters of a FAT filesystem stored on a disk. + * parameters of a FAT file system stored on a disk. * * \note This definition is truncated to save space; the magic signature - * 0xAA55 must be appended to the very end of the block for it to - * be detected by the host as a valid boot block. + * \c 0xAA55 must be appended to the very end of the block for it + * to be detected by the host as a valid boot block. */ typedef struct { @@ -154,11 +218,12 @@ /* uint16_t MagicSignature; */ } FATBootBlock_t; - /** FAT legacy 8.3 style directory entry structure definition, used to - * identify the files and folders of FAT filesystem stored on a disk. + /** FAT directory entry structure, for the various kinds of File and + * directory descriptors on a FAT disk. */ typedef union { + /** VFAT Long File Name file entry. */ struct { uint8_t Ordinal; @@ -179,8 +244,9 @@ uint16_t Reserved2; uint16_t Unicode12; uint16_t Unicode13; - } VFAT; + } VFAT_LongFileName; + /** Legacy FAT MSDOS 8.3 file entry. */ struct { uint8_t Filename[8]; @@ -191,21 +257,46 @@ uint16_t CreationDate; uint16_t StartingCluster; uint32_t FileSizeBytes; - } MSDOS; + } MSDOS_File; + + /** Legacy FAT MSDOS (sub-)directory entry. */ + struct + { + uint8_t Name[11]; + uint8_t Attributes; + uint8_t Reserved[10]; + uint16_t CreationTime; + uint16_t CreationDate; + uint16_t StartingCluster; + uint32_t Reserved2; + } MSDOS_Directory; } FATDirectoryEntry_t; /* Function Prototypes: */ #if defined(INCLUDE_FROM_VIRTUAL_FAT_C) + static uint8_t ReadEEPROMByte(const uint8_t* const Address) ATTR_NO_INLINE; + + static void WriteEEPROMByte(uint8_t* const Address, + const uint8_t Data) ATTR_NO_INLINE; + static void UpdateFAT12ClusterEntry(uint8_t* const FATTable, const uint16_t Index, const uint16_t ChainEntry) AUX_BOOT_SECTION; - static void WriteVirtualBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; - static void ReadVirtualBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; + + static void UpdateFAT12ClusterChain(uint8_t* const FATTable, + const uint16_t StartIndex, + const uint8_t ChainLength) AUX_BOOT_SECTION; + + static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber, + uint8_t* BlockBuffer, + const bool Read) AUX_BOOT_SECTION; + + static void ReadWriteEEPROMFileBlock(const uint16_t BlockNumber, + uint8_t* BlockBuffer, + const bool Read) AUX_BOOT_SECTION; #endif - void VirtualFAT_WriteBlocks(const uint16_t BlockAddress, - uint16_t TotalBlocks) AUX_BOOT_SECTION; + void VirtualFAT_WriteBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; + void VirtualFAT_ReadBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; - void VirtualFAT_ReadBlocks(const uint16_t BlockAddress, - uint16_t TotalBlocks) AUX_BOOT_SECTION; #endif