Update Mass Storage bootloader so that it can support devices with only 4KB bootloader sections by creating a special AUX section before the real bootloader section to store part of the bootloader code.
This commit is contained in:
parent
f8a1dc7424
commit
be33d3a515
12 changed files with 136 additions and 109 deletions
|
@ -104,9 +104,6 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
|||
case SCSI_CMD_READ_CAPACITY_10:
|
||||
CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
||||
CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_WRITE_10:
|
||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
|
||||
break;
|
||||
|
@ -116,6 +113,7 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
|||
case SCSI_CMD_MODE_SENSE_6:
|
||||
CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
||||
case SCSI_CMD_START_STOP_UNIT:
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
|
@ -227,33 +225,6 @@ static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInt
|
|||
return true;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the
|
||||
* board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is
|
||||
* supported.
|
||||
*
|
||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
||||
*
|
||||
* \return Boolean true if the command completed successfully, false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
/* Check to see if the SELF TEST bit is not set */
|
||||
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
|
||||
{
|
||||
/* Only self-test supported - update SENSE key and fail the command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address
|
||||
* and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual
|
||||
* reading and writing of the data.
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "../BootloaderMassStorage.h"
|
||||
#include "../Descriptors.h"
|
||||
#include "VirtualFAT.h"
|
||||
|
||||
|
@ -69,16 +68,15 @@
|
|||
#define DEVICE_TYPE_BLOCK 0x00
|
||||
|
||||
/* Function Prototypes: */
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
|
||||
#if defined(INCLUDE_FROM_SCSI_C)
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
||||
const bool IsDataRead);
|
||||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
||||
const bool IsDataRead) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -151,26 +151,28 @@ static void WriteVirtualBlock(const uint16_t BlockNumber)
|
|||
|
||||
if ((BlockNumber >= 4) && (BlockNumber < (4 + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES))))
|
||||
{
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
uint32_t WriteFlashAddress = (uint32_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES;
|
||||
#else
|
||||
uint16_t WriteFlashAddress = (uint16_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES;
|
||||
#endif
|
||||
|
||||
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();
|
||||
BootloaderAPI_ErasePage(WriteFlashAddress);
|
||||
}
|
||||
|
||||
/* Write the next data word to the FLASH page */
|
||||
boot_page_fill(WriteFlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]);
|
||||
BootloaderAPI_FillWord(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();
|
||||
BootloaderAPI_WritePage(WriteFlashAddress - SPM_PAGESIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,10 +221,17 @@ static void ReadVirtualBlock(const uint16_t BlockNumber)
|
|||
default: /* Blocks 4 onwards: Data allocation section */
|
||||
if ((BlockNumber >= 4) && (BlockNumber < (4 + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES))))
|
||||
{
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
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++);
|
||||
#else
|
||||
uint16_t ReadFlashAddress = (uint16_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES;
|
||||
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||
BlockBuffer[i] = pgm_read_byte(ReadFlashAddress++);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -237,8 +246,8 @@ static void ReadVirtualBlock(const uint16_t BlockNumber)
|
|||
* 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
|
||||
* \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,
|
||||
|
@ -256,8 +265,8 @@ void VirtualFAT_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
|||
* 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
|
||||
* \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,
|
||||
|
|
|
@ -37,9 +37,11 @@
|
|||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "../BootloaderAPI.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Size of the virtual FIRMWARE.BIN file in bytes. */
|
||||
#define FIRMWARE_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR))
|
||||
#define FIRMWARE_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR) - AUX_BOOT_SECTION_SIZE)
|
||||
|
||||
/** Number of sectors that comprise a single logical disk cluster. */
|
||||
#define SECTOR_PER_CLUSTER 4
|
||||
|
@ -144,16 +146,16 @@
|
|||
#if defined(INCLUDE_FROM_VIRTUAL_FAT_C)
|
||||
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
|
||||
const uint16_t Index,
|
||||
const uint16_t ChainEntry);
|
||||
static void WriteVirtualBlock(const uint16_t BlockNumber);
|
||||
static void ReadVirtualBlock(const uint16_t BlockNumber);
|
||||
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;
|
||||
#endif
|
||||
|
||||
void VirtualFAT_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
||||
const uint32_t BlockAddress,
|
||||
uint16_t TotalBlocks);
|
||||
uint16_t TotalBlocks) AUX_BOOT_SECTION;
|
||||
|
||||
void VirtualFAT_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
||||
const uint32_t BlockAddress,
|
||||
uint16_t TotalBlocks);
|
||||
uint16_t TotalBlocks) AUX_BOOT_SECTION;
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue