Added priority elevation to Downstream USB host processing code that

interacts with SPI.

It elevates to USB_OTG priority to avoid preemption by SPI, DMA, or USB
interrupts thus avoiding synchronisation issues between USB host stack
and SPI interface.

Also minor improvements to Downstream error handling.
pull/7/head
Robert Fisk 9 years ago
parent c1b2c191c4
commit fc522bae0a

@ -32,6 +32,13 @@ typedef enum
} while (0);
#define DOWNSTREAM_STATEMACHINE_FREAKOUT_NORETURN \
do { \
LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
DownstreamState = STATE_ERROR; \
} while (0);
void Downstream_InitStateMachine(void);

@ -42,6 +42,7 @@
#include "usbh_msc.h"
#include "usbh_msc_bot.h"
#include "usbh_msc_scsi.h"
#include "interrupts.h"
/** @addtogroup USBH_LIB
@ -498,6 +499,10 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
case MSC_READ:
case MSC_WRITE:
//USBH_MSC_RdWrProcess interacts heavily with downstream SPI code.
//So to protect against preemption we elevate our priority here.
__set_BASEPRI(INT_PRIORITY_OTG_FS);
error = USBH_MSC_RdWrProcess(phost, MSC_Handle->rw_lun);
if(((int32_t)(phost->Timer - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0))
{
@ -513,6 +518,8 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
MSC_Handle->RdWrCompleteCallback = NULL;
}
}
__set_BASEPRI(0);
break;
default:

@ -388,6 +388,12 @@ void USBH_MSC_BOT_Read_FreePacketCallback(DownstreamPacketTypeDef* freePacket)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (MSC_Handle->hbot.state != BOT_DATA_IN_WAIT)
{
Downstream_PacketProcessor_FreakOut();
return;
}
MSC_Handle->hbot.bot_packet = freePacket;
MSC_Handle->hbot.pbuf = freePacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = BOT_PAGE_LENGTH;
@ -421,6 +427,12 @@ void USBH_MSC_BOT_Write_ReceivePacketCallback(DownstreamPacketTypeDef* receivedP
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (MSC_Handle->hbot.state != BOT_DATA_OUT_WAIT)
{
Downstream_PacketProcessor_FreakOut();
return;
}
MSC_Handle->hbot.bot_packet = receivedPacket;
MSC_Handle->hbot.pbuf = receivedPacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength;

@ -13,6 +13,7 @@
#include "usbh_core.h"
#include "usbh_msc.h"
#include "led.h"
#include "interrupts.h"
@ -153,9 +154,9 @@ void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket)
}
//This callback receives various event ids from the host stack, either
//at INT_PRIORITY_OTG_FS or from main(). We should therefore be prepared
//for pre-emption by USB or SPI/DMA interrupts.
//This callback receives various event ids from the host stack,
//either at INT_PRIORITY_OTG_FS or from main().
//We should therefore elevate our execution priority to INT_PRIORITY_OTG_FS where necessary.
void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
{
InterfaceCommandClassTypeDef newActiveClass = COMMAND_CLASS_INTERFACE;
@ -172,7 +173,19 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
return;
}
//Called from main(). Beware pre-emption!
//Elevate our priority level so we aren't interrupted
__set_BASEPRI(INT_PRIORITY_OTG_FS);
//Called from main()
if (id == HOST_USER_UNRECOVERED_ERROR)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT_NORETURN;
__set_BASEPRI(0);
return;
}
//Called from main()
if (id == HOST_USER_CLASS_ACTIVE)
{
switch (phost->pActiveClass->ClassCode)
@ -186,11 +199,12 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
//Add other classes here...
//Any unsupported device will cause a slow fault flash.
//Unsupported device classes will cause a slow fault flash.
//This is distinct from the fast freakout flash caused by internal errors or attacks.
default:
LED_Fault_SetBlinkRate(LED_SLOW_BLINK_RATE);
DownstreamState = STATE_ERROR;
__set_BASEPRI(0);
return;
}
@ -198,7 +212,9 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
//If the new device has failed its 'approval' checks, we are sufficiently freaked out.
if (newActiveClass == COMMAND_CLASS_INTERFACE)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
DOWNSTREAM_STATEMACHINE_FREAKOUT_NORETURN;
__set_BASEPRI(0);
return;
}
//If we already configured a device class, we cannot change to a different one without rebooting.
@ -206,23 +222,29 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
if ((ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE) &&
(ConfiguredDeviceClass != newActiveClass))
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
DOWNSTREAM_STATEMACHINE_FREAKOUT_NORETURN;
__set_BASEPRI(0);
return;
}
ConfiguredDeviceClass = newActiveClass;
if (DownstreamState == STATE_WAIT_DEVICE_READY)
{
Downstream_GetFreePacket(Downstream_PacketProcessor_Interface_ReplyNotifyDevice);
__set_BASEPRI(0);
return;
}
if (DownstreamState == STATE_DEVICE_NOT_READY)
{
DownstreamState = STATE_DEVICE_READY;
__set_BASEPRI(0);
return;
}
DOWNSTREAM_STATEMACHINE_FREAKOUT;
DOWNSTREAM_STATEMACHINE_FREAKOUT_NORETURN;
__set_BASEPRI(0);
return;
}
}

Loading…
Cancel
Save