Improved Downstream error handling:

- More sensible handling of error cases on SPI interface
- Improved Freakout macros
- Implemented automatic fault LED blinking
pull/7/head
Robert Fisk 9 years ago
parent 0e1fed6047
commit c1b2c191c4

@ -35,6 +35,11 @@
#define STAT_LED_ON (STAT_LED_PORT->BSRR = (STAT_LED_PIN << BSRR_SHIFT_LOW)) //Stat LED is active-low #define STAT_LED_ON (STAT_LED_PORT->BSRR = (STAT_LED_PIN << BSRR_SHIFT_LOW)) //Stat LED is active-low
#define STAT_LED_OFF (STAT_LED_PORT->BSRR = (STAT_LED_PIN << BSRR_SHIFT_HIGH)) #define STAT_LED_OFF (STAT_LED_PORT->BSRR = (STAT_LED_PIN << BSRR_SHIFT_HIGH))
//#define RUN_LED_ON......
#define FAULT_LED_ON STAT_LED_ON
#define FAULT_LED_OFF STAT_LED_OFF
//#define SPI_DMA_ACTIVE_PIN GPIO_PIN_5 /////////Temporary indicator of SPI & DMA activity //#define SPI_DMA_ACTIVE_PIN GPIO_PIN_5 /////////Temporary indicator of SPI & DMA activity
//#define SPI_DMA_ACTIVE_PORT GPIOB //#define SPI_DMA_ACTIVE_PORT GPIOB
//#define SPI_DMA_ACTIVE_ON SPI_DMA_ACTIVE_PORT->BSRR = (SPI_DMA_ACTIVE_PIN << BSRR_SHIFT_LOW) //#define SPI_DMA_ACTIVE_ON SPI_DMA_ACTIVE_PORT->BSRR = (SPI_DMA_ACTIVE_PIN << BSRR_SHIFT_LOW)

@ -16,8 +16,7 @@
#define MSC_FIXED_LUN 0 #define MSC_FIXED_LUN 0
typedef void (*DownstreamMSCCallbackPacketTypeDef)(HAL_StatusTypeDef result, typedef void (*DownstreamMSCCallbackPacketTypeDef)(DownstreamPacketTypeDef* receivedPacket,
DownstreamPacketTypeDef* receivedPacket,
uint16_t dataLength); uint16_t dataLength);

@ -17,25 +17,23 @@
#define DOWNSTREAM_PACKET_LEN_MIN (DOWNSTREAM_PACKET_HEADER_LEN) #define DOWNSTREAM_PACKET_LEN_MIN (DOWNSTREAM_PACKET_HEADER_LEN)
#define SPI_INTERFACE_FREAKOUT_RETURN_VOID \ #define DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID \
do { \ do { \
while (1); \ LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
/*UpstreamInterfaceState = INTERFACE_STATE_ERROR;*/ \ Downstream_PacketProcessor_SetErrorState(); \
/*return;*/ \ DownstreamInterfaceState = DOWNSTREAM_INTERFACE_ERROR; \
} while (0); while (1); \
/*return;*/ \
#define SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR \ } while (0);
do { \
while (1); \ #define DOWNSTREAM_SPI_FREAKOUT_RETURN_HAL_ERROR \
/*UpstreamInterfaceState = INTERFACE_STATE_ERROR;*/ \ do { \
/*return HAL_ERROR;*/ \ LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
} while (0); Downstream_PacketProcessor_SetErrorState(); \
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_ERROR; \
#define SPI_INTERFACE_FREAKOUT_NO_RETURN \ while (1); \
do { \ /*return HAL_ERROR;*/ \
while (1); \ } while (0);
/*while (1);*/ \
} while (0);

@ -16,19 +16,31 @@
typedef enum typedef enum
{ {
STATE_DEVICE_NOT_READY, STATE_DEVICE_NOT_READY,
STATE_DEVICE_READY, //HOST_USER_CLASS_ACTIVE callback arrives first STATE_DEVICE_READY, //Go here if HOST_USER_CLASS_ACTIVE callback arrives first
STATE_WAIT_DEVICE_READY, //COMMAND_INTERFACE_NOTIFY_DEVICE message arrives first STATE_WAIT_DEVICE_READY, //Go here if COMMAND_INTERFACE_NOTIFY_DEVICE message arrives first
STATE_ACTIVE, STATE_ACTIVE,
STATE_ERROR STATE_ERROR
} DownstreamStateTypeDef; } DownstreamStateTypeDef;
#define DOWNSTREAM_STATEMACHINE_FREAKOUT \
do { \
LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
DownstreamState = STATE_ERROR; \
return; \
} while (0);
void Downstream_InitStateMachine(void); void Downstream_InitStateMachine(void);
void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id); void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id);
void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket); void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
void Downstream_PacketProcessor_ErrorReply(DownstreamPacketTypeDef* replyPacket); void Downstream_PacketProcessor_ErrorReply(DownstreamPacketTypeDef* replyPacket);
void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket); void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket);
void Downstream_PacketProcessor_SetErrorState(void);
void Downstream_PacketProcessor_FreakOut(void);
#endif /* INC_DOWNSTREAM_STATEMACHINE_H_ */ #endif /* INC_DOWNSTREAM_STATEMACHINE_H_ */

