Update Studio Integration DLL, to include package logging.
[pub/USBasp.git] / Bootloaders / MassStorage / Lib / VirtualFAT.h
index 440b65d..cc4d692 100644 (file)
@@ -1,13 +1,13 @@
 /*
              LUFA Library
 /*
              LUFA Library
-     Copyright (C) Dean Camera, 2013.
+     Copyright (C) Dean Camera, 2015.
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
 
   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
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
                #include "../BootloaderAPI.h"
 
        /* Macros: */
                #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
 
                /** 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 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.
                 *
 
                /** Converts a given time in HH:MM:SS format to a FAT filesystem time.
                 *
                 */
                #define FAT_DATE(dd, mm, yyyy)    (((yyyy - 1980) << 9) | (mm << 5) | (dd << 0))
 
                 */
                #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. */
                /** \name FAT Filesystem Flags */
                //@{
                /** FAT attribute flag to indicate a read-only file. */
                #define FAT_ORDINAL_LAST_ENTRY    (1 << 6)
                //@}
 
                #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
        /* 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
                 *
                 *  \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
                {
                 */
                typedef struct
                {
                        /* uint16_t MagicSignature; */
                } FATBootBlock_t;
 
                        /* 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
                {
                 */
                typedef union
                {
+                       /** VFAT Long File Name file entry. */
                        struct
                        {
                                uint8_t  Ordinal;
                        struct
                        {
                                uint8_t  Ordinal;
                                uint16_t Reserved2;
                                uint16_t Unicode12;
                                uint16_t Unicode13;
                                uint16_t Reserved2;
                                uint16_t Unicode12;
                                uint16_t Unicode13;
-                       } VFAT;
+                       } VFAT_LongFileName;
 
 
+                       /** Legacy FAT MSDOS 8.3 file entry. */
                        struct
                        {
                                uint8_t  Filename[8];
                        struct
                        {
                                uint8_t  Filename[8];
                                uint16_t CreationDate;
                                uint16_t StartingCluster;
                                uint32_t FileSizeBytes;
                                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)
                } 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 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
 
                #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
 #endif