X-Git-Url: http://git.linex4red.de/pub/lufa.git/blobdiff_plain/ef7b6a274c9ea66d301d0b3b0d2f6de7cee2b0d1..0b1f33e2a26091714982447132b251496d5a48b2:/Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.c?ds=sidebyside diff --git a/Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.c b/Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.c deleted file mode 100644 index 0bcda0620..000000000 --- a/Bootloaders/Incomplete/MassStorage/Lib/VirtualFAT.c +++ /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++); -} -