@ -0,0 +1,26 @@
/*
* led.h
*
* Created on: 19/08/2015
* Author: Robert Fisk
*/
#ifndef INC_LED_H_
#define INC_LED_H_
void LED_Init(void);
void LED_Fault_SetBlinkRate(uint16_t newBlinkRate);
void LED_DoBlinks(void);
#define STARTUP_FLASH_DELAY 500 //units = ticks = ms
//LEDs are on for BLINK_RATE ticks, then off for BLINK_RATE ticks
#define LED_FAST_BLINK_RATE 100
#define LED_SLOW_BLINK_RATE 500
#endif /* INC_LED_H_ */

@ -37,8 +37,7 @@ static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost); static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost);
void USBH_MSC_BOT_Read_FreePacketCallback(DownstreamPacketTypeDef* freePacket); void USBH_MSC_BOT_Read_FreePacketCallback(DownstreamPacketTypeDef* freePacket);
void USBH_MSC_BOT_Read_PrepareURB(USBH_HandleTypeDef *phost); void USBH_MSC_BOT_Read_PrepareURB(USBH_HandleTypeDef *phost);
void USBH_MSC_BOT_Write_ReceivePacketCallback(HAL_StatusTypeDef result, void USBH_MSC_BOT_Write_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket,
DownstreamPacketTypeDef* receivedPacket,
uint16_t dataLength); uint16_t dataLength);
void USBH_MSC_BOT_Write_PrepareURB(USBH_HandleTypeDef *phost); void USBH_MSC_BOT_Write_PrepareURB(USBH_HandleTypeDef *phost);
@ -178,8 +177,11 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
case BOT_DATA_IN: case BOT_DATA_IN:
/* Get first packet */ /* Get first packet */
Callback_MSC_phost = phost; Callback_MSC_phost = phost;
Downstream_GetFreePacket(USBH_MSC_BOT_Read_FreePacketCallback); MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT; if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_FreePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
}
break; break;
case BOT_DATA_IN_WAIT: case BOT_DATA_IN_WAIT:
@ -189,6 +191,7 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
{ {
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size; MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size; MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
MSC_Handle->hbot.pbuf += MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0) if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
{ {
@ -218,7 +221,6 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
else else
{ {
//Continue filling the current bot_packet //Continue filling the current bot_packet
MSC_Handle->hbot.pbuf += MSC_Handle->hbot.this_URB_size;
USBH_MSC_BOT_Read_PrepareURB(phost); USBH_MSC_BOT_Read_PrepareURB(phost);
} }
} }
@ -254,6 +256,7 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
{ {
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size; MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size; MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
MSC_Handle->hbot.pbuf += MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0) if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
{ {
@ -268,14 +271,12 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
//Get next bot_packet //Get next bot_packet
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_ReceivePacketCallback) != HAL_OK) if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_ReceivePacketCallback) != HAL_OK)
{ {
MSC_Handle->hbot.state = BOT_ERROR_IN; MSC_Handle->hbot.state = BOT_ERROR_OUT;
break;
} }
} }
else else
{ {
//Continue reading the current bot_packet //Continue reading the current bot_packet
MSC_Handle->hbot.pbuf += MSC_Handle->hbot.this_URB_size;
USBH_MSC_BOT_Write_PrepareURB(phost); USBH_MSC_BOT_Write_PrepareURB(phost);
} }
} }
@ -415,18 +416,11 @@ void USBH_MSC_BOT_Read_PrepareURB(USBH_HandleTypeDef *phost)
} }
void USBH_MSC_BOT_Write_ReceivePacketCallback(HAL_StatusTypeDef result, void USBH_MSC_BOT_Write_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket,
DownstreamPacketTypeDef* receivedPacket,
uint16_t dataLength) uint16_t dataLength)
{ {
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (result != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
return;
}
MSC_Handle->hbot.bot_packet = receivedPacket; MSC_Handle->hbot.bot_packet = receivedPacket;
MSC_Handle->hbot.pbuf = receivedPacket->Data; MSC_Handle->hbot.pbuf = receivedPacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength; MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength;

@ -40,13 +40,11 @@ HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void)
if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) || if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) ||
(MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX)) (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX))
{ {
//FreakOut?????
return HAL_ERROR; return HAL_ERROR;
} }
if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE) if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE)
{ {
//FreakOut?????
return HAL_ERROR; return HAL_ERROR;
} }
@ -75,8 +73,7 @@ void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
break; break;
default: default:
//FreakOut????? Downstream_PacketProcessor_FreakOut();
Downstream_PacketProcessor_ErrorReply(receivedPacket);
} }
} }
@ -118,8 +115,7 @@ void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedP
if (receivedPacket->Length != (DOWNSTREAM_PACKET_HEADER_LEN + (4 * 3))) if (receivedPacket->Length != (DOWNSTREAM_PACKET_HEADER_LEN + (4 * 3)))
{ {
//FreakOut????? Downstream_PacketProcessor_FreakOut();
Downstream_PacketProcessor_ErrorReply(receivedPacket);
return; return;
} }
@ -130,8 +126,7 @@ void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedP
((readBlockAddress + readBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || ((readBlockAddress + readBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
(readByteCount > UINT32_MAX)) (readByteCount > UINT32_MAX))
{ {
//FreakOut????? Downstream_PacketProcessor_FreakOut();
Downstream_PacketProcessor_ErrorReply(receivedPacket);
return; return;
} }
@ -173,8 +168,7 @@ void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* received
if (receivedPacket->Length != (DOWNSTREAM_PACKET_HEADER_LEN + (4 * 3))) if (receivedPacket->Length != (DOWNSTREAM_PACKET_HEADER_LEN + (4 * 3)))
{ {
//FreakOut????? Downstream_PacketProcessor_FreakOut();
Downstream_PacketProcessor_ErrorReply(receivedPacket);
return; return;
} }
@ -185,8 +179,7 @@ void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* received
((writeBlockAddress + writeBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || ((writeBlockAddress + writeBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
(writeByteCount > UINT32_MAX)) (writeByteCount > UINT32_MAX))
{ {
//FreakOut????? Downstream_PacketProcessor_FreakOut();
Downstream_PacketProcessor_ErrorReply(receivedPacket);
return; return;
} }
@ -214,7 +207,7 @@ void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* received
} }
//Used by USB MSC host driver
HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend, HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend,
uint32_t dataLength) uint32_t dataLength)
{ {
@ -225,6 +218,7 @@ HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* pa
} }
//Used by USB MSC host driver
HAL_StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback) HAL_StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback)
{ {
GetStreamDataCallback = callback; GetStreamDataCallback = callback;
@ -260,14 +254,13 @@ void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* replyPa
(replyPacket->Length <= DOWNSTREAM_PACKET_HEADER_LEN) || //Should be at least one data byte in the packet. (replyPacket->Length <= DOWNSTREAM_PACKET_HEADER_LEN) || //Should be at least one data byte in the packet.
(replyPacket->Length > ByteCount)) (replyPacket->Length > ByteCount))
{ {
//FreakOut????? Downstream_PacketProcessor_FreakOut();
GetStreamDataCallback(HAL_ERROR, NULL, NULL);
return; return;
} }
dataLength = replyPacket->Length - DOWNSTREAM_PACKET_HEADER_LEN; dataLength = replyPacket->Length - DOWNSTREAM_PACKET_HEADER_LEN;
ByteCount -= dataLength; ByteCount -= dataLength;
GetStreamDataCallback(HAL_OK, replyPacket, dataLength); //usb_msc_scsi will use this packet, so don't release now GetStreamDataCallback(replyPacket, dataLength); //usb_msc_scsi will use this packet, so don't release now
if (ByteCount > 0) if (ByteCount > 0)
{ {
Downstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it Downstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it

@ -6,20 +6,22 @@
*/ */
#include <downstream_interface_def.h> #include "downstream_interface_def.h"
#include <downstream_spi.h> #include "downstream_spi.h"
#include "downstream_statemachine.h"
#include "board_config.h" #include "board_config.h"
#include "led.h"
SPI_HandleTypeDef Hspi1; SPI_HandleTypeDef Hspi1;
DownstreamPacketTypeDef DownstreamPacket0; DownstreamPacketTypeDef DownstreamPacket0;
DownstreamPacketTypeDef DownstreamPacket1; DownstreamPacketTypeDef DownstreamPacket1;
DownstreamPacketTypeDef* CurrentWorkingPacket; DownstreamPacketTypeDef* CurrentWorkingPacket;
DownstreamPacketTypeDef* NextTxPacket; DownstreamPacketTypeDef* NextTxPacket = NULL;
InterfaceStateTypeDef DownstreamInterfaceState; InterfaceStateTypeDef DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
FreePacketCallbackTypeDef PendingFreePacketCallback; //Indicates someone is waiting for a packet buffer to become available FreePacketCallbackTypeDef PendingFreePacketCallback = NULL; //Indicates someone is waiting for a packet buffer to become available
SpiPacketReceivedCallbackTypeDef ReceivePacketCallback; //Indicates someone is waiting for a received packet SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates someone is waiting for a received packet
@ -35,11 +37,6 @@ void Downstream_InitSPI(void)
DownstreamPacket0.Busy = NOT_BUSY; DownstreamPacket0.Busy = NOT_BUSY;
DownstreamPacket1.Busy = NOT_BUSY; DownstreamPacket1.Busy = NOT_BUSY;
NextTxPacket = NULL;
PendingFreePacketCallback = NULL;
ReceivePacketCallback = NULL;
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
} }
@ -61,19 +58,18 @@ void SPI1_Init(void)
} }
//Used by... //Used by downstream state machine and USB host classes.
HAL_StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback) HAL_StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback)
{ {
//Sanity checks
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; return HAL_ERROR;
} }
//Do we already have a queued callback? //Do we already have a queued callback?
if (PendingFreePacketCallback != NULL) if (PendingFreePacketCallback != NULL)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; DOWNSTREAM_SPI_FREAKOUT_RETURN_HAL_ERROR;
} }
//Check if there is a free buffer now //Check if there is a free buffer now
@ -96,40 +92,20 @@ HAL_StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback)
} }
//DownstreamPacketTypeDef* Downstream_GetFreePacketImmediately(void) //Used by Downstream state machine and USB host classes.
//{
// //Sanity checks
// if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
// {
// SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR;
// }
//
// //We are expecting a free buffer now
// if (DownstreamPacket0.Busy == NOT_BUSY)
// {
// DownstreamPacket0.Busy = BUSY;
// return &DownstreamPacket0;
// }
// if (DownstreamPacket1.Busy == NOT_BUSY)
// {
// DownstreamPacket1.Busy = BUSY;
// return &DownstreamPacket1;
// }
//
// //Should not happen:
// SPI_INTERFACE_FREAKOUT_NO_RETURN;
//}
//Used by...
void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease) void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease)
{ {
FreePacketCallbackTypeDef tempCallback; FreePacketCallbackTypeDef tempCallback;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
if ((packetToRelease != &DownstreamPacket0) && if ((packetToRelease != &DownstreamPacket0) &&
(packetToRelease != &DownstreamPacket1)) (packetToRelease != &DownstreamPacket1))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
if (PendingFreePacketCallback != NULL) if (PendingFreePacketCallback != NULL)
@ -146,14 +122,19 @@ void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease)
//Used by Downstream state machine (and USB classes?). //Used by Downstream state machine and USB classes.
//Ok to call when idle or transmitting. //Ok to call when idle or transmitting.
//Not OK to call when receiving or awaiting reception. //Not OK to call when receiving or awaiting reception.
HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback) HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback)
{ {
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if (ReceivePacketCallback != NULL) if (ReceivePacketCallback != NULL)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; DOWNSTREAM_SPI_FREAKOUT_RETURN_HAL_ERROR;
} }
ReceivePacketCallback = callback; ReceivePacketCallback = callback;
return Downstream_CheckPreparePacketReception(); return Downstream_CheckPreparePacketReception();
@ -163,11 +144,6 @@ HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef call
//Internal use only //Internal use only
HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void) HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void)
{ {
if (DownstreamInterfaceState > DOWNSTREAM_INTERFACE_TX_PACKET_WAIT)
{
SPI_INTERFACE_FREAKOUT_RETURN_VOID;
}
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_IDLE) if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_IDLE)
{ {
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_SIZE_WAIT; DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_SIZE_WAIT;
@ -182,7 +158,7 @@ void Downstream_PreparePacketReception(DownstreamPacketTypeDef* freePacket)
{ {
if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_RX_SIZE_WAIT)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
CurrentWorkingPacket = freePacket; CurrentWorkingPacket = freePacket;
//CurrentWorkingPacket->Length = 0; //CurrentWorkingPacket->Length = 0;
@ -191,7 +167,7 @@ void Downstream_PreparePacketReception(DownstreamPacketTypeDef* freePacket)
(uint8_t*)&CurrentWorkingPacket->Length, (uint8_t*)&CurrentWorkingPacket->Length,
(2 + 1)) != HAL_OK) //"When the CRC feature is enabled the pData Length must be Size + 1" (2 + 1)) != HAL_OK) //"When the CRC feature is enabled the pData Length must be Size + 1"
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
UPSTREAM_TX_REQUEST_ASSERT; UPSTREAM_TX_REQUEST_ASSERT;
@ -206,10 +182,9 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
UPSTREAM_TX_REQUEST_DEASSERT; UPSTREAM_TX_REQUEST_DEASSERT;
if ((DownstreamInterfaceState != DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) && if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
(DownstreamInterfaceState != DOWNSTREAM_INTERFACE_RX_PACKET_WAIT))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; return;
} }
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT)
@ -217,14 +192,14 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
if ((CurrentWorkingPacket->Length < DOWNSTREAM_PACKET_LEN_MIN) || if ((CurrentWorkingPacket->Length < DOWNSTREAM_PACKET_LEN_MIN) ||
(CurrentWorkingPacket->Length > DOWNSTREAM_PACKET_LEN)) (CurrentWorkingPacket->Length > DOWNSTREAM_PACKET_LEN))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_PACKET_WAIT; DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_PACKET_WAIT;
if ((HAL_SPI_Receive_DMA(&Hspi1, if ((HAL_SPI_Receive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass, &CurrentWorkingPacket->CommandClass,
CurrentWorkingPacket->Length + 1)) != HAL_OK) //"When the CRC feature is enabled the pData Length must be Size + 1" CurrentWorkingPacket->Length + 1)) != HAL_OK) //"When the CRC feature is enabled the pData Length must be Size + 1"
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
UPSTREAM_TX_REQUEST_ASSERT; UPSTREAM_TX_REQUEST_ASSERT;
return; return;
@ -235,7 +210,7 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE; DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback == NULL) if (ReceivePacketCallback == NULL)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
//Packet processor may want to receive another packet immediately, //Packet processor may want to receive another packet immediately,
//so clear ReceivePacketCallback before the call. //so clear ReceivePacketCallback before the call.
@ -243,7 +218,10 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
tempPacketCallback = ReceivePacketCallback; tempPacketCallback = ReceivePacketCallback;
ReceivePacketCallback = NULL; ReceivePacketCallback = NULL;
tempPacketCallback(CurrentWorkingPacket); tempPacketCallback(CurrentWorkingPacket);
return;
} }
DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
@ -253,21 +231,26 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
//It doesn't make sense to call when receiving or awaiting reception. //It doesn't make sense to call when receiving or awaiting reception.
HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite) HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite)
{ {
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Sanity checks //Sanity checks
if ((packetToWrite != &DownstreamPacket0) && if ((packetToWrite != &DownstreamPacket0) &&
(packetToWrite != &DownstreamPacket1)) (packetToWrite != &DownstreamPacket1))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; DOWNSTREAM_SPI_FREAKOUT_RETURN_HAL_ERROR;
} }
if ((packetToWrite->Busy != BUSY) || if ((packetToWrite->Busy != BUSY) ||
(packetToWrite->Length < DOWNSTREAM_PACKET_LEN_MIN) || (packetToWrite->Length < DOWNSTREAM_PACKET_LEN_MIN) ||
(packetToWrite->Length > DOWNSTREAM_PACKET_LEN)) (packetToWrite->Length > DOWNSTREAM_PACKET_LEN))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; DOWNSTREAM_SPI_FREAKOUT_RETURN_HAL_ERROR;
} }
if (NextTxPacket != NULL) if (NextTxPacket != NULL)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; DOWNSTREAM_SPI_FREAKOUT_RETURN_HAL_ERROR;
} }
switch (DownstreamInterfaceState) switch (DownstreamInterfaceState)
@ -285,13 +268,13 @@ HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWri
(uint8_t*)&CurrentWorkingPacket->Length, (uint8_t*)&CurrentWorkingPacket->Length,
2 + 1) != HAL_OK) //"When the CRC feature is enabled the pRxData Length must be Size + 1" 2 + 1) != HAL_OK) //"When the CRC feature is enabled the pRxData Length must be Size + 1"
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_HAL_ERROR;
} }
UPSTREAM_TX_REQUEST_ASSERT; UPSTREAM_TX_REQUEST_ASSERT;
break; break;
default: default:
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; DOWNSTREAM_SPI_FREAKOUT_RETURN_HAL_ERROR;
} }
return HAL_OK; return HAL_OK;
@ -306,16 +289,21 @@ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{ {
UPSTREAM_TX_REQUEST_DEASSERT; UPSTREAM_TX_REQUEST_DEASSERT;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_TX_SIZE_WAIT) if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_TX_SIZE_WAIT)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
if (CurrentWorkingPacket->Length != 0) if (CurrentWorkingPacket->Length != 0)
{ {
//Currently we just freak out if Upstream sends us an unexpected command. //Currently we just freak out if Upstream sends us an unexpected command.
//Theoretically we could reset our downstream state machine and accept the new command... //Theoretically we could reset our downstream state machine and accept the new command...
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_PACKET_WAIT; DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_PACKET_WAIT;
@ -323,7 +311,7 @@ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
&CurrentWorkingPacket->CommandClass, &CurrentWorkingPacket->CommandClass,
CurrentWorkingPacket->Length)) != HAL_OK) CurrentWorkingPacket->Length)) != HAL_OK)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
UPSTREAM_TX_REQUEST_ASSERT; UPSTREAM_TX_REQUEST_ASSERT;
} }
@ -335,9 +323,14 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{ {
UPSTREAM_TX_REQUEST_DEASSERT; UPSTREAM_TX_REQUEST_DEASSERT;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_TX_PACKET_WAIT) if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_TX_PACKET_WAIT)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
Downstream_ReleasePacket(CurrentWorkingPacket); Downstream_ReleasePacket(CurrentWorkingPacket);
@ -349,11 +342,11 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
CurrentWorkingPacket = NextTxPacket; CurrentWorkingPacket = NextTxPacket;
NextTxPacket = NULL; NextTxPacket = NULL;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1, if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length, (uint8_t*)&CurrentWorkingPacket->Length,
(uint8_t*)&CurrentWorkingPacket->Length, (uint8_t*)&CurrentWorkingPacket->Length,
2 + 1) != HAL_OK) //"When the CRC feature is enabled the pRxData Length must be Size + 1" 2 + 1) != HAL_OK) //"When the CRC feature is enabled the pRxData Length must be Size + 1"
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }
UPSTREAM_TX_REQUEST_ASSERT; UPSTREAM_TX_REQUEST_ASSERT;
return; return;
@ -371,6 +364,6 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
//Something bad happened! Possibly CRC error... //Something bad happened! Possibly CRC error...
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_SPI_FREAKOUT_RETURN_VOID;
} }

