diff --git a/Downstream/Inc/led.h b/Downstream/Inc/led.h index 6b60489..a944cc9 100644 --- a/Downstream/Inc/led.h +++ b/Downstream/Inc/led.h @@ -9,6 +9,9 @@ #define INC_LED_H_ +#include "stm32f4xx_hal.h" + + void LED_Init(void); void LED_Fault_SetBlinkRate(uint16_t newBlinkRate); void LED_DoBlinks(void); diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c index 5284cae..3f8638f 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c @@ -30,6 +30,7 @@ #include "usbh_msc.h" #include "downstream_spi.h" #include "downstream_msc.h" +#include "downstream_statemachine.h" diff --git a/Downstream/Src/downstream_spi.c b/Downstream/Src/downstream_spi.c index 8814ad6..b02b640 100644 --- a/Downstream/Src/downstream_spi.c +++ b/Downstream/Src/downstream_spi.c @@ -25,7 +25,6 @@ SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates some -void SPI1_Init(void); HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void); void Downstream_PreparePacketReception(DownstreamPacketTypeDef* freePacket); @@ -33,28 +32,22 @@ void Downstream_PreparePacketReception(DownstreamPacketTypeDef* freePacket); void Downstream_InitSPI(void) { - SPI1_Init(); - DownstreamPacket0.Busy = NOT_BUSY; DownstreamPacket1.Busy = NOT_BUSY; -} - -void SPI1_Init(void) -{ - Hspi1.Instance = SPI1; - Hspi1.Init.Mode = SPI_MODE_SLAVE; - Hspi1.Init.Direction = SPI_DIRECTION_2LINES; - Hspi1.Init.DataSize = SPI_DATASIZE_8BIT; - Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; - Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; - Hspi1.Init.NSS = SPI_NSS_HARD_INPUT; - Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; - Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; - Hspi1.Init.TIMode = SPI_TIMODE_DISABLED; - Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE; - Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL; - HAL_SPI_Init(&Hspi1); + Hspi1.Instance = SPI1; + Hspi1.Init.Mode = SPI_MODE_SLAVE; + Hspi1.Init.Direction = SPI_DIRECTION_2LINES; + Hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + Hspi1.Init.NSS = SPI_NSS_HARD_INPUT; + Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + Hspi1.Init.TIMode = SPI_TIMODE_DISABLED; + Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE; + Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL; + HAL_SPI_Init(&Hspi1); } diff --git a/Downstream/Src/led.c b/Downstream/Src/led.c index 1edbf8c..3f27acf 100644 --- a/Downstream/Src/led.c +++ b/Downstream/Src/led.c @@ -6,15 +6,14 @@ */ -#include "stm32f4xx_hal.h" #include "led.h" #include "board_config.h" -uint16_t FaultLedBlinkRate = 0; -uint16_t FaultLedBlinkCounter = 0; -uint8_t FaultLedState = 0; +uint16_t FaultLedBlinkRate = 0; +uint16_t FaultLedBlinkCounter = 0; +uint8_t FaultLedState = 0; void LED_Init(void) diff --git a/Upstream/.cproject b/Upstream/.cproject index d430332..0983f0b 100755 --- a/Upstream/.cproject +++ b/Upstream/.cproject @@ -109,7 +109,7 @@ - + @@ -234,7 +234,7 @@ - + diff --git a/Upstream/Inc/board_config.h b/Upstream/Inc/board_config.h index 2c848d1..30fb7a3 100644 --- a/Upstream/Inc/board_config.h +++ b/Upstream/Inc/board_config.h @@ -26,10 +26,14 @@ #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 SPI_DMA_ACTIVE_PIN GPIO_PIN_5 /////////Temporary indicator of SPI & DMA activity -#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_OFF SPI_DMA_ACTIVE_PORT->BSRR = (SPI_DMA_ACTIVE_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_PORT GPIOB +//#define SPI_DMA_ACTIVE_ON SPI_DMA_ACTIVE_PORT->BSRR = (SPI_DMA_ACTIVE_PIN << BSRR_SHIFT_LOW) +//#define SPI_DMA_ACTIVE_OFF SPI_DMA_ACTIVE_PORT->BSRR = (SPI_DMA_ACTIVE_PIN << BSRR_SHIFT_HIGH) #define SPI1_NSS_PIN GPIO_PIN_4 #define SPI1_NSS_PORT GPIOA diff --git a/Upstream/Inc/led.h b/Upstream/Inc/led.h new file mode 100644 index 0000000..a944cc9 --- /dev/null +++ b/Upstream/Inc/led.h @@ -0,0 +1,29 @@ +/* + * led.h + * + * Created on: 19/08/2015 + * Author: Robert Fisk + */ + +#ifndef INC_LED_H_ +#define INC_LED_H_ + + +#include "stm32f4xx_hal.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_ */ diff --git a/Upstream/Inc/upstream_msc.h b/Upstream/Inc/upstream_msc.h index 8d961e1..94597fa 100644 --- a/Upstream/Inc/upstream_msc.h +++ b/Upstream/Inc/upstream_msc.h @@ -13,12 +13,11 @@ typedef void (*UpstreamMSCCallbackTypeDef)(HAL_StatusTypeDef result); -typedef void (*UpstreamMSCCallbackPacketTypeDef)(HAL_StatusTypeDef result, - UpstreamPacketTypeDef* upstreamPacket, +typedef void (*UpstreamMSCCallbackPacketTypeDef)(UpstreamPacketTypeDef* upstreamPacket, uint16_t dataLength); -typedef void (*UpstreamMSCCallbackUintPacketTypeDef)(HAL_StatusTypeDef result, - uint32_t result_uint[], - UpstreamPacketTypeDef* upstreamPacket); +typedef void (*UpstreamMSCCallbackUintPacketTypeDef)(UpstreamPacketTypeDef* upstreamPacket, + uint32_t result_uint1, + uint32_t result_uint2); HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback); diff --git a/Upstream/Inc/upstream_spi.h b/Upstream/Inc/upstream_spi.h index 02c9e8b..ba1dd00 100644 --- a/Upstream/Inc/upstream_spi.h +++ b/Upstream/Inc/upstream_spi.h @@ -17,32 +17,19 @@ #define UPSTREAM_PACKET_LEN_MIN (UPSTREAM_PACKET_HEADER_LEN) -#define SPI_INTERFACE_FREAKOUT_RETURN_VOID \ - do { \ - while (1); \ - /*UpstreamInterfaceState = INTERFACE_STATE_ERROR;*/ \ - /*return;*/ \ +#define UPSTREAM_SPI_FREAKOUT \ + do { \ + LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \ + UpstreamInterfaceState = UPSTREAM_INTERFACE_ERROR; \ + Upstream_StateMachine_SetErrorState(); \ + while (1); \ } while (0); -#define SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR \ - do { \ - while (1); \ - /*UpstreamInterfaceState = INTERFACE_STATE_ERROR;*/ \ - /*return HAL_ERROR;*/ \ -} while (0); - -#define SPI_INTERFACE_FREAKOUT_NO_RETURN \ - do { \ - while (1); \ - /*while (1);*/ \ -} while (0); typedef enum { - UPSTREAM_INTERFACE_RESET, - UPSTREAM_INTERFACE_AWAITING_DEVICE, UPSTREAM_INTERFACE_IDLE, UPSTREAM_INTERFACE_TX_SIZE_WAIT, UPSTREAM_INTERFACE_TX_SIZE, diff --git a/Upstream/Inc/upstream_statemachine.h b/Upstream/Inc/upstream_statemachine.h new file mode 100644 index 0000000..8c16c81 --- /dev/null +++ b/Upstream/Inc/upstream_statemachine.h @@ -0,0 +1,39 @@ +/* + * upstream_statemachine.h + * + * Created on: 20/08/2015 + * Author: Robert Fisk + */ + +#ifndef INC_UPSTREAM_STATEMACHINE_H_ +#define INC_UPSTREAM_STATEMACHINE_H_ + + +#include "led.h" + + +typedef enum +{ + STATE_TEST_INTERFACE, + STATE_WAIT_DEVICE, + STATE_DEVICE_ACTIVE, + STATE_ERROR +} UpstreamStateTypeDef; + + + +#define UPSTREAM_STATEMACHINE_FREAKOUT \ + do { \ + LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \ + Upstream_StateMachine_SetErrorState(); \ +} while (0); + + + +void Upstream_InitStateMachine(void); +void Upstream_StateMachine_SetErrorState(void); +HAL_StatusTypeDef Upstream_StateMachine_CheckClassOperationOk(void); + + + +#endif /* INC_UPSTREAM_STATEMACHINE_H_ */ diff --git a/Upstream/Inc/usb_device.h b/Upstream/Inc/usb_device.h index e11adfb..ffa6a02 100755 --- a/Upstream/Inc/usb_device.h +++ b/Upstream/Inc/usb_device.h @@ -43,11 +43,15 @@ #include "stm32f4xx_hal.h" #include "usbd_def.h" + extern USBD_HandleTypeDef hUsbDeviceFS; -/* USB_Device init function */ + void USB_Device_Init(void); + + + #ifdef __cplusplus } #endif diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c index c512133..3ed5b07 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c @@ -104,15 +104,14 @@ static void SCSI_Verify10(void); static int8_t SCSI_CheckAddressRange (uint32_t blk_offset , uint16_t blk_nbr); void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result); -void SCSI_ReadCapacity10Callback(HAL_StatusTypeDef result, - uint32_t result_uint[], - UpstreamPacketTypeDef* upstreamPacket); -void SCSI_ReadFormatCapacityCallback(HAL_StatusTypeDef result, - uint32_t result_uint[], - UpstreamPacketTypeDef* packetToUse); +void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket, + uint32_t result_uint1, + uint32_t result_uint2); +void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket, + uint32_t result_uint1, + uint32_t result_uint2); void SCSI_Read10BeginCallback(HAL_StatusTypeDef result); -void SCSI_Read10ReplyCallback(HAL_StatusTypeDef result, - UpstreamPacketTypeDef* upstreamPacket, +void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket, uint16_t dataLength); void SCSI_Write10BeginCallback(HAL_StatusTypeDef result); void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket); @@ -316,16 +315,16 @@ static void SCSI_ReadCapacity10(void) { if (Upstream_MSC_GetCapacity(SCSI_ReadCapacity10Callback) != HAL_OK) { - SCSI_ReadCapacity10Callback(HAL_ERROR, NULL, NULL); + SCSI_ReadCapacity10Callback(NULL, 0, 0); } } -void SCSI_ReadCapacity10Callback(HAL_StatusTypeDef result, - uint32_t result_uint[], - UpstreamPacketTypeDef* upstreamPacket) +void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket, + uint32_t result_uint1, + uint32_t result_uint2) { - if (result != HAL_OK) + if (upstreamPacket == NULL) { SCSI_SenseCode(SCSI_ProcessCmd_pdev, SCSI_ProcessCmd_lun, @@ -338,8 +337,8 @@ void SCSI_ReadCapacity10Callback(HAL_StatusTypeDef result, SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket; SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data; - SCSI_ProcessCmd_hmsc->scsi_blk_nbr = result_uint[0]; - SCSI_ProcessCmd_hmsc->scsi_blk_size = result_uint[1]; + SCSI_ProcessCmd_hmsc->scsi_blk_nbr = result_uint1; + SCSI_ProcessCmd_hmsc->scsi_blk_size = result_uint2; SCSI_ProcessCmd_hmsc->bot_data[0] = (uint8_t)((SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1) >> 24); SCSI_ProcessCmd_hmsc->bot_data[1] = (uint8_t)((SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1) >> 16); @@ -366,16 +365,16 @@ static void SCSI_ReadFormatCapacity(void) { if (Upstream_MSC_GetCapacity(SCSI_ReadFormatCapacityCallback) != HAL_OK) { - SCSI_ReadFormatCapacityCallback(HAL_ERROR, NULL, NULL); + SCSI_ReadFormatCapacityCallback(NULL, 0, 0); } } -void SCSI_ReadFormatCapacityCallback(HAL_StatusTypeDef result, - uint32_t result_uint[], - UpstreamPacketTypeDef* packetToUse) +void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket, + uint32_t result_uint1, + uint32_t result_uint2) { - if (result != HAL_OK) + if (upstreamPacket == NULL) { SCSI_SenseCode(SCSI_ProcessCmd_pdev, SCSI_ProcessCmd_lun, @@ -385,22 +384,22 @@ void SCSI_ReadFormatCapacityCallback(HAL_StatusTypeDef result, return; } - SCSI_ProcessCmd_hmsc->bot_packet = packetToUse; - SCSI_ProcessCmd_hmsc->bot_data = packetToUse->Data; + SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket; + SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data; SCSI_ProcessCmd_hmsc->bot_data[0] = 0; SCSI_ProcessCmd_hmsc->bot_data[1] = 0; SCSI_ProcessCmd_hmsc->bot_data[2] = 0; SCSI_ProcessCmd_hmsc->bot_data[3] = 0x08; - SCSI_ProcessCmd_hmsc->bot_data[4] = (uint8_t)((result_uint[0] - 1) >> 24); - SCSI_ProcessCmd_hmsc->bot_data[5] = (uint8_t)((result_uint[0] - 1) >> 16); - SCSI_ProcessCmd_hmsc->bot_data[6] = (uint8_t)((result_uint[0] - 1) >> 8); - SCSI_ProcessCmd_hmsc->bot_data[7] = (uint8_t)(result_uint[0] - 1); + SCSI_ProcessCmd_hmsc->bot_data[4] = (uint8_t)((result_uint1 - 1) >> 24); + SCSI_ProcessCmd_hmsc->bot_data[5] = (uint8_t)((result_uint1 - 1) >> 16); + SCSI_ProcessCmd_hmsc->bot_data[6] = (uint8_t)((result_uint1 - 1) >> 8); + SCSI_ProcessCmd_hmsc->bot_data[7] = (uint8_t)(result_uint1 - 1); SCSI_ProcessCmd_hmsc->bot_data[8] = 0x02; - SCSI_ProcessCmd_hmsc->bot_data[9] = (uint8_t)(result_uint[1] >> 16); - SCSI_ProcessCmd_hmsc->bot_data[10] = (uint8_t)(result_uint[1] >> 8); - SCSI_ProcessCmd_hmsc->bot_data[11] = (uint8_t)(result_uint[1]); + SCSI_ProcessCmd_hmsc->bot_data[9] = (uint8_t)(result_uint2 >> 16); + SCSI_ProcessCmd_hmsc->bot_data[10] = (uint8_t)(result_uint2 >> 8); + SCSI_ProcessCmd_hmsc->bot_data[11] = (uint8_t)(result_uint2); SCSI_ProcessCmd_hmsc->bot_data_length = 12; SCSI_ProcessCmd_callback(0); @@ -602,7 +601,7 @@ static void SCSI_Read10(void) //hmsc->bot_state is already USBD_BOT_DATA_IN if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK) { - SCSI_Read10ReplyCallback(HAL_ERROR, NULL, 0); + SCSI_Read10ReplyCallback(NULL, 0); } } @@ -622,16 +621,15 @@ void SCSI_Read10BeginCallback(HAL_StatusTypeDef result) if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK) { - SCSI_Read10ReplyCallback(HAL_ERROR, NULL, 0); + SCSI_Read10ReplyCallback(NULL, 0); } } -void SCSI_Read10ReplyCallback(HAL_StatusTypeDef result, - UpstreamPacketTypeDef* upstreamPacket, +void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket, uint16_t dataLength) { - if (result != HAL_OK) + if (upstreamPacket == NULL) { SCSI_SenseCode(SCSI_ProcessCmd_pdev, SCSI_ProcessCmd_lun, diff --git a/Upstream/Src/interrupts.c b/Upstream/Src/interrupts.c index 471b41a..5ee1148 100755 --- a/Upstream/Src/interrupts.c +++ b/Upstream/Src/interrupts.c @@ -37,6 +37,7 @@ #include "stm32f4xx_hal.h" #include "stm32f4xx.h" #include "board_config.h" +#include "led.h" /* USER CODE BEGIN 0 */ @@ -55,7 +56,7 @@ extern DMA_HandleTypeDef spiRxDmaHandle; void SysTick_Handler(void) { HAL_IncTick(); - + LED_DoBlinks(); } ///////////////////////// @@ -65,31 +66,31 @@ void SysTick_Handler(void) ///////////////////////// void OTG_FS_IRQHandler(void) { - STAT_LED_ON; //blink STAT LED while processing interrupt + //STAT_LED_ON; //blink STAT LED while processing interrupt HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); - STAT_LED_OFF; + //STAT_LED_OFF; } void DMA2_Stream2_IRQHandler(void) { - SPI_DMA_ACTIVE_ON; + //SPI_DMA_ACTIVE_ON; HAL_DMA_IRQHandler(&spiRxDmaHandle); - SPI_DMA_ACTIVE_OFF; + //SPI_DMA_ACTIVE_OFF; } void DMA2_Stream3_IRQHandler(void) { - SPI_DMA_ACTIVE_ON; + //SPI_DMA_ACTIVE_ON; HAL_DMA_IRQHandler(&spiTxDmaHandle); - SPI_DMA_ACTIVE_OFF; + //SPI_DMA_ACTIVE_OFF; } void EXTI3_IRQHandler(void) { - SPI_DMA_ACTIVE_ON; + //SPI_DMA_ACTIVE_ON; __HAL_GPIO_EXTI_CLEAR_IT(3); Upstream_TxOkInterrupt(); - SPI_DMA_ACTIVE_OFF; + //SPI_DMA_ACTIVE_OFF; } ///////////////////////// ///////////////////////// diff --git a/Upstream/Src/led.c b/Upstream/Src/led.c new file mode 100644 index 0000000..3f27acf --- /dev/null +++ b/Upstream/Src/led.c @@ -0,0 +1,61 @@ +/* + * led.c + * + * Created on: 19/08/2015 + * Author: Robert Fisk + */ + + +#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; + } + } + } +} + diff --git a/Upstream/Src/main.c b/Upstream/Src/main.c index f082e2a..72c640b 100755 --- a/Upstream/Src/main.c +++ b/Upstream/Src/main.c @@ -33,11 +33,11 @@ */ /* Includes ------------------------------------------------------------------*/ -#include #include "stm32f4xx_hal.h" #include "usb_device.h" #include "board_config.h" - +#include "led.h" +#include "upstream_statemachine.h" /* Private variables ---------------------------------------------------------*/ @@ -52,8 +52,6 @@ static void GPIO_Init(void); int main(void) { - /* MCU Configuration----------------------------------------------------------*/ - /* Configure the system clock */ SystemClock_Config(); @@ -62,16 +60,16 @@ int main(void) /* Initialize all configured peripherals */ GPIO_Init(); + LED_Init(); USB_Device_Init(); - Upstream_InitSPI(); + Upstream_InitStateMachine(); while (1) { } - } /** System Clock Configuration @@ -102,7 +100,7 @@ void SystemClock_Config(void) RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2)) while(1); + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) while(1); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); } @@ -153,12 +151,12 @@ void GPIO_Init(void) HAL_GPIO_Init(STAT_LED_PORT, &GPIO_InitStruct); STAT_LED_OFF; - //SPI_DMA_ACTIVE indicator - GPIO_InitStruct.Pin = SPI_DMA_ACTIVE_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(SPI_DMA_ACTIVE_PORT, &GPIO_InitStruct); - SPI_DMA_ACTIVE_OFF; +// //SPI_DMA_ACTIVE indicator +// GPIO_InitStruct.Pin = SPI_DMA_ACTIVE_PIN; +// GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; +// GPIO_InitStruct.Pull = GPIO_NOPULL; +// HAL_GPIO_Init(SPI_DMA_ACTIVE_PORT, &GPIO_InitStruct); +// SPI_DMA_ACTIVE_OFF; } /* USER CODE BEGIN 4 */ diff --git a/Upstream/Src/upstream_msc.c b/Upstream/Src/upstream_msc.c index 56074df..a2ecb0f 100644 --- a/Upstream/Src/upstream_msc.c +++ b/Upstream/Src/upstream_msc.c @@ -6,9 +6,10 @@ */ -#include -#include -#include +#include "upstream_interface_def.h" +#include "upstream_msc.h" +#include "upstream_spi.h" +#include "upstream_statemachine.h" #include "stm32f4xx_hal.h" @@ -31,27 +32,45 @@ static void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPac HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback) { UpstreamPacketTypeDef* freePacket; - HAL_StatusTypeDef tempResult; + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return HAL_ERROR; + } + TestReadyCallback = callback; freePacket = Upstream_GetFreePacketImmediately(); + if (freePacket == NULL) + { + return HAL_ERROR; + } freePacket->Length = UPSTREAM_PACKET_HEADER_LEN; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->Command = COMMAND_MSC_TEST_UNIT_READY; - tempResult = Upstream_TransmitPacket(freePacket); - if (tempResult != HAL_OK) + if (Upstream_TransmitPacket(freePacket) == HAL_OK) { - return tempResult; + return Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback); } - return Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback); + //else: + return HAL_ERROR; } void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket) { + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return; + } + + if (replyPacket == NULL) + { + TestReadyCallback(HAL_ERROR); + return; + } + if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) || - (replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE) || (replyPacket->Data[0] != HAL_OK)) { Upstream_ReleasePacket(replyPacket); @@ -68,37 +87,56 @@ void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket) HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef callback) { UpstreamPacketTypeDef* freePacket; - HAL_StatusTypeDef tempResult; + + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return HAL_ERROR; + } GetCapacityCallback = callback; freePacket = Upstream_GetFreePacketImmediately(); + if (freePacket == NULL) + { + return HAL_ERROR; + } freePacket->Length = UPSTREAM_PACKET_HEADER_LEN; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->Command = COMMAND_MSC_GET_CAPACITY; - tempResult = Upstream_TransmitPacket(freePacket); - if (tempResult != HAL_OK) + if (Upstream_TransmitPacket(freePacket) == HAL_OK) { - return tempResult; + return Upstream_ReceivePacket(Upstream_MSC_GetCapacityReplyCallback); } - return Upstream_ReceivePacket(Upstream_MSC_GetCapacityReplyCallback); + //else: + return HAL_ERROR; } void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPacket) { - uint32_t uint[2]; + uint32_t uint1; + uint32_t uint2; + + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return; + } - if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8) || - (replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE))) + if (replyPacket == NULL) { - GetCapacityCallback(HAL_ERROR, NULL, NULL); + GetCapacityCallback(NULL, 0, 0); return; } - uint[0] = *(uint32_t*)&(replyPacket->Data[0]); - uint[1] = *(uint32_t*)&(replyPacket->Data[4]); - GetCapacityCallback(HAL_OK, uint, replyPacket); //usb_msc_scsi will use this packet, so don't release now + if (replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8)) + { + GetCapacityCallback(NULL, 0, 0); + return; + } + + uint1 = *(uint32_t*)&(replyPacket->Data[0]); + uint2 = *(uint32_t*)&(replyPacket->Data[4]); + GetCapacityCallback(replyPacket, uint1, uint2); //usb_msc_scsi will use this packet, so don't release now } @@ -109,7 +147,11 @@ HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback, uint32_t readByteCount) { UpstreamPacketTypeDef* freePacket; - HAL_StatusTypeDef tempResult; + + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return HAL_ERROR; + } ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use ReadStreamBusy = 0; @@ -117,6 +159,10 @@ HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback, TestReadyCallback = callback; freePacket = Upstream_GetFreePacketImmediately(); + if (freePacket == NULL) + { + return HAL_ERROR; + } freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3); freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; @@ -124,18 +170,22 @@ HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback, *(uint64_t*)&(freePacket->Data[0]) = readBlockStart; *(uint32_t*)&(freePacket->Data[8]) = readBlockCount; - tempResult = Upstream_TransmitPacket(freePacket); - if (tempResult != HAL_OK) + if (Upstream_TransmitPacket(freePacket) == HAL_OK) { - TestReadyCallback(tempResult); + return Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback); //Re-use TestReadyReplyCallback because it does exactly what we want! } - return Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback); //Re-use TestReadyReplyCallback because it does exactly what we want! + //else: + return HAL_ERROR; } HAL_StatusTypeDef Upstream_MSC_GetStreamDataPacket(UpstreamMSCCallbackPacketTypeDef callback) { + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return HAL_ERROR; + } GetStreamDataCallback = callback; if (ReadStreamBusy != 0) @@ -159,24 +209,36 @@ void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket uint16_t dataLength; ReadStreamBusy = 0; + + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return; + } + if (GetStreamDataCallback == NULL) { ReadStreamPacket = replyPacket; //We used up our callback already, so save this one for later. return; } + if (replyPacket == NULL) + { + GetStreamDataCallback(NULL, 0); + return; + } + dataLength = replyPacket->Length - UPSTREAM_PACKET_HEADER_LEN; if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any 'command' reply (as opposed to 'data' reply) is an automatic fail here (replyPacket->Length <= UPSTREAM_PACKET_HEADER_LEN) || //Should be at least one data byte in the reply. (dataLength > ByteCount)) //No more data than expected transfer length { - GetStreamDataCallback(HAL_ERROR, NULL, NULL); + GetStreamDataCallback(NULL, 0); return; } 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) { Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it @@ -190,10 +252,18 @@ HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback, uint32_t readBlockCount) { UpstreamPacketTypeDef* freePacket; - HAL_StatusTypeDef tempResult; + + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return HAL_ERROR; + } TestReadyCallback = callback; freePacket = Upstream_GetFreePacketImmediately(); + if (freePacket == NULL) + { + return HAL_ERROR; + } freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3); freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; @@ -201,19 +271,31 @@ HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback, *(uint64_t*)&(freePacket->Data[0]) = readBlockStart; *(uint32_t*)&(freePacket->Data[8]) = readBlockCount; - tempResult = Upstream_TransmitPacket(freePacket); - if (tempResult != HAL_OK) + if (Upstream_TransmitPacket(freePacket) == HAL_OK) { - TestReadyCallback(tempResult); + return Upstream_ReceivePacket(Upstream_MSC_BeginWriteReplyCallback); } - return Upstream_ReceivePacket(Upstream_MSC_BeginWriteReplyCallback); + //else: + return HAL_ERROR; } void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket) { + uint8_t tempResult; + + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return; + } + + if (replyPacket == NULL) + { + TestReadyCallback(HAL_ERROR); + return; + } + if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) || - (replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE) || ((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY))) { Upstream_ReleasePacket(replyPacket); @@ -221,8 +303,9 @@ void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket) return; } + tempResult = replyPacket->Data[0]; Upstream_ReleasePacket(replyPacket); - TestReadyCallback(replyPacket->Data[0]); + TestReadyCallback(tempResult); } @@ -230,6 +313,11 @@ void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket) HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend, uint32_t dataLength) { + if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK) + { + return HAL_ERROR; + } + packetToSend->Length = dataLength + UPSTREAM_PACKET_HEADER_LEN; packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG; packetToSend->Command = COMMAND_MSC_BEGIN_WRITE; diff --git a/Upstream/Src/upstream_spi.c b/Upstream/Src/upstream_spi.c index 9ae9ced..52c79bf 100644 --- a/Upstream/Src/upstream_spi.c +++ b/Upstream/Src/upstream_spi.c @@ -5,8 +5,9 @@ * Author: Robert Fisk */ -#include -#include +#include "upstream_interface_def.h" +#include "upstream_spi.h" +#include "upstream_statemachine.h" #include "stm32f4xx_hal.h" #include "usbd_def.h" #include "board_config.h" @@ -17,17 +18,16 @@ SPI_HandleTypeDef Hspi1; UpstreamPacketTypeDef UpstreamPacket0; UpstreamPacketTypeDef UpstreamPacket1; UpstreamPacketTypeDef* CurrentWorkingPacket; -UpstreamPacketTypeDef* NextTxPacket; //Indicates we have a pending TX packet +UpstreamPacketTypeDef* NextTxPacket = NULL; //Indicates we have a pending TX packet -InterfaceStateTypeDef UpstreamInterfaceState; -FreePacketCallbackTypeDef PendingFreePacketCallback; //Indicates someone is waiting for a packet buffer to become available -SpiPacketReceivedCallbackTypeDef ReceivePacketCallback; //Indicates someone is waiting for a received packet +InterfaceStateTypeDef UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE; +FreePacketCallbackTypeDef PendingFreePacketCallback = NULL; //Indicates someone is waiting for a packet buffer to become available +SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates someone is waiting for a received packet uint8_t SentCommandClass; uint8_t SentCommand; -static void SPI1_Init(void); static HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void); static void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket); @@ -35,24 +35,9 @@ static void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket); void Upstream_InitSPI(void) { - UpstreamInterfaceState = UPSTREAM_INTERFACE_RESET; - - SPI1_Init(); UpstreamPacket0.Busy = NOT_BUSY; UpstreamPacket1.Busy = NOT_BUSY; - NextTxPacket = NULL; - PendingFreePacketCallback = NULL; - ReceivePacketCallback = NULL; - - //Todo: check connection to downstream, await client USB insertion - - while (!DOWNSTREAM_TX_OK_ACTIVE); - UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE; -} - -void SPI1_Init(void) -{ Hspi1.Instance = SPI1; Hspi1.State = HAL_SPI_STATE_RESET; Hspi1.Init.Mode = SPI_MODE_MASTER; @@ -74,17 +59,16 @@ void SPI1_Init(void) //Used by USB interface classes, and by our internal RX code. HAL_StatusTypeDef Upstream_GetFreePacket(FreePacketCallbackTypeDef callback) { - //Sanity checks - if ((UpstreamInterfaceState < UPSTREAM_INTERFACE_IDLE) || - (UpstreamInterfaceState > UPSTREAM_INTERFACE_RX_PACKET)) + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + return HAL_ERROR; } //Do we already have a queued callback? if (PendingFreePacketCallback != NULL) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + UPSTREAM_SPI_FREAKOUT; + return HAL_ERROR; } //Check if there is a free buffer now @@ -109,11 +93,9 @@ HAL_StatusTypeDef Upstream_GetFreePacket(FreePacketCallbackTypeDef callback) UpstreamPacketTypeDef* Upstream_GetFreePacketImmediately(void) { - //Sanity checks - if ((UpstreamInterfaceState < UPSTREAM_INTERFACE_IDLE) || - (UpstreamInterfaceState > UPSTREAM_INTERFACE_RX_PACKET)) + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + return NULL; } //We are expecting a free buffer now @@ -129,7 +111,8 @@ UpstreamPacketTypeDef* Upstream_GetFreePacketImmediately(void) } //Should not happen: - SPI_INTERFACE_FREAKOUT_NO_RETURN; + UPSTREAM_SPI_FREAKOUT; + return NULL; } @@ -137,11 +120,17 @@ UpstreamPacketTypeDef* Upstream_GetFreePacketImmediately(void) void Upstream_ReleasePacket(UpstreamPacketTypeDef* packetToRelease) { FreePacketCallbackTypeDef tempCallback; + + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) + { + return; + } if ((packetToRelease != &UpstreamPacket0) && (packetToRelease != &UpstreamPacket1)) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + UPSTREAM_SPI_FREAKOUT; + return; } if (PendingFreePacketCallback != NULL) @@ -163,21 +152,29 @@ void Upstream_ReleasePacket(UpstreamPacketTypeDef* packetToRelease) //as we can't let the size/packet sequence get out of sync. HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite) { + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) + { + return HAL_ERROR; + } + //Sanity checks if ((packetToWrite != &UpstreamPacket0) && (packetToWrite != &UpstreamPacket1)) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + UPSTREAM_SPI_FREAKOUT; + return HAL_ERROR; } if ((packetToWrite->Busy != BUSY) || (packetToWrite->Length < UPSTREAM_PACKET_LEN_MIN) || (packetToWrite->Length > UPSTREAM_PACKET_LEN)) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + UPSTREAM_SPI_FREAKOUT; + return HAL_ERROR; } if (NextTxPacket != NULL) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + UPSTREAM_SPI_FREAKOUT; + return HAL_ERROR; } switch (UpstreamInterfaceState) @@ -197,7 +194,8 @@ HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite) break; default: - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + UPSTREAM_SPI_FREAKOUT; + return HAL_ERROR; } return HAL_OK; } @@ -210,26 +208,32 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { SPI1_NSS_DEASSERT; - if ((UpstreamInterfaceState != UPSTREAM_INTERFACE_TX_SIZE) && - (UpstreamInterfaceState != UPSTREAM_INTERFACE_TX_PACKET)) + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + return; } + //Finished transmitting packet size if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_SIZE) { UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_PACKET_WAIT; return; } + //Finished transmitting packet body if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_PACKET) { if ((PendingFreePacketCallback != NULL) && (NextTxPacket == NULL)) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; + return; } Upstream_ReleasePacket(CurrentWorkingPacket); + if (UpstreamInterfaceState == UPSTREAM_INTERFACE_ERROR) + { + return; //Really shouldn't happen, but we are being paranoid... + } if (NextTxPacket != NULL) { //NextTxPacket has already passed the checks in Upstream_TransmitPacket. @@ -245,7 +249,11 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { Upstream_CheckBeginPacketReception(); } + return; } + + //case default: + UPSTREAM_SPI_FREAKOUT; } @@ -254,9 +262,15 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) //Not OK to call when receiving or waiting for downstream reply. HAL_StatusTypeDef Upstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback) { + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) + { + return HAL_ERROR; + } + if (ReceivePacketCallback != NULL) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + UPSTREAM_SPI_FREAKOUT; + return HAL_ERROR; } ReceivePacketCallback = callback; @@ -267,10 +281,15 @@ HAL_StatusTypeDef Upstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callba //Internal use only. HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void) { - if ((UpstreamInterfaceState < UPSTREAM_INTERFACE_IDLE) || - (UpstreamInterfaceState > UPSTREAM_INTERFACE_RX_SIZE_WAIT)) + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) { - SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; + return HAL_ERROR; + } + + if (UpstreamInterfaceState > UPSTREAM_INTERFACE_RX_SIZE_WAIT) + { + UPSTREAM_SPI_FREAKOUT; + return HAL_ERROR; } if (UpstreamInterfaceState == UPSTREAM_INTERFACE_IDLE) @@ -285,6 +304,11 @@ HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void) //indicating that downstream is ready for the next transaction. void Upstream_TxOkInterrupt(void) { + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) + { + return; + } + switch (UpstreamInterfaceState) { case UPSTREAM_INTERFACE_TX_SIZE_WAIT: @@ -294,7 +318,7 @@ void Upstream_TxOkInterrupt(void) (uint8_t*)&CurrentWorkingPacket->Length, 2) != HAL_OK) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; } break; @@ -305,7 +329,7 @@ void Upstream_TxOkInterrupt(void) &CurrentWorkingPacket->CommandClass, CurrentWorkingPacket->Length)) != HAL_OK) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; } break; @@ -320,12 +344,12 @@ void Upstream_TxOkInterrupt(void) &CurrentWorkingPacket->CommandClass, (CurrentWorkingPacket->Length + 1))) != HAL_OK) //"When the CRC feature is enabled the pData Length must be Size + 1" { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; } break; default: - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; } } @@ -334,9 +358,15 @@ void Upstream_TxOkInterrupt(void) //Called when we want to receive downstream packet, and a packet buffer has become free. void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket) { + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) + { + return; + } + if (UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_SIZE_WAIT) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; + return; } UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_SIZE; CurrentWorkingPacket = freePacket; @@ -346,7 +376,7 @@ void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket) (uint8_t*)&CurrentWorkingPacket->Length, (2 + 1)) != HAL_OK) //"When the CRC feature is enabled the pData Length must be Size + 1" { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; } } @@ -359,10 +389,9 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) SPI1_NSS_DEASSERT; - if ((UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_SIZE) && - (UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_PACKET)) + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + return; } if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_SIZE) @@ -370,7 +399,8 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) if ((CurrentWorkingPacket->Length < UPSTREAM_PACKET_LEN_MIN) || (CurrentWorkingPacket->Length > UPSTREAM_PACKET_LEN)) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; + return; } UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_PACKET_WAIT; return; @@ -378,29 +408,53 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_PACKET) { - UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE; - if (((SentCommandClass != (CurrentWorkingPacket->CommandClass & COMMAND_CLASS_MASK)) && - (SentCommandClass != COMMAND_CLASS_ERROR)) || - (SentCommand != CurrentWorkingPacket->Command)) + if (ReceivePacketCallback == NULL) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; + return; } - if (ReceivePacketCallback == NULL) + + UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE; + if ((SentCommandClass != (CurrentWorkingPacket->CommandClass & COMMAND_CLASS_MASK)) || + (SentCommand != CurrentWorkingPacket->Command)) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + UPSTREAM_SPI_FREAKOUT; + Upstream_ReleasePacket(CurrentWorkingPacket); + CurrentWorkingPacket = NULL; //Call back with a NULL packet to indicate error } + //USB interface may want to receive another packet immediately, //so clear ReceivePacketCallback before the call. //It is the callback's responsibility to release the packet buffer we are passing to it! tempPacketCallback = ReceivePacketCallback; ReceivePacketCallback = NULL; tempPacketCallback(CurrentWorkingPacket); + return; } + + //case default: + UPSTREAM_SPI_FREAKOUT; } //Something bad happened! Possibly CRC error... void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) { - SPI_INTERFACE_FREAKOUT_RETURN_VOID; + SpiPacketReceivedCallbackTypeDef tempPacketCallback; + + if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR) + { + return; + } + + UPSTREAM_SPI_FREAKOUT; + + if (ReceivePacketCallback != NULL) + { + tempPacketCallback = ReceivePacketCallback; + ReceivePacketCallback = NULL; + tempPacketCallback(NULL); //Call back with a NULL packet to indicate error + } } + + diff --git a/Upstream/Src/upstream_statemachine.c b/Upstream/Src/upstream_statemachine.c new file mode 100644 index 0000000..90f01be --- /dev/null +++ b/Upstream/Src/upstream_statemachine.c @@ -0,0 +1,176 @@ +/* + * upstream_statemachine.c + * + * Created on: 20/08/2015 + * Author: Robert Fisk + */ + + +#include "upstream_statemachine.h" +#include "upstream_spi.h" +#include "upstream_interface_def.h" +#include "usb_device.h" +#include "usbd_core.h" +#include "usbd_msc.h" + + +UpstreamStateTypeDef UpstreamState = STATE_TEST_INTERFACE; +InterfaceCommandClassTypeDef ActiveDeviceClass = COMMAND_CLASS_INTERFACE; + + +void Upstream_TestInterfaceReplyCallback(UpstreamPacketTypeDef* replyPacket); +void Upstream_NotifyDeviceReplyCallback(UpstreamPacketTypeDef* replyPacket); + + + +void Upstream_InitStateMachine(void) +{ + UpstreamPacketTypeDef* freePacket; + uint16_t i; + uint8_t testDataValue; + + Upstream_InitSPI(); + + //Prepare SPI test packet + freePacket = Upstream_GetFreePacketImmediately(); + if (freePacket == NULL) + { + UpstreamState = STATE_ERROR; + return; + } + + freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + MSC_MEDIA_PACKET; + freePacket->CommandClass = COMMAND_CLASS_INTERFACE; + freePacket->Command = COMMAND_INTERFACE_ECHO; + testDataValue = 0xFF; + + //Fill our test packet with some junk + for (i = 0; i < MSC_MEDIA_PACKET; i++) + { + freePacket->Data[i] = testDataValue; + testDataValue += 39; + } + + if (Upstream_TransmitPacket(freePacket) == HAL_OK) + { + Upstream_ReceivePacket(Upstream_TestInterfaceReplyCallback); + } +} + + +//Used by upstream_spi freakout macro, indicates we should stop everything. +void Upstream_StateMachine_SetErrorState(void) +{ + UpstreamState = STATE_ERROR; + if ((ActiveDeviceClass > COMMAND_CLASS_INTERFACE) && + (ActiveDeviceClass < COMMAND_CLASS_ERROR)) + { + USBD_Stop(&hUsbDeviceFS); + } +} + + +HAL_StatusTypeDef Upstream_StateMachine_CheckClassOperationOk(void) +{ + if (UpstreamState == STATE_ERROR) + { + return HAL_ERROR; + } + + if (UpstreamState != STATE_DEVICE_ACTIVE) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return HAL_ERROR; + } + + return HAL_OK; +} + + +void Upstream_TestInterfaceReplyCallback(UpstreamPacketTypeDef* replyPacket) +{ + uint16_t i; + uint8_t testDataValue; + + if (UpstreamState >= STATE_ERROR) + { + return; + } + + if ((UpstreamState != STATE_TEST_INTERFACE) || + (replyPacket == NULL)) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + + if (replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + MSC_MEDIA_PACKET)) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + + testDataValue = 0xFF; + for (i = 0; i < MSC_MEDIA_PACKET; i++) + { + if (replyPacket->Data[i] != testDataValue) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + testDataValue += 39; + } + + + //SPI interface passed checks. Now we wait for a device to be attached to downstream. + UpstreamState = STATE_WAIT_DEVICE; + replyPacket->Length = UPSTREAM_PACKET_HEADER_LEN; + replyPacket->CommandClass = COMMAND_CLASS_INTERFACE; + replyPacket->Command = COMMAND_INTERFACE_NOTIFY_DEVICE; + if (Upstream_TransmitPacket(replyPacket) == HAL_OK) + { + Upstream_ReceivePacket(Upstream_NotifyDeviceReplyCallback); + } +} + + +void Upstream_NotifyDeviceReplyCallback(UpstreamPacketTypeDef* replyPacket) +{ + if (UpstreamState >= STATE_ERROR) + { + return; + } + + if ((UpstreamState != STATE_WAIT_DEVICE) || + (replyPacket == NULL)) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + + if (replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) + { + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + + switch (replyPacket->Data[0]) + { + case COMMAND_CLASS_MASS_STORAGE: + USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC); + break; + + default: + UPSTREAM_STATEMACHINE_FREAKOUT; + return; + } + + USBD_Start(&hUsbDeviceFS); + UpstreamState = STATE_DEVICE_ACTIVE; + ActiveDeviceClass = replyPacket->Data[0]; + + //The USB device stack will now receive commands from our host. + //All we need to do is check for downstream device removal. +} + + diff --git a/Upstream/Src/usb_device.c b/Upstream/Src/usb_device.c index 3aadc60..9debcbc 100755 --- a/Upstream/Src/usb_device.c +++ b/Upstream/Src/usb_device.c @@ -33,9 +33,8 @@ ****************************************************************************** */ -/* Includes ------------------------------------------------------------------*/ -#include +#include "usbd_descriptors.h" #include "usb_device.h" #include "usbd_core.h" #include "usbd_msc.h" @@ -43,23 +42,18 @@ /* USB Device Core handle declaration */ USBD_HandleTypeDef hUsbDeviceFS; -/* init function */ + void USB_Device_Init(void) { - /* Init Device Library,Add Supported Class and Start the library*/ - USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS); - - USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC); + USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS); - USBD_Start(&hUsbDeviceFS); +// USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC); +// USBD_Start(&hUsbDeviceFS); } -/** - * @} - */ -/** - * @} - */ + + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/