Rewrote the implementation of the SwapEndian_16() and SwapEndian_32() functions so that they compile down in most instances to minimal loads and stores rather than complicated shifts.

Fixed SCSI.c implementations of all the demos/projects casting the block count to a 32-bit temporary before calling SwapEndian_16().
pull/1469/head
Dean Camera 15 years ago
parent 2b0e86243f
commit c326fe9605

@ -160,7 +160,7 @@ static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -257,7 +257,7 @@ static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo
BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */ /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
TotalBlocks = SwapEndian_16(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
/* Check if the block address is outside the maximum allowable value for the LUN */ /* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= LUN_MEDIA_BLOCKS) if (BlockAddress >= LUN_MEDIA_BLOCKS)

@ -170,7 +170,7 @@ static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -196,7 +196,7 @@ static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInf
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
@ -306,15 +306,11 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo
uint32_t BlockAddress; uint32_t BlockAddress;
uint16_t TotalBlocks; uint16_t TotalBlocks;
/* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */ /* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
((uint8_t*)&BlockAddress)[3] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]; BlockAddress = SwapEndian_32(*(uint32_t*)&CommandBlock.SCSICommandData[2]);
((uint8_t*)&BlockAddress)[2] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[3];
((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
((uint8_t*)&BlockAddress)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[5];
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */ /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
((uint8_t*)&TotalBlocks)[1] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]; TotalBlocks = SwapEndian_16(*(uint16_t*)&CommandBlock.SCSICommandData[7]);
((uint8_t*)&TotalBlocks)[0] = MSInterfaceInfo->State.CommandBlock.SCSICommandData[8];
/* Check if the block address is outside the maximum allowable value for the LUN */ /* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= LUN_MEDIA_BLOCKS) if (BlockAddress >= LUN_MEDIA_BLOCKS)

@ -159,7 +159,7 @@ static void SCSI_Command_Inquiry(void)
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), StreamCallback_AbortOnMassStoreReset);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -182,7 +182,7 @@ static void SCSI_Command_Request_Sense(void)
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), StreamCallback_AbortOnMassStoreReset);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -256,15 +256,11 @@ static void SCSI_Command_ReadWrite_10(const bool IsDataRead)
uint32_t BlockAddress; uint32_t BlockAddress;
uint16_t TotalBlocks; uint16_t TotalBlocks;
/* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */ /* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
((uint8_t*)&BlockAddress)[3] = CommandBlock.SCSICommandData[2]; BlockAddress = SwapEndian_32(*(uint32_t*)&CommandBlock.SCSICommandData[2]);
((uint8_t*)&BlockAddress)[2] = CommandBlock.SCSICommandData[3];
((uint8_t*)&BlockAddress)[1] = CommandBlock.SCSICommandData[4];
((uint8_t*)&BlockAddress)[0] = CommandBlock.SCSICommandData[5];
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */ /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
((uint8_t*)&TotalBlocks)[1] = CommandBlock.SCSICommandData[7]; TotalBlocks = SwapEndian_16(*(uint16_t*)&CommandBlock.SCSICommandData[7]);
((uint8_t*)&TotalBlocks)[0] = CommandBlock.SCSICommandData[8];
/* Check if the block address is outside the maximum allowable value for the LUN */ /* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= LUN_MEDIA_BLOCKS) if (BlockAddress >= LUN_MEDIA_BLOCKS)

@ -174,7 +174,21 @@
static inline uint16_t SwapEndian_16(uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST; static inline uint16_t SwapEndian_16(uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
static inline uint16_t SwapEndian_16(uint16_t Word) static inline uint16_t SwapEndian_16(uint16_t Word)
{ {
return ((Word >> 8) | (Word << 8)); uint8_t Temp;
union
{
uint16_t Word;
uint8_t Bytes[2];
} Data;
Data.Word = Word;
Temp = Data.Bytes[0];
Data.Bytes[0] = Data.Bytes[1];
Data.Bytes[1] = Temp;
return Data.Word;
} }
/** Function to reverse the byte ordering of the individual bytes in a 32 bit number. /** Function to reverse the byte ordering of the individual bytes in a 32 bit number.
@ -186,10 +200,25 @@
static inline uint32_t SwapEndian_32(uint32_t DWord) ATTR_WARN_UNUSED_RESULT ATTR_CONST; static inline uint32_t SwapEndian_32(uint32_t DWord) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
static inline uint32_t SwapEndian_32(uint32_t DWord) static inline uint32_t SwapEndian_32(uint32_t DWord)
{ {
return (((DWord & 0xFF000000) >> 24) | uint8_t Temp;
((DWord & 0x00FF0000) >> 8) |
((DWord & 0x0000FF00) << 8) | union
((DWord & 0x000000FF) << 24)); {
uint32_t DWord;
uint8_t Bytes[4];
} Data;
Data.DWord = DWord;
Temp = Data.Bytes[0];
Data.Bytes[0] = Data.Bytes[3];
Data.Bytes[3] = Temp;
Temp = Data.Bytes[1];
Data.Bytes[1] = Data.Bytes[2];
Data.Bytes[2] = Temp;
return Data.DWord;
} }
/** Function to reverse the byte ordering of the individual bytes in a n byte number. /** Function to reverse the byte ordering of the individual bytes in a n byte number.

@ -25,6 +25,8 @@
* - Removed unused line encoding data and control requests from the CDC Bootloader code, to save space * - Removed unused line encoding data and control requests from the CDC Bootloader code, to save space
* - Renamed SERIAL_STREAM_ASSERT() macro to STDOUT_ASSERT() * - Renamed SERIAL_STREAM_ASSERT() macro to STDOUT_ASSERT()
* - The USB_Device_IsRemoteWakeupSent() and USB_Device_IsUSBSuspended() macros have been deleted, as they are now obsolete * - The USB_Device_IsRemoteWakeupSent() and USB_Device_IsUSBSuspended() macros have been deleted, as they are now obsolete
* - Rewrote the implementation of the SwapEndian_16() and SwapEndian_32() functions so that they compile down in most instances to
* minimal loads and stores rather than complicated shifts
* *
* <b>Fixed:</b> * <b>Fixed:</b>
* - Fixed AVRISP project sending a LOAD EXTENDED ADDRESS command to 128KB AVRs after programming or reading from * - Fixed AVRISP project sending a LOAD EXTENDED ADDRESS command to 128KB AVRs after programming or reading from

@ -161,7 +161,7 @@ static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInf
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -183,7 +183,7 @@ static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterf
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
@ -258,7 +258,7 @@ static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */ /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
TotalBlocks = SwapEndian_16(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
/* Check if the block address is outside the maximum allowable value for the LUN */ /* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS) if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS)

@ -160,7 +160,7 @@ static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInf
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -182,7 +182,7 @@ static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterf
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
@ -257,7 +257,7 @@ static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */ /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
TotalBlocks = SwapEndian_16(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
/* Check if the block address is outside the maximum allowable value for the LUN */ /* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS) if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS)

@ -160,7 +160,7 @@ static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInf
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */ /* Pad out remaining bytes with 0x00 */
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
/* Finalize the stream transfer to send the last packet */ /* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -182,7 +182,7 @@ static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterf
uint8_t PadBytes[AllocationLength - BytesTransferred]; uint8_t PadBytes[AllocationLength - BytesTransferred];
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK); Endpoint_Write_Stream_LE(&PadBytes, sizeof(PadBytes), NO_STREAM_CALLBACK);
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */ /* Succeed the command and update the bytes transferred counter */
@ -257,7 +257,7 @@ static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */ /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
TotalBlocks = SwapEndian_16(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
/* Check if the block address is outside the maximum allowable value for the LUN */ /* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS) if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS)

Loading…
Cancel
Save