@ -12,11 +12,12 @@
#include "downstream_msc.h" #include "downstream_msc.h"
#include "usbh_core.h" #include "usbh_core.h"
#include "usbh_msc.h" #include "usbh_msc.h"
#include "led.h"
DownstreamStateTypeDef DownstreamState; DownstreamStateTypeDef DownstreamState = STATE_DEVICE_NOT_READY;
InterfaceCommandClassTypeDef ConfiguredDeviceClass; InterfaceCommandClassTypeDef ConfiguredDeviceClass = COMMAND_CLASS_INTERFACE;
void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket); void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket);
@ -26,8 +27,6 @@ void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketType
void Downstream_InitStateMachine(void) void Downstream_InitStateMachine(void)
{ {
DownstreamState = STATE_DEVICE_NOT_READY;
ConfiguredDeviceClass = COMMAND_CLASS_INTERFACE;
Downstream_InitSPI(); Downstream_InitSPI();
//Prepare to receive our first packet from Upstream! //Prepare to receive our first packet from Upstream!
@ -37,12 +36,18 @@ void Downstream_InitStateMachine(void)
void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket) void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
{ {
if (DownstreamState >= STATE_ERROR)
{
Downstream_ReleasePacket(receivedPacket);
return;
}
switch (receivedPacket->CommandClass) switch (receivedPacket->CommandClass)
{ {
case COMMAND_CLASS_INTERFACE: case COMMAND_CLASS_INTERFACE:
if (DownstreamState > STATE_DEVICE_READY) if (DownstreamState > STATE_DEVICE_READY)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; DOWNSTREAM_STATEMACHINE_FREAKOUT;
} }
Downstream_PacketProcessor_Interface(receivedPacket); Downstream_PacketProcessor_Interface(receivedPacket);
break; break;
@ -50,8 +55,7 @@ void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
case COMMAND_CLASS_MASS_STORAGE: case COMMAND_CLASS_MASS_STORAGE:
if (DownstreamState != STATE_ACTIVE) if (DownstreamState != STATE_ACTIVE)
{ {
Downstream_PacketProcessor_ErrorReply(receivedPacket); DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
} }
Downstream_MSC_PacketProcessor(receivedPacket); Downstream_MSC_PacketProcessor(receivedPacket);
break; break;
@ -59,19 +63,35 @@ void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
//Add other classes here... //Add other classes here...
default: default:
Downstream_PacketProcessor_ErrorReply(receivedPacket); DOWNSTREAM_STATEMACHINE_FREAKOUT;
} }
} }
//Used by downstream_spi freakout macro, indicates we should stop everything.
void Downstream_PacketProcessor_SetErrorState(void)
{
DownstreamState = STATE_ERROR;
}
//Used by downstream class interfaces
void Downstream_PacketProcessor_FreakOut(void)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
}
void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket) void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket)
{ {
switch (receivedPacket->Command) switch (receivedPacket->Command)
{ {
case COMMAND_INTERFACE_ECHO: case COMMAND_INTERFACE_ECHO:
Downstream_TransmitPacket(receivedPacket); if (Downstream_TransmitPacket(receivedPacket) == HAL_OK)
Downstream_ReceivePacket(Downstream_PacketProcessor); {
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
return; return;
case COMMAND_INTERFACE_NOTIFY_DEVICE: case COMMAND_INTERFACE_NOTIFY_DEVICE:
@ -87,12 +107,12 @@ void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacke
Downstream_ReleasePacket(receivedPacket); Downstream_ReleasePacket(receivedPacket);
return; return;
} }
Downstream_PacketProcessor_ErrorReply(receivedPacket); DOWNSTREAM_STATEMACHINE_FREAKOUT;
return; return;
default: default:
Downstream_PacketProcessor_ErrorReply(receivedPacket); DOWNSTREAM_STATEMACHINE_FREAKOUT;
} }
} }
@ -103,10 +123,12 @@ void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketType
replyPacket->CommandClass = COMMAND_CLASS_INTERFACE; replyPacket->CommandClass = COMMAND_CLASS_INTERFACE;
replyPacket->Command = COMMAND_INTERFACE_NOTIFY_DEVICE; replyPacket->Command = COMMAND_INTERFACE_NOTIFY_DEVICE;
replyPacket->Data[0] = ConfiguredDeviceClass; replyPacket->Data[0] = ConfiguredDeviceClass;
Downstream_TransmitPacket(replyPacket);
DownstreamState = STATE_ACTIVE; if (Downstream_TransmitPacket(replyPacket) == HAL_OK)
Downstream_ReceivePacket(Downstream_PacketProcessor); {
DownstreamState = STATE_ACTIVE;
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
} }
@ -114,15 +136,20 @@ void Downstream_PacketProcessor_ErrorReply(DownstreamPacketTypeDef* replyPacket)
{ {
replyPacket->Length = DOWNSTREAM_PACKET_HEADER_LEN; replyPacket->Length = DOWNSTREAM_PACKET_HEADER_LEN;
replyPacket->CommandClass = COMMAND_CLASS_ERROR; replyPacket->CommandClass = COMMAND_CLASS_ERROR;
Downstream_TransmitPacket(replyPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor); if (Downstream_TransmitPacket(replyPacket) == HAL_OK)
{
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
} }
void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket) void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket)
{ {
Downstream_TransmitPacket(replyPacket); if (Downstream_TransmitPacket(replyPacket) == HAL_OK)
Downstream_ReceivePacket(Downstream_PacketProcessor); {
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
} }
@ -133,6 +160,11 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
{ {
InterfaceCommandClassTypeDef newActiveClass = COMMAND_CLASS_INTERFACE; InterfaceCommandClassTypeDef newActiveClass = COMMAND_CLASS_INTERFACE;
if (DownstreamState >= STATE_ERROR)
{
return;
}
//Called from USB interrupt //Called from USB interrupt
if (id == HOST_USER_DISCONNECTION) if (id == HOST_USER_DISCONNECTION)
{ {
@ -153,23 +185,31 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
break; break;
//Add other classes here... //Add other classes here...
}
//To change device class, we must reboot. //Any unsupported device will cause a slow fault flash.
if ((ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE) && //This is distinct from the fast freakout flash caused by internal errors or attacks.
(ConfiguredDeviceClass != newActiveClass)) default:
{ LED_Fault_SetBlinkRate(LED_SLOW_BLINK_RATE);
SPI_INTERFACE_FREAKOUT_NO_RETURN;
DownstreamState = STATE_ERROR; DownstreamState = STATE_ERROR;
return; return;
} }
//If the new device has failed its 'approval' checks, we are sufficiently freaked out.
if (newActiveClass == COMMAND_CLASS_INTERFACE) if (newActiveClass == COMMAND_CLASS_INTERFACE)
{ {
return; DOWNSTREAM_STATEMACHINE_FREAKOUT;
} }
//If we already configured a device class, we cannot change to a different one without rebooting.
//This blocks some BadUSB attacks.
if ((ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE) &&
(ConfiguredDeviceClass != newActiveClass))
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
}
ConfiguredDeviceClass = newActiveClass; ConfiguredDeviceClass = newActiveClass;
if (DownstreamState == STATE_WAIT_DEVICE_READY) if (DownstreamState == STATE_WAIT_DEVICE_READY)
{ {
Downstream_GetFreePacket(Downstream_PacketProcessor_Interface_ReplyNotifyDevice); Downstream_GetFreePacket(Downstream_PacketProcessor_Interface_ReplyNotifyDevice);
@ -182,9 +222,7 @@ void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
return; return;
} }
SPI_INTERFACE_FREAKOUT_NO_RETURN; DOWNSTREAM_STATEMACHINE_FREAKOUT;
DownstreamState = STATE_ERROR;
return;
} }
} }

