Commit 9a97f16b authored by Dean Camera's avatar Dean Camera
Browse files

Add TMC header read and write functions, so that TMC data can now be exchanged in both directions.

Minor update to the LowLevel MassStorage device demo, so that the ReadInCommandBlock() performs the data OUT endpoint selection and packet arrival test.
parent 059307d8
......@@ -329,36 +329,36 @@ void TMC_Task(void)
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(TMC_OUT_EPNUM);
if (Endpoint_IsOUTReceived())
TMC_MessageHeader_t MessageHeader;
/* Check if a TMC packet has been received */
if (ReadTMCHeader(&MessageHeader))
{
TMC_MessageHeader_t MessageHeader;
Endpoint_Read_Stream_LE(&MessageHeader, sizeof(MessageHeader), StreamCallback_AbortOUTOnRequest);
CurrentTransferTag = MessageHeader.Tag;
/* Indicate busy */
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
switch (MessageHeader.MessageID)
{
case TMC_MESSAGEID_DEV_DEP_MSG_OUT:
Endpoint_Discard_Stream(MessageHeader.TransferSize, StreamCallback_AbortOUTOnRequest);
Endpoint_ClearOUT();
break;
case TMC_MESSAGEID_DEV_DEP_MSG_IN:
Endpoint_ClearOUT();
break;
case TMC_MESSAGEID_DEV_VENDOR_OUT:
break;
case TMC_MESSAGEID_DEV_VENDOR_IN:
MessageHeader.TransferSize = 3;
WriteTMCHeader(&MessageHeader);
Endpoint_Write_Stream_LE("TMC", 3, StreamCallback_AbortINOnRequest);
Endpoint_ClearIN();
break;
default:
Endpoint_StallTransaction();
break;
}
Endpoint_ClearOUT();
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/* All pending data has been processed - reset the data abort flags */
......@@ -366,6 +366,45 @@ void TMC_Task(void)
IsTMCBulkOUTReset = false;
}
bool ReadTMCHeader(TMC_MessageHeader_t* const MessageHeader)
{
/* Select the Data Out endpoint */
Endpoint_SelectEndpoint(TMC_OUT_EPNUM);
/* Abort if no command has been sent from the host */
if (!(Endpoint_IsOUTReceived()))
return false;
/* Read in the header of the command from the host */
Endpoint_Read_Stream_LE(MessageHeader, sizeof(TMC_MessageHeader_t), StreamCallback_AbortOUTOnRequest);
/* Store the new command tag value for later use */
CurrentTransferTag = MessageHeader->Tag;
/* Indicate if the command has been aborted or not */
return !IsTMCBulkOUTReset;
}
bool WriteTMCHeader(TMC_MessageHeader_t* const MessageHeader)
{
/* Compute the next transfer tag value, must be between 1 and 254 */
if (++CurrentTransferTag == 0xFF)
CurrentTransferTag = 1;
/* Set the message tag of the command header */
MessageHeader->Tag = CurrentTransferTag;
MessageHeader->InverseTag = ~CurrentTransferTag;
/* Select the Data In endpoint */
Endpoint_SelectEndpoint(TMC_IN_EPNUM);
/* Send the command header to the host */
Endpoint_Write_Stream_LE(MessageHeader, sizeof(TMC_MessageHeader_t), StreamCallback_AbortINOnRequest);
/* Indicate if the command has been aborted or not */
return !IsTMCBulkINReset;
}
/** Stream callback function for the Endpoint stream write functions. This callback will abort the current stream transfer
* if a TMC Abort Bulk IN request has been issued to the control endpoint.
*/
......
......@@ -45,17 +45,20 @@
/* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1
#define LEDMASK_USB_NOTREADY LEDS_LED1
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY LEDS_LED2
#define Req_InitiateAbortBulkOut 0x01
#define Req_CheckAbortBulkOutStatus 0x02
#define Req_InitiateAbortBulkIn 0x03
......@@ -139,6 +142,8 @@
/* Function Prototypes: */
void SetupHardware(void);
void TMC_Task(void);
bool ReadTMCHeader(TMC_MessageHeader_t* const MessageHeader);
bool WriteTMCHeader(TMC_MessageHeader_t* const MessageHeader);
void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void);
......
......@@ -173,47 +173,35 @@ void MassStorage_Task(void)
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
/* Select the Data Out Endpoint */
Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
/* Check to see if a command from the host has been issued */
if (Endpoint_IsReadWriteAllowed())
/* Process sent command block from the host if one has been sent */
if (ReadInCommandBlock())
{
/* Indicate busy */
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
/* Process sent command block from the host */
if (ReadInCommandBlock())
{
/* Check direction of command, select Data IN endpoint if data is from the device */
if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
/* Check direction of command, select Data IN endpoint if data is from the device */
if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
/* Decode the received SCSI command, set returned status code */
CommandStatus.Status = SCSI_DecodeSCSICommand() ? Command_Pass : Command_Fail;
/* Decode the received SCSI command, set returned status code */
CommandStatus.Status = SCSI_DecodeSCSICommand() ? Command_Pass : Command_Fail;
/* Load in the CBW tag into the CSW to link them together */
CommandStatus.Tag = CommandBlock.Tag;
/* Load in the CBW tag into the CSW to link them together */
CommandStatus.Tag = CommandBlock.Tag;
/* Load in the data residue counter into the CSW */
CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength;
/* Stall the selected data pipe if command failed (if data is still to be transferred) */
if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))
Endpoint_StallTransaction();
/* Return command status block to the host */
ReturnCommandStatus();
/* Indicate ready */
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
else
{
/* Indicate error reading in the command block from the host */
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/* Load in the data residue counter into the CSW */
CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength;
/* Stall the selected data pipe if command failed (if data is still to be transferred) */
if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))
Endpoint_StallTransaction();
/* Return command status block to the host */
ReturnCommandStatus();
/* Indicate ready */
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
/* Check if a Mass Storage Reset occurred */
......@@ -244,6 +232,10 @@ static bool ReadInCommandBlock(void)
{
/* Select the Data Out endpoint */
Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
/* Abort if no command has been sent from the host */
if (!(Endpoint_IsOUTReceived()))
return false;
/* Read in command block header */
Endpoint_Read_Stream_LE(&CommandBlock, (sizeof(CommandBlock) - sizeof(CommandBlock.SCSICommandData)),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment