Move out the Mass Storage class bootloader to the main Bootloader directory now that...
[pub/lufa.git] / Bootloaders / Incomplete / MassStorage / Lib / VirtualFAT.c
diff --git a/Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.c b/Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.c
deleted file mode 100644 (file)
index 0bcda06..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
-             LUFA Library
-     Copyright (C) Dean Camera, 2013.
-
-  dean [at] fourwalledcubicle [dot] com
-           www.lufa-lib.org
-*/
-
-/*
-  Copyright 2013  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
-  without fee, provided that the above copyright notice appear in
-  all copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting
-  documentation, and that the name of the author not be used in
-  advertising or publicity pertaining to distribution of the
-  software without specific, written prior permission.
-
-  The author disclaims all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-/** \file
- *
- *  Virtualized FAT12 filesystem implementation, to perform self-programming
- *  in response to read and write requests to the virtual filesystem by the
- *  host PC.
- */
-
-#define  INCLUDE_FROM_VIRTUAL_FAT_C
-#include "VirtualFAT.h"
-
-/** FAT filesystem boot sector block, must be the first sector on the physical
- *  disk so that the host can identify the presence of a FAT filesystem. This
- *  block is truncated; normally a large bootstrap section is located near the
- *  end of the block for booting purposes however as this is not meant to be a
- *  bootable disk it is omitted for space reasons.
- *
- *  \note When returning the boot block to the host, the magic signature 0xAA55
- *        must be added to the very end of the block to identify it as a boot
- *        block.
- */
-static const FATBootBlock_t BootBlock =
-       {
-               .Bootstrap               = {0xEB, 0x3C, 0x90},
-               .Description             = "mkdosfs",
-               .SectorSize              = SECTOR_SIZE_BYTES,
-               .SectorsPerCluster       = SECTOR_PER_CLUSTER,
-               .ReservedSectors         = 1,
-               .FATCopies               = 2,
-               .RootDirectoryEntries    = (SECTOR_SIZE_BYTES / sizeof(FATDirectoryEntry_t)),
-               .TotalSectors16          = LUN_MEDIA_BLOCKS,
-               .MediaDescriptor         = 0xF8,
-               .SectorsPerFAT           = 1,
-               .SectorsPerTrack         = (LUN_MEDIA_BLOCKS % 64),
-               .Heads                   = (LUN_MEDIA_BLOCKS / 64),
-               .HiddenSectors           = 0,
-               .TotalSectors32          = 0,
-               .PhysicalDriveNum        = 0,
-               .ExtendedBootRecordSig   = 0x29,
-               .VolumeSerialNumber      = 0x12345678,
-               .VolumeLabel             = "LUFA BOOT  ",
-               .FilesystemIdentifier    = "FAT12   ",
-       };
-
-/** FAT 8.3 style directory entry, for the virtual FLASH contents file. */
-static FATDirectoryEntry_t FirmwareFileEntry =
-       {
-               .Filename               = "FIRMWARE",
-               .Extension              = "BIN",
-               .Attributes             = 0,
-               .Reserved               = {0},
-               .CreationTime           = FAT_TIME(1, 1, 0),
-               .CreationDate           = FAT_DATE(14, 2, 1989),
-               .StartingCluster        = 2,
-               .FileSizeBytes          = FIRMWARE_FILE_SIZE_BYTES,
-       };
-
-
-/** Updates a FAT12 cluster entry in the FAT file table with the specified next
- *  chain index. If the cluster is the last in the file chain, the magic value
- *  0xFFF is used.
- *
- *  \note FAT data cluster indexes are offset by 2, so that cluster 2 is the
- *        first file data cluster on the disk. See the FAT specification.
- *
- *  \param[out]  FATTable    Pointer to the FAT12 allocation table
- *  \param[in]   Index       Index of the cluster entry to update
- *  \param[in]   ChainEntry  Next cluster index in the file chain
- */
-static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
-                                    const uint16_t Index,
-                                    const uint16_t ChainEntry)
-{
-       /* Calculate the starting offset of the cluster entry in the FAT12 table */
-       uint8_t FATOffset   =   (Index * 3) / 2;
-       bool    UpperNibble = (((Index * 3) % 2) != 0);
-
-       /* Check if the start of the entry is at an upper nibble of the byte, fill
-        * out FAT12 entry as required */
-       if (UpperNibble)
-       {
-               FATTable[FATOffset]     = (FATTable[FATOffset] & 0x0F) | ((ChainEntry & 0x0F) << 4);
-               FATTable[FATOffset + 1] = (ChainEntry >> 4);
-       }
-       else
-       {
-               FATTable[FATOffset]     = ChainEntry;
-               FATTable[FATOffset + 1] = (FATTable[FATOffset] & 0xF0) | (ChainEntry >> 8);
-       }
-}
-
-/** Writes a block of data to the virtual FAT filesystem, from the USB Mass
- *  Storage interface.
- *
- *  \param[in]  BlockNumber  Index of the block to write.
- */
-static void WriteVirtualBlock(const uint16_t BlockNumber)
-{
-       uint8_t BlockBuffer[SECTOR_SIZE_BYTES];
-
-       /* Buffer the entire block to be written from the host */
-       Endpoint_Read_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL);
-       Endpoint_ClearOUT();
-
-       if ((BlockNumber >= 4) && (BlockNumber < (4 + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES))))
-       {
-               uint32_t WriteFlashAddress = (uint32_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES;
-
-               for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i += 2)
-               {
-                       if ((WriteFlashAddress % SPM_PAGESIZE) == 0)
-                       {
-                               /* Erase the given FLASH page, ready to be programmed */
-                               boot_page_erase(WriteFlashAddress);
-                               boot_spm_busy_wait();
-                       }
-
-                       /* Write the next data word to the FLASH page */
-                       boot_page_fill(WriteFlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]);
-                       WriteFlashAddress += 2;
-
-                       if ((WriteFlashAddress % SPM_PAGESIZE) == 0)
-                       {
-                               /* Write the filled FLASH page to memory */
-                               boot_page_write(WriteFlashAddress - SPM_PAGESIZE);
-                               boot_spm_busy_wait();
-                       }
-               }
-       }
-}
-
-/** Reads a block of data from the virtual FAT filesystem, and sends it to the
- *  host via the USB Mass Storage interface.
- *
- *  \param[in]  BlockNumber  Index of the block to read.
- */
-static void ReadVirtualBlock(const uint16_t BlockNumber)
-{
-       uint8_t BlockBuffer[SECTOR_SIZE_BYTES];
-       memset(BlockBuffer, 0x00, sizeof(BlockBuffer));
-
-       switch (BlockNumber)
-       {
-               case 0: /* Block 0: Boot block sector */
-                       memcpy(BlockBuffer, &BootBlock, sizeof(FATBootBlock_t));
-
-                       /* Add the magic signature to the end of the block */
-                       BlockBuffer[SECTOR_SIZE_BYTES - 2] = 0x55;
-                       BlockBuffer[SECTOR_SIZE_BYTES - 1] = 0xAA;
-                       break;
-
-               case 1: /* Block 1: First FAT12 cluster chain copy */
-               case 2: /* Block 2: Second FAT12 cluster chain copy */
-                       /* Cluster 0: Media type/Reserved */
-                       UpdateFAT12ClusterEntry(BlockBuffer, 0, 0xF00 | BootBlock.MediaDescriptor);
-
-                       /* Cluster 1: Reserved */
-                       UpdateFAT12ClusterEntry(BlockBuffer, 1, 0xFFF);
-
-                       /* Cluster 2 onwards: Cluster chain of FIRMWARE.BIN */
-                       for (uint16_t i = 0; i < FILE_CLUSTERS(FIRMWARE_FILE_SIZE_BYTES); i++)
-                         UpdateFAT12ClusterEntry(BlockBuffer, i+2, i+3);
-
-                       /* Mark last cluster as end of file */
-                       UpdateFAT12ClusterEntry(BlockBuffer, FILE_CLUSTERS(FIRMWARE_FILE_SIZE_BYTES) + 1, 0xFFF);
-                       break;
-
-               case 3: /* Block 3: Root file entries */
-                       memcpy(BlockBuffer, &FirmwareFileEntry, sizeof(FATDirectoryEntry_t));
-                       break;
-
-               default: /* Blocks 4 onwards: Data allocation section */
-                       if ((BlockNumber >= 4) && (BlockNumber < (4 + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES))))
-                       {
-                               uint32_t ReadFlashAddress = (uint32_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES;
-
-                               for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
-                                 BlockBuffer[i] = pgm_read_byte_far(ReadFlashAddress++);
-                       }
-
-                       break;
-       }
-
-       /* Write the entire read block Buffer to the host */
-       Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL);
-       Endpoint_ClearIN();
-}
-
-/** Writes a number of blocks to the virtual FAT file system, from the host
- *  PC via the USB Mass Storage interface.
- *
- *  \param[in] MSInterfaceInfo  Pointer to a structure containing a Mass Storage Class configuration and state
- *  \param[in] BlockAddress  Data block starting address for the write sequence
- *  \param[in] TotalBlocks   Number of blocks of data to write
- */
-void VirtualFAT_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
-                            const uint32_t BlockAddress,
-                            uint16_t TotalBlocks)
-{
-       uint16_t CurrentBlock = (uint16_t)BlockAddress;
-
-       /* Emulated FAT is performed per-block, pass each requested block index
-        * to the emulated FAT block write function */
-       while (TotalBlocks--)
-         WriteVirtualBlock(CurrentBlock++);
-}
-
-/** Reads a number of blocks from the virtual FAT file system, and sends them
- *  to the host PC via the USB Mass Storage interface.
- *
- *  \param[in] MSInterfaceInfo  Pointer to a structure containing a Mass Storage Class configuration and state
- *  \param[in] BlockAddress  Data block starting address for the read sequence
- *  \param[in] TotalBlocks   Number of blocks of data to read
- */
-void VirtualFAT_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
-                           const uint32_t BlockAddress,
-                           uint16_t TotalBlocks)
-{
-       uint16_t CurrentBlock = (uint16_t)BlockAddress;
-
-       /* Emulated FAT is performed per-block, pass each requested block index
-        * to the emulated FAT block read function */
-       while (TotalBlocks--)
-         ReadVirtualBlock(CurrentBlock++);
-}
-