@ -34,6 +34,7 @@
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "stm32f4xx.h" #include "stm32f4xx.h"
#include "interrupts.h" #include "interrupts.h"
#include "led.h"
/* External variables --------------------------------------------------------*/ /* External variables --------------------------------------------------------*/
@ -51,6 +52,7 @@ extern DMA_HandleTypeDef hdma_spi1_tx;
void SysTick_Handler(void) void SysTick_Handler(void)
{ {
HAL_IncTick(); HAL_IncTick();
LED_DoBlinks();
} }
/******************************************************************************/ /******************************************************************************/

@ -0,0 +1,62 @@
/*
* led.c
*
* Created on: 19/08/2015
* Author: Robert Fisk
*/
#include "stm32f4xx_hal.h"
#include "led.h"
#include "board_config.h"
uint16_t FaultLedBlinkRate = 0;
uint16_t FaultLedBlinkCounter = 0;
uint8_t FaultLedState = 0;
void LED_Init(void)
{
//RUN_LED_ON;
FAULT_LED_ON;
HAL_Delay(STARTUP_FLASH_DELAY);
//RUN_LED_OFF;
FAULT_LED_OFF;
}
void LED_Fault_SetBlinkRate(uint16_t newBlinkRate)
{
FaultLedBlinkRate = newBlinkRate;
if (newBlinkRate == 0)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
}
void LED_DoBlinks(void)
{
if (FaultLedBlinkRate > 0)
{
FaultLedBlinkCounter++;
if (FaultLedBlinkCounter >= FaultLedBlinkRate)
{
FaultLedBlinkCounter = 0;
if (FaultLedState)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
else
{
FaultLedState = 1;
FAULT_LED_ON;
}
}
}
}

@ -31,10 +31,11 @@
****************************************************************************** ******************************************************************************
*/ */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include <downstream_spi.h>
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "usb_host.h" #include "usb_host.h"
#include "board_config.h" #include "board_config.h"
#include "downstream_statemachine.h"
#include "led.h"
@ -46,8 +47,6 @@ static void GPIO_Init(void);
int main(void) int main(void)
{ {
/* MCU Configuration----------------------------------------------------------*/
/* Configure the system clock */ /* Configure the system clock */
SystemClock_Config(); SystemClock_Config();
@ -56,9 +55,10 @@ int main(void)
/* Initialize all configured peripherals */ /* Initialize all configured peripherals */
GPIO_Init(); GPIO_Init();
LED_Init();
USB_Host_Init(); USB_Host_Init();
Downstream_InitSPI(); Downstream_InitStateMachine();
while (1) while (1)
{ {

Loading…
Cancel
Save