Commit e071f389 authored by Dean Camera's avatar Dean Camera
Browse files

Added new USB_DeviceState variable to keep track of the current Device mode USB state.

Added new Endpoint_ClearStatusStage() convenience function to assist with the status stages of control transfers.

Removed vague USB_IsConnected global - test USB_DeviceState or USB_HostState explicitly to gain previous functionality.

Removed USB_IsSuspended global - test USB_DeviceState against DEVICE_STATE_Suspended instead.

Fixed possible enumeration errors from spinloops which may fail to exit if the USB connection is severed before the exit condition becomes true.
parent 44179abc
......@@ -165,9 +165,7 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearIN();
/* Acknowledge status stage */
while (!(Endpoint_IsOUTReceived()));
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
}
break;
......@@ -176,16 +174,18 @@ void EVENT_USB_UnhandledControlPacket(void)
{
Endpoint_ClearSETUP();
while (!(Endpoint_IsOUTReceived()));
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
for (uint8_t i = 0; i < sizeof(LineCoding); i++)
*(LineCodingData++) = Endpoint_Read_Byte();
Endpoint_ClearOUT();
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
......@@ -194,9 +194,7 @@ void EVENT_USB_UnhandledControlPacket(void)
{
Endpoint_ClearSETUP();
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
......@@ -333,7 +331,12 @@ static uint8_t FetchNextCommandByte(void)
while (!(Endpoint_IsReadWriteAllowed()))
{
Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived()));
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return 0;
}
}
/* Fetch the next byte from the OUT endpoint */
......@@ -354,7 +357,12 @@ static void WriteNextResponseByte(const uint8_t Response)
if (!(Endpoint_IsReadWriteAllowed()))
{
Endpoint_ClearIN();
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Write the next byte to the OUT endpoint */
......@@ -563,12 +571,21 @@ void CDC_Task(void)
/* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */
if (IsEndpointFull)
{
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
Endpoint_ClearIN();
}
/* Wait until the data has been sent to the host */
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Select the OUT endpoint */
Endpoint_SelectEndpoint(CDC_RX_EPNUM);
......
......@@ -177,7 +177,11 @@ void EVENT_USB_UnhandledControlPacket(void)
/* If the request has a data stage, load it into the command struct */
if (SentCommand.DataSize)
{
while (!(Endpoint_IsOUTReceived()));
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* First byte of the data stage is the DNLOAD request's command */
SentCommand.Command = Endpoint_Read_Byte();
......@@ -235,7 +239,12 @@ void EVENT_USB_UnhandledControlPacket(void)
if (!(Endpoint_BytesInEndpoint()))
{
Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived()));
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Write the next word into the current flash page */
......@@ -279,7 +288,12 @@ void EVENT_USB_UnhandledControlPacket(void)
if (!(Endpoint_BytesInEndpoint()))
{
Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived()));
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Read the byte from the USB interface and write to to the EEPROM */
......@@ -297,16 +311,18 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearOUT();
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
break;
case DFU_UPLOAD:
Endpoint_ClearSETUP();
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
if (DFU_State != dfuUPLOAD_IDLE)
{
if ((DFU_State == dfuERROR) && IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Blank Check
......@@ -343,7 +359,12 @@ void EVENT_USB_UnhandledControlPacket(void)
if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE)
{
Endpoint_ClearIN();
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Read the flash word and send it via USB to the host */
......@@ -368,7 +389,12 @@ void EVENT_USB_UnhandledControlPacket(void)
if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE)
{
Endpoint_ClearIN();
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Read the EEPROM byte and send it via USB to the host */
......@@ -385,10 +411,7 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearIN();
/* Acknowledge status stage */
while (!(Endpoint_IsOUTReceived()));
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
break;
case DFU_GETSTATUS:
Endpoint_ClearSETUP();
......@@ -408,10 +431,7 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearIN();
/* Acknowledge status stage */
while (!(Endpoint_IsOUTReceived()));
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
break;
case DFU_CLRSTATUS:
Endpoint_ClearSETUP();
......@@ -419,10 +439,7 @@ void EVENT_USB_UnhandledControlPacket(void)
/* Reset the status value variable to the default OK status */
DFU_Status = OK;
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
break;
case DFU_GETSTATE:
Endpoint_ClearSETUP();
......@@ -432,21 +449,15 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearIN();
/* Acknowledge status stage */
while (!(Endpoint_IsOUTReceived()));
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
break;
case DFU_ABORT:
Endpoint_ClearSETUP();
/* Reset the current state variable to the default idle state */
DFU_State = dfuIDLE;
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
break;
}
}
......@@ -465,7 +476,11 @@ static void DiscardFillerBytes(uint8_t NumberOfBytes)
Endpoint_ClearOUT();
/* Wait until next data packet received */
while (!(Endpoint_IsOUTReceived()));
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
else
{
......
......@@ -119,7 +119,7 @@ void EVENT_USB_UnhandledControlPacket(void)
/* Wait until the command (report) has been sent by the host */
while (!(Endpoint_IsOUTReceived()));
/* Read in the write destination address */
uint16_t PageAddress = Endpoint_Read_Word_LE();
......@@ -158,9 +158,7 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearOUT();
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
......
......@@ -69,7 +69,11 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
Dataflash_SendAddressBytes(0, CurrDFPageByte);
/* Wait until endpoint is ready before continuing */
while (!(Endpoint_IsReadWriteAllowed()));
while (!(Endpoint_IsReadWriteAllowed()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
while (TotalBlocks)
{
......@@ -85,7 +89,11 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
Endpoint_ClearOUT();
/* Wait until the host has sent another packet */
while (!(Endpoint_IsReadWriteAllowed()));
while (!(Endpoint_IsReadWriteAllowed()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Check if end of dataflash page reached */
......@@ -197,7 +205,11 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con
Dataflash_SendByte(0x00);
/* Wait until endpoint is ready before continuing */
while (!(Endpoint_IsReadWriteAllowed()));
while (!(Endpoint_IsReadWriteAllowed()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
while (TotalBlocks)
{
......@@ -213,7 +225,11 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con
Endpoint_ClearIN();
/* Wait until the endpoint is ready for more data */
while (!(Endpoint_IsReadWriteAllowed()));
while (!(Endpoint_IsReadWriteAllowed()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Check if end of dataflash page reached */
......
......@@ -152,7 +152,7 @@ void EVENT_USB_UnhandledControlPacket(void)
*/
ISR(USART1_RX_vect, ISR_BLOCK)
{
if (USB_IsConnected)
if (USB_DeviceState == DEVICE_STATE_Configured)
Buffer_StoreElement(&Tx_Buffer, UDR1);
}
......
......@@ -142,7 +142,7 @@ void EVENT_USB_UnhandledControlPacket(void)
void SideShow_Task(void)
{
/* Device must be connected and configured for the task to run */
if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
/* Select the SideShow data out endpoint */
......
......@@ -139,9 +139,7 @@ void EVENT_USB_UnhandledControlPacket(void)
/* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0);
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
......@@ -152,7 +150,7 @@ void EVENT_USB_UnhandledControlPacket(void)
void USB_Audio_Task(void)
{
/* Device must be connected and configured for the task to run */
if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
/* Check to see if the streaming interface is selected, if not the host is not receiving audio */
......
......@@ -166,9 +166,7 @@ void EVENT_USB_UnhandledControlPacket(void)
/* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0);
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
......@@ -181,7 +179,7 @@ void EVENT_USB_UnhandledControlPacket(void)
void USB_Audio_Task(void)
{
/* Device must be connected and configured for the task to run */
if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
/* Check to see if the streaming interface is selected, if not the host is not receiving audio */
......
......@@ -56,12 +56,15 @@ CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,
*/
static int CDC_putchar (char c, FILE *stream)
{
if (!(USB_IsConnected))
return -1;
{
Endpoint_SelectEndpoint(CDC_TX_EPNUM);
while (!(Endpoint_IsReadWriteAllowed()));
while (!(Endpoint_IsReadWriteAllowed()))
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return -1;
}
Endpoint_Write_Byte(c);
Endpoint_ClearIN();
......@@ -76,10 +79,11 @@ static int CDC_getchar (FILE *stream)
for (;;)
{
if (!(USB_IsConnected))
return -1;
while (!(Endpoint_IsReadWriteAllowed()));
while (!(Endpoint_IsReadWriteAllowed()))
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return -1;
}
if (!(Endpoint_BytesInEndpoint()))
{
......@@ -229,9 +233,7 @@ void EVENT_USB_UnhandledControlPacket(void)
CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
*/
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
......@@ -244,18 +246,17 @@ void CDC_Task(void)
char* ReportString = NULL;
uint8_t JoyStatus_LCL = Joystick_GetStatus();
static bool ActionSent = false;
char* JoystickStrings[] =
{
"Joystick Up\r\n",
"Joystick Down\r\n",
"Joystick Left\r\n",
"Joystick Right\r\n",
"Joystick Pressed\r\n",
};
char* JoystickStrings[] =
{
"Joystick Up\r\n",
"Joystick Down\r\n",
"Joystick Left\r\n",
"Joystick Right\r\n",
"Joystick Pressed\r\n",
};
/* Device must be connected and configured for the task to run */
if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
#if 0
......@@ -319,7 +320,11 @@ void CDC_Task(void)
if (IsFull)
{
/* Wait until the endpoint is ready for another packet */
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Send an empty packet to ensure that the host does not buffer data sent to it */
Endpoint_ClearIN();
......
......@@ -211,9 +211,7 @@ void EVENT_USB_UnhandledControlPacket(void)
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP();
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
Endpoint_ClearStatusStage();
}
break;
......@@ -228,20 +226,19 @@ void CDC1_Task(void)
char* ReportString = NULL;
uint8_t JoyStatus_LCL = Joystick_GetStatus();
static bool ActionSent = false;
char* JoystickStrings[] =
{
"Joystick Up\r\n",
"Joystick Down\r\n",
"Joystick Left\r\n",
"Joystick Right\r\n",
"Joystick Pressed\r\n",
};
/* Device must be connected and configured for the task to run */
if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
char* JoystickStrings[] =
{
"Joystick Up\r\n",
"Joystick Down\r\n",
"Joystick Left\r\n",
"Joystick Right\r\n",
"Joystick Pressed\r\n",
};
/* Determine if a joystick action has occurred */
if (JoyStatus_LCL & JOY_UP)
ReportString = JoystickStrings[0];
......@@ -273,7 +270,11 @@ void CDC1_Task(void)
Endpoint_ClearIN();
/* Wait until the endpoint is ready for another packet */
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Send an empty packet to ensure that the host does not buffer data sent to it */
Endpoint_ClearIN();
......@@ -293,7 +294,7 @@ void CDC1_Task(void)
void CDC2_Task(void)
{
/* Device must be connected and configured for the task to run */
if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
/* Select the Serial Rx Endpoint */
......@@ -324,7 +325,11 @@ void CDC2_Task(void)
Endpoint_ClearIN();
/* Wait until the endpoint is ready for the next packet */
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Send an empty packet to prevent host buffering */
Endpoint_ClearIN();
......
......@@ -148,7 +148,11 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearSETUP();
/* Wait until the generic report has been sent by the host */
while (!(Endpoint_IsOUTReceived()));
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
Endpoint_Read_Control_Stream_LE(&GenericData, sizeof(GenericData));
......@@ -158,7 +162,11 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearOUT();
/* Wait until the host is ready to receive the request confirmation */
while (!(Endpoint_IsINReady()));
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Handshake the request by sending an empty IN packet */
Endpoint_ClearIN();
......@@ -203,7 +211,7 @@ void CreateGenericHIDReport(uint8_t* DataArray)
void HID_Task(void)
{
/* Device must be connected and configured for the task to run */
if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM);
......
......@@ -182,7 +182,7 @@ bool GetNextReport(USB_JoystickReport_Data_t* ReportData)
void HID_Task(void)
{
/* Device must be connected and configured for the task to run */
if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
/* Select the Joystick Report Endpoint */
......
......@@ -172,7 +172,11 @@ void EVENT_USB_UnhandledControlPacket(void)
Endpoint_ClearSETUP();
/* Wait until the LED report has been sent by the host */
while (!(Endpoint_IsOUTReceived()));
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Read in the LED report from the host */
uint8_t LEDStatus = Endpoint_Read_Byte();
......@@ -183,9 +187,7 @@ void EVENT_USB_UnhandledControlPacket(void)
/* Clear the endpoint data */
Endpoint_ClearOUT();
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
En