Revisit Upstream project to:

- Implement Upstream state machine, with Downstream-dependent device
emulation
- Add fault LED flashing
- Improve fault handling and freakouts
- Misc bug fixes
pull/7/head
Robert Fisk 9 years ago
parent fc522bae0a
commit f24714cd8c

@ -9,6 +9,9 @@
#define INC_LED_H_ #define INC_LED_H_
#include "stm32f4xx_hal.h"
void LED_Init(void); void LED_Init(void);
void LED_Fault_SetBlinkRate(uint16_t newBlinkRate); void LED_Fault_SetBlinkRate(uint16_t newBlinkRate);
void LED_DoBlinks(void); void LED_DoBlinks(void);

@ -30,6 +30,7 @@
#include "usbh_msc.h" #include "usbh_msc.h"
#include "downstream_spi.h" #include "downstream_spi.h"
#include "downstream_msc.h" #include "downstream_msc.h"
#include "downstream_statemachine.h"

@ -25,7 +25,6 @@ SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates some
void SPI1_Init(void);
HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void); HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void);
void Downstream_PreparePacketReception(DownstreamPacketTypeDef* freePacket); void Downstream_PreparePacketReception(DownstreamPacketTypeDef* freePacket);
@ -33,28 +32,22 @@ void Downstream_PreparePacketReception(DownstreamPacketTypeDef* freePacket);
void Downstream_InitSPI(void) void Downstream_InitSPI(void)
{ {
SPI1_Init();
DownstreamPacket0.Busy = NOT_BUSY; DownstreamPacket0.Busy = NOT_BUSY;
DownstreamPacket1.Busy = NOT_BUSY; DownstreamPacket1.Busy = NOT_BUSY;
}
Hspi1.Instance = SPI1;
void SPI1_Init(void) Hspi1.Init.Mode = SPI_MODE_SLAVE;
{ Hspi1.Init.Direction = SPI_DIRECTION_2LINES;
Hspi1.Instance = SPI1; Hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
Hspi1.Init.Mode = SPI_MODE_SLAVE; Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
Hspi1.Init.Direction = SPI_DIRECTION_2LINES; Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
Hspi1.Init.DataSize = SPI_DATASIZE_8BIT; Hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
Hspi1.Init.NSS = SPI_NSS_HARD_INPUT; Hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL;
Hspi1.Init.TIMode = SPI_TIMODE_DISABLED; HAL_SPI_Init(&Hspi1);
Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL;
HAL_SPI_Init(&Hspi1);
} }

@ -6,15 +6,14 @@
*/ */
#include "stm32f4xx_hal.h"
#include "led.h" #include "led.h"
#include "board_config.h" #include "board_config.h"
uint16_t FaultLedBlinkRate = 0; uint16_t FaultLedBlinkRate = 0;
uint16_t FaultLedBlinkCounter = 0; uint16_t FaultLedBlinkCounter = 0;
uint8_t FaultLedState = 0; uint8_t FaultLedState = 0;
void LED_Init(void) void LED_Init(void)

@ -109,7 +109,7 @@
</toolChain> </toolChain>
</folderInfo> </folderInfo>
<sourceEntries> <sourceEntries>
<entry excluding="Src/upstream_msc.c|Src/upstream_interface_msc.c|Src/downstream_interface_msc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c|Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c|Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> <entry excluding="Src/upstream_msc_mock.c|Src/upstream_interface_msc.c|Src/downstream_interface_msc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c|Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c|Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries> </sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>
@ -234,7 +234,7 @@
</toolChain> </toolChain>
</folderInfo> </folderInfo>
<sourceEntries> <sourceEntries>
<entry excluding="Src/upstream_msc.c|Src/upstream_interface_msc.c|Src/downstream_interface_msc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c|Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c|Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> <entry excluding="Src/upstream_msc_mock.c|Src/upstream_interface_msc.c|Src/downstream_interface_msc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c|Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c|Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries> </sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>

@ -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_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 SPI_DMA_ACTIVE_PIN GPIO_PIN_5 /////////Temporary indicator of SPI & DMA activity //#define RUN_LED_ON......
#define SPI_DMA_ACTIVE_PORT GPIOB #define FAULT_LED_ON STAT_LED_ON
#define SPI_DMA_ACTIVE_ON SPI_DMA_ACTIVE_PORT->BSRR = (SPI_DMA_ACTIVE_PIN << BSRR_SHIFT_LOW) #define FAULT_LED_OFF STAT_LED_OFF
#define SPI_DMA_ACTIVE_OFF SPI_DMA_ACTIVE_PORT->BSRR = (SPI_DMA_ACTIVE_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 SPI1_NSS_PIN GPIO_PIN_4 #define SPI1_NSS_PIN GPIO_PIN_4
#define SPI1_NSS_PORT GPIOA #define SPI1_NSS_PORT GPIOA

@ -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_ */

@ -13,12 +13,11 @@
typedef void (*UpstreamMSCCallbackTypeDef)(HAL_StatusTypeDef result); typedef void (*UpstreamMSCCallbackTypeDef)(HAL_StatusTypeDef result);
typedef void (*UpstreamMSCCallbackPacketTypeDef)(HAL_StatusTypeDef result, typedef void (*UpstreamMSCCallbackPacketTypeDef)(UpstreamPacketTypeDef* upstreamPacket,
UpstreamPacketTypeDef* upstreamPacket,
uint16_t dataLength); uint16_t dataLength);
typedef void (*UpstreamMSCCallbackUintPacketTypeDef)(HAL_StatusTypeDef result, typedef void (*UpstreamMSCCallbackUintPacketTypeDef)(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint[], uint32_t result_uint1,
UpstreamPacketTypeDef* upstreamPacket); uint32_t result_uint2);
HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback); HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback);

@ -17,32 +17,19 @@
#define UPSTREAM_PACKET_LEN_MIN (UPSTREAM_PACKET_HEADER_LEN) #define UPSTREAM_PACKET_LEN_MIN (UPSTREAM_PACKET_HEADER_LEN)
#define SPI_INTERFACE_FREAKOUT_RETURN_VOID \ #define UPSTREAM_SPI_FREAKOUT \
do { \ do { \
while (1); \ LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
/*UpstreamInterfaceState = INTERFACE_STATE_ERROR;*/ \ UpstreamInterfaceState = UPSTREAM_INTERFACE_ERROR; \
/*return;*/ \ Upstream_StateMachine_SetErrorState(); \
while (1); \
} while (0); } 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 typedef enum
{ {
UPSTREAM_INTERFACE_RESET,
UPSTREAM_INTERFACE_AWAITING_DEVICE,
UPSTREAM_INTERFACE_IDLE, UPSTREAM_INTERFACE_IDLE,
UPSTREAM_INTERFACE_TX_SIZE_WAIT, UPSTREAM_INTERFACE_TX_SIZE_WAIT,
UPSTREAM_INTERFACE_TX_SIZE, UPSTREAM_INTERFACE_TX_SIZE,

@ -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_ */

@ -43,11 +43,15 @@
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "usbd_def.h" #include "usbd_def.h"
extern USBD_HandleTypeDef hUsbDeviceFS; extern USBD_HandleTypeDef hUsbDeviceFS;
/* USB_Device init function */
void USB_Device_Init(void); void USB_Device_Init(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -104,15 +104,14 @@ static void SCSI_Verify10(void);
static int8_t SCSI_CheckAddressRange (uint32_t blk_offset , uint16_t blk_nbr); static int8_t SCSI_CheckAddressRange (uint32_t blk_offset , uint16_t blk_nbr);
void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result); void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result);
void SCSI_ReadCapacity10Callback(HAL_StatusTypeDef result, void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint[], uint32_t result_uint1,
UpstreamPacketTypeDef* upstreamPacket); uint32_t result_uint2);
void SCSI_ReadFormatCapacityCallback(HAL_StatusTypeDef result, void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint[], uint32_t result_uint1,
UpstreamPacketTypeDef* packetToUse); uint32_t result_uint2);
void SCSI_Read10BeginCallback(HAL_StatusTypeDef result); void SCSI_Read10BeginCallback(HAL_StatusTypeDef result);
void SCSI_Read10ReplyCallback(HAL_StatusTypeDef result, void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket,
UpstreamPacketTypeDef* upstreamPacket,
uint16_t dataLength); uint16_t dataLength);
void SCSI_Write10BeginCallback(HAL_StatusTypeDef result); void SCSI_Write10BeginCallback(HAL_StatusTypeDef result);
void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket); void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket);
@ -316,16 +315,16 @@ static void SCSI_ReadCapacity10(void)
{ {
if (Upstream_MSC_GetCapacity(SCSI_ReadCapacity10Callback) != HAL_OK) 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, void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint[], uint32_t result_uint1,
UpstreamPacketTypeDef* upstreamPacket) uint32_t result_uint2)
{ {
if (result != HAL_OK) if (upstreamPacket == NULL)
{ {
SCSI_SenseCode(SCSI_ProcessCmd_pdev, SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun, SCSI_ProcessCmd_lun,
@ -338,8 +337,8 @@ void SCSI_ReadCapacity10Callback(HAL_StatusTypeDef result,
SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket; SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket;
SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data; SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data;
SCSI_ProcessCmd_hmsc->scsi_blk_nbr = result_uint[0]; SCSI_ProcessCmd_hmsc->scsi_blk_nbr = result_uint1;
SCSI_ProcessCmd_hmsc->scsi_blk_size = result_uint[1]; 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[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); 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) 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, void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint[], uint32_t result_uint1,
UpstreamPacketTypeDef* packetToUse) uint32_t result_uint2)
{ {
if (result != HAL_OK) if (upstreamPacket == NULL)
{ {
SCSI_SenseCode(SCSI_ProcessCmd_pdev, SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun, SCSI_ProcessCmd_lun,
@ -385,22 +384,22 @@ void SCSI_ReadFormatCapacityCallback(HAL_StatusTypeDef result,
return; return;
} }
SCSI_ProcessCmd_hmsc->bot_packet = packetToUse; SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket;
SCSI_ProcessCmd_hmsc->bot_data = packetToUse->Data; SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data;
SCSI_ProcessCmd_hmsc->bot_data[0] = 0; SCSI_ProcessCmd_hmsc->bot_data[0] = 0;
SCSI_ProcessCmd_hmsc->bot_data[1] = 0; SCSI_ProcessCmd_hmsc->bot_data[1] = 0;
SCSI_ProcessCmd_hmsc->bot_data[2] = 0; SCSI_ProcessCmd_hmsc->bot_data[2] = 0;
SCSI_ProcessCmd_hmsc->bot_data[3] = 0x08; 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[4] = (uint8_t)((result_uint1 - 1) >> 24);
SCSI_ProcessCmd_hmsc->bot_data[5] = (uint8_t)((result_uint[0] - 1) >> 16); SCSI_ProcessCmd_hmsc->bot_data[5] = (uint8_t)((result_uint1 - 1) >> 16);
SCSI_ProcessCmd_hmsc->bot_data[6] = (uint8_t)((result_uint[0] - 1) >> 8); SCSI_ProcessCmd_hmsc->bot_data[6] = (uint8_t)((result_uint1 - 1) >> 8);
SCSI_ProcessCmd_hmsc->bot_data[7] = (uint8_t)(result_uint[0] - 1); SCSI_ProcessCmd_hmsc->bot_data[7] = (uint8_t)(result_uint1 - 1);
SCSI_ProcessCmd_hmsc->bot_data[8] = 0x02; SCSI_ProcessCmd_hmsc->bot_data[8] = 0x02;
SCSI_ProcessCmd_hmsc->bot_data[9] = (uint8_t)(result_uint[1] >> 16); SCSI_ProcessCmd_hmsc->bot_data[9] = (uint8_t)(result_uint2 >> 16);
SCSI_ProcessCmd_hmsc->bot_data[10] = (uint8_t)(result_uint[1] >> 8); SCSI_ProcessCmd_hmsc->bot_data[10] = (uint8_t)(result_uint2 >> 8);
SCSI_ProcessCmd_hmsc->bot_data[11] = (uint8_t)(result_uint[1]); SCSI_ProcessCmd_hmsc->bot_data[11] = (uint8_t)(result_uint2);
SCSI_ProcessCmd_hmsc->bot_data_length = 12; SCSI_ProcessCmd_hmsc->bot_data_length = 12;
SCSI_ProcessCmd_callback(0); SCSI_ProcessCmd_callback(0);
@ -602,7 +601,7 @@ static void SCSI_Read10(void)
//hmsc->bot_state is already USBD_BOT_DATA_IN //hmsc->bot_state is already USBD_BOT_DATA_IN
if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK) 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) if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK)
{ {
SCSI_Read10ReplyCallback(HAL_ERROR, NULL, 0); SCSI_Read10ReplyCallback(NULL, 0);
} }
} }
void SCSI_Read10ReplyCallback(HAL_StatusTypeDef result, void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket,
UpstreamPacketTypeDef* upstreamPacket,
uint16_t dataLength) uint16_t dataLength)
{ {
if (result != HAL_OK) if (upstreamPacket == NULL)
{ {
SCSI_SenseCode(SCSI_ProcessCmd_pdev, SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun, SCSI_ProcessCmd_lun,

@ -37,6 +37,7 @@
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "stm32f4xx.h" #include "stm32f4xx.h"
#include "board_config.h" #include "board_config.h"
#include "led.h"
/* USER CODE BEGIN 0 */ /* USER CODE BEGIN 0 */
@ -55,7 +56,7 @@ extern DMA_HandleTypeDef spiRxDmaHandle;
void SysTick_Handler(void) void SysTick_Handler(void)
{ {
HAL_IncTick(); HAL_IncTick();
LED_DoBlinks();
} }
///////////////////////// /////////////////////////
@ -65,31 +66,31 @@ void SysTick_Handler(void)
///////////////////////// /////////////////////////
void OTG_FS_IRQHandler(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); HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
STAT_LED_OFF; //STAT_LED_OFF;
} }
void DMA2_Stream2_IRQHandler(void) void DMA2_Stream2_IRQHandler(void)
{ {
SPI_DMA_ACTIVE_ON; //SPI_DMA_ACTIVE_ON;
HAL_DMA_IRQHandler(&spiRxDmaHandle); HAL_DMA_IRQHandler(&spiRxDmaHandle);
SPI_DMA_ACTIVE_OFF; //SPI_DMA_ACTIVE_OFF;
} }
void DMA2_Stream3_IRQHandler(void) void DMA2_Stream3_IRQHandler(void)
{ {
SPI_DMA_ACTIVE_ON; //SPI_DMA_ACTIVE_ON;
HAL_DMA_IRQHandler(&spiTxDmaHandle); HAL_DMA_IRQHandler(&spiTxDmaHandle);
SPI_DMA_ACTIVE_OFF; //SPI_DMA_ACTIVE_OFF;
} }
void EXTI3_IRQHandler(void) void EXTI3_IRQHandler(void)
{ {
SPI_DMA_ACTIVE_ON; //SPI_DMA_ACTIVE_ON;
__HAL_GPIO_EXTI_CLEAR_IT(3); __HAL_GPIO_EXTI_CLEAR_IT(3);
Upstream_TxOkInterrupt(); Upstream_TxOkInterrupt();
SPI_DMA_ACTIVE_OFF; //SPI_DMA_ACTIVE_OFF;
} }
///////////////////////// /////////////////////////
///////////////////////// /////////////////////////

@ -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;
}
}
}
}

@ -33,11 +33,11 @@
*/ */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include <upstream_spi.h>
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "usb_device.h" #include "usb_device.h"
#include "board_config.h" #include "board_config.h"
#include "led.h"
#include "upstream_statemachine.h"
/* Private variables ---------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/
@ -52,8 +52,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();
@ -62,16 +60,16 @@ int main(void)
/* Initialize all configured peripherals */ /* Initialize all configured peripherals */
GPIO_Init(); GPIO_Init();
LED_Init();
USB_Device_Init(); USB_Device_Init();
Upstream_InitSPI(); Upstream_InitStateMachine();
while (1) while (1)
{ {
} }
} }
/** System Clock Configuration /** System Clock Configuration
@ -102,7 +100,7 @@ void SystemClock_Config(void)
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 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); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
} }
@ -153,12 +151,12 @@ void GPIO_Init(void)
HAL_GPIO_Init(STAT_LED_PORT, &GPIO_InitStruct); HAL_GPIO_Init(STAT_LED_PORT, &GPIO_InitStruct);
STAT_LED_OFF; STAT_LED_OFF;
//SPI_DMA_ACTIVE indicator // //SPI_DMA_ACTIVE indicator
GPIO_InitStruct.Pin = SPI_DMA_ACTIVE_PIN; // GPIO_InitStruct.Pin = SPI_DMA_ACTIVE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; // GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SPI_DMA_ACTIVE_PORT, &GPIO_InitStruct); // HAL_GPIO_Init(SPI_DMA_ACTIVE_PORT, &GPIO_InitStruct);
SPI_DMA_ACTIVE_OFF; // SPI_DMA_ACTIVE_OFF;
} }
/* USER CODE BEGIN 4 */ /* USER CODE BEGIN 4 */

@ -6,9 +6,10 @@
*/ */
#include <upstream_interface_def.h> #include "upstream_interface_def.h"
#include <upstream_msc.h> #include "upstream_msc.h"
#include <upstream_spi.h> #include "upstream_spi.h"
#include "upstream_statemachine.h"
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
@ -31,27 +32,45 @@ static void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPac
HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback) HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback)
{ {
UpstreamPacketTypeDef* freePacket; UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
TestReadyCallback = callback; TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
return HAL_ERROR;
}
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN; freePacket->Length = UPSTREAM_PACKET_HEADER_LEN;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_TEST_UNIT_READY; freePacket->Command = COMMAND_MSC_TEST_UNIT_READY;
tempResult = Upstream_TransmitPacket(freePacket); if (Upstream_TransmitPacket(freePacket) == HAL_OK)
if (tempResult != 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) 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)) || if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
(replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE) ||
(replyPacket->Data[0] != HAL_OK)) (replyPacket->Data[0] != HAL_OK))
{ {
Upstream_ReleasePacket(replyPacket); Upstream_ReleasePacket(replyPacket);
@ -68,37 +87,56 @@ void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket)
HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef callback) HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef callback)
{ {
UpstreamPacketTypeDef* freePacket; UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
GetCapacityCallback = callback; GetCapacityCallback = callback;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
return HAL_ERROR;
}
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN; freePacket->Length = UPSTREAM_PACKET_HEADER_LEN;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_GET_CAPACITY; freePacket->Command = COMMAND_MSC_GET_CAPACITY;
tempResult = Upstream_TransmitPacket(freePacket); if (Upstream_TransmitPacket(freePacket) == HAL_OK)
if (tempResult != 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) 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) || if (replyPacket == NULL)
(replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE)))
{ {
GetCapacityCallback(HAL_ERROR, NULL, NULL); GetCapacityCallback(NULL, 0, 0);
return; return;
} }
uint[0] = *(uint32_t*)&(replyPacket->Data[0]); if (replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8))
uint[1] = *(uint32_t*)&(replyPacket->Data[4]); {
GetCapacityCallback(HAL_OK, uint, replyPacket); //usb_msc_scsi will use this packet, so don't release now 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) uint32_t readByteCount)
{ {
UpstreamPacketTypeDef* freePacket; UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0; ReadStreamBusy = 0;
@ -117,6 +159,10 @@ HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback,
TestReadyCallback = callback; TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
return HAL_ERROR;
}
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3); freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
@ -124,18 +170,22 @@ HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback,
*(uint64_t*)&(freePacket->Data[0]) = readBlockStart; *(uint64_t*)&(freePacket->Data[0]) = readBlockStart;
*(uint32_t*)&(freePacket->Data[8]) = readBlockCount; *(uint32_t*)&(freePacket->Data[8]) = readBlockCount;
tempResult = Upstream_TransmitPacket(freePacket); if (Upstream_TransmitPacket(freePacket) == HAL_OK)
if (tempResult != 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) HAL_StatusTypeDef Upstream_MSC_GetStreamDataPacket(UpstreamMSCCallbackPacketTypeDef callback)
{ {
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
GetStreamDataCallback = callback; GetStreamDataCallback = callback;
if (ReadStreamBusy != 0) if (ReadStreamBusy != 0)
@ -159,24 +209,36 @@ void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket
uint16_t dataLength; uint16_t dataLength;
ReadStreamBusy = 0; ReadStreamBusy = 0;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (GetStreamDataCallback == NULL) if (GetStreamDataCallback == NULL)
{ {
ReadStreamPacket = replyPacket; //We used up our callback already, so save this one for later. ReadStreamPacket = replyPacket; //We used up our callback already, so save this one for later.
return; return;
} }
if (replyPacket == NULL)
{
GetStreamDataCallback(NULL, 0);
return;
}
dataLength = replyPacket->Length - UPSTREAM_PACKET_HEADER_LEN; 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 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. (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 (dataLength > ByteCount)) //No more data than expected transfer length
{ {
GetStreamDataCallback(HAL_ERROR, NULL, NULL); GetStreamDataCallback(NULL, 0);
return; return;
} }
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)
{ {
Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it 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) uint32_t readBlockCount)
{ {
UpstreamPacketTypeDef* freePacket; UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
TestReadyCallback = callback; TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
return HAL_ERROR;
}
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3); freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
@ -201,19 +271,31 @@ HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback,
*(uint64_t*)&(freePacket->Data[0]) = readBlockStart; *(uint64_t*)&(freePacket->Data[0]) = readBlockStart;
*(uint32_t*)&(freePacket->Data[8]) = readBlockCount; *(uint32_t*)&(freePacket->Data[8]) = readBlockCount;
tempResult = Upstream_TransmitPacket(freePacket); if (Upstream_TransmitPacket(freePacket) == HAL_OK)
if (tempResult != 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) 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)) || if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
(replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE) ||
((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY))) ((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY)))
{ {
Upstream_ReleasePacket(replyPacket); Upstream_ReleasePacket(replyPacket);
@ -221,8 +303,9 @@ void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket)
return; return;
} }
tempResult = replyPacket->Data[0];
Upstream_ReleasePacket(replyPacket); 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, HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend,
uint32_t dataLength) uint32_t dataLength)
{ {
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
packetToSend->Length = dataLength + UPSTREAM_PACKET_HEADER_LEN; packetToSend->Length = dataLength + UPSTREAM_PACKET_HEADER_LEN;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG; packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_BEGIN_WRITE; packetToSend->Command = COMMAND_MSC_BEGIN_WRITE;

@ -5,8 +5,9 @@
* Author: Robert Fisk * Author: Robert Fisk
*/ */
#include <upstream_interface_def.h> #include "upstream_interface_def.h"
#include <upstream_spi.h> #include "upstream_spi.h"
#include "upstream_statemachine.h"
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "usbd_def.h" #include "usbd_def.h"
#include "board_config.h" #include "board_config.h"
@ -17,17 +18,16 @@ SPI_HandleTypeDef Hspi1;
UpstreamPacketTypeDef UpstreamPacket0; UpstreamPacketTypeDef UpstreamPacket0;
UpstreamPacketTypeDef UpstreamPacket1; UpstreamPacketTypeDef UpstreamPacket1;
UpstreamPacketTypeDef* CurrentWorkingPacket; UpstreamPacketTypeDef* CurrentWorkingPacket;
UpstreamPacketTypeDef* NextTxPacket; //Indicates we have a pending TX packet UpstreamPacketTypeDef* NextTxPacket = NULL; //Indicates we have a pending TX packet
InterfaceStateTypeDef UpstreamInterfaceState; InterfaceStateTypeDef UpstreamInterfaceState = UPSTREAM_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
uint8_t SentCommandClass; uint8_t SentCommandClass;
uint8_t SentCommand; uint8_t SentCommand;
static void SPI1_Init(void);
static HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void); static HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void);
static void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket); static void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket);
@ -35,24 +35,9 @@ static void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket);
void Upstream_InitSPI(void) void Upstream_InitSPI(void)
{ {
UpstreamInterfaceState = UPSTREAM_INTERFACE_RESET;
SPI1_Init();
UpstreamPacket0.Busy = NOT_BUSY; UpstreamPacket0.Busy = NOT_BUSY;
UpstreamPacket1.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.Instance = SPI1;
Hspi1.State = HAL_SPI_STATE_RESET; Hspi1.State = HAL_SPI_STATE_RESET;
Hspi1.Init.Mode = SPI_MODE_MASTER; 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. //Used by USB interface classes, and by our internal RX code.
HAL_StatusTypeDef Upstream_GetFreePacket(FreePacketCallbackTypeDef callback) HAL_StatusTypeDef Upstream_GetFreePacket(FreePacketCallbackTypeDef callback)
{ {
//Sanity checks if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
if ((UpstreamInterfaceState < UPSTREAM_INTERFACE_IDLE) ||
(UpstreamInterfaceState > UPSTREAM_INTERFACE_RX_PACKET))
{ {
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; UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
} }
//Check if there is a free buffer now //Check if there is a free buffer now
@ -109,11 +93,9 @@ HAL_StatusTypeDef Upstream_GetFreePacket(FreePacketCallbackTypeDef callback)
UpstreamPacketTypeDef* Upstream_GetFreePacketImmediately(void) UpstreamPacketTypeDef* Upstream_GetFreePacketImmediately(void)
{ {
//Sanity checks if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
if ((UpstreamInterfaceState < UPSTREAM_INTERFACE_IDLE) ||
(UpstreamInterfaceState > UPSTREAM_INTERFACE_RX_PACKET))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; return NULL;
} }
//We are expecting a free buffer now //We are expecting a free buffer now
@ -129,7 +111,8 @@ UpstreamPacketTypeDef* Upstream_GetFreePacketImmediately(void)
} }
//Should not happen: //Should not happen:
SPI_INTERFACE_FREAKOUT_NO_RETURN; UPSTREAM_SPI_FREAKOUT;
return NULL;
} }
@ -138,10 +121,16 @@ void Upstream_ReleasePacket(UpstreamPacketTypeDef* packetToRelease)
{ {
FreePacketCallbackTypeDef tempCallback; FreePacketCallbackTypeDef tempCallback;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
if ((packetToRelease != &UpstreamPacket0) && if ((packetToRelease != &UpstreamPacket0) &&
(packetToRelease != &UpstreamPacket1)) (packetToRelease != &UpstreamPacket1))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; UPSTREAM_SPI_FREAKOUT;
return;
} }
if (PendingFreePacketCallback != NULL) 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. //as we can't let the size/packet sequence get out of sync.
HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite) HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite)
{ {
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Sanity checks //Sanity checks
if ((packetToWrite != &UpstreamPacket0) && if ((packetToWrite != &UpstreamPacket0) &&
(packetToWrite != &UpstreamPacket1)) (packetToWrite != &UpstreamPacket1))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
} }
if ((packetToWrite->Busy != BUSY) || if ((packetToWrite->Busy != BUSY) ||
(packetToWrite->Length < UPSTREAM_PACKET_LEN_MIN) || (packetToWrite->Length < UPSTREAM_PACKET_LEN_MIN) ||
(packetToWrite->Length > UPSTREAM_PACKET_LEN)) (packetToWrite->Length > UPSTREAM_PACKET_LEN))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
} }
if (NextTxPacket != NULL) if (NextTxPacket != NULL)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
} }
switch (UpstreamInterfaceState) switch (UpstreamInterfaceState)
@ -197,7 +194,8 @@ HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite)
break; break;
default: default:
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
} }
return HAL_OK; return HAL_OK;
} }
@ -210,26 +208,32 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{ {
SPI1_NSS_DEASSERT; SPI1_NSS_DEASSERT;
if ((UpstreamInterfaceState != UPSTREAM_INTERFACE_TX_SIZE) && if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
(UpstreamInterfaceState != UPSTREAM_INTERFACE_TX_PACKET))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; return;
} }
//Finished transmitting packet size
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_SIZE) if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_SIZE)
{ {
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_PACKET_WAIT; UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_PACKET_WAIT;
return; return;
} }
//Finished transmitting packet body
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_PACKET) if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_PACKET)
{ {
if ((PendingFreePacketCallback != NULL) && (NextTxPacket == NULL)) if ((PendingFreePacketCallback != NULL) && (NextTxPacket == NULL))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; UPSTREAM_SPI_FREAKOUT;
return;
} }
Upstream_ReleasePacket(CurrentWorkingPacket); Upstream_ReleasePacket(CurrentWorkingPacket);
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_ERROR)
{
return; //Really shouldn't happen, but we are being paranoid...
}
if (NextTxPacket != NULL) if (NextTxPacket != NULL)
{ {
//NextTxPacket has already passed the checks in Upstream_TransmitPacket. //NextTxPacket has already passed the checks in Upstream_TransmitPacket.
@ -245,7 +249,11 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{ {
Upstream_CheckBeginPacketReception(); 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. //Not OK to call when receiving or waiting for downstream reply.
HAL_StatusTypeDef Upstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback) HAL_StatusTypeDef Upstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback)
{ {
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if (ReceivePacketCallback != NULL) if (ReceivePacketCallback != NULL)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
} }
ReceivePacketCallback = callback; ReceivePacketCallback = callback;
@ -267,10 +281,15 @@ HAL_StatusTypeDef Upstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callba
//Internal use only. //Internal use only.
HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void) HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void)
{ {
if ((UpstreamInterfaceState < UPSTREAM_INTERFACE_IDLE) || if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
(UpstreamInterfaceState > UPSTREAM_INTERFACE_RX_SIZE_WAIT)) {
return HAL_ERROR;
}
if (UpstreamInterfaceState > UPSTREAM_INTERFACE_RX_SIZE_WAIT)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
} }
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_IDLE) if (UpstreamInterfaceState == UPSTREAM_INTERFACE_IDLE)
@ -285,6 +304,11 @@ HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void)
//indicating that downstream is ready for the next transaction. //indicating that downstream is ready for the next transaction.
void Upstream_TxOkInterrupt(void) void Upstream_TxOkInterrupt(void)
{ {
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
switch (UpstreamInterfaceState) switch (UpstreamInterfaceState)
{ {
case UPSTREAM_INTERFACE_TX_SIZE_WAIT: case UPSTREAM_INTERFACE_TX_SIZE_WAIT:
@ -294,7 +318,7 @@ void Upstream_TxOkInterrupt(void)
(uint8_t*)&CurrentWorkingPacket->Length, (uint8_t*)&CurrentWorkingPacket->Length,
2) != HAL_OK) 2) != HAL_OK)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; UPSTREAM_SPI_FREAKOUT;
} }
break; break;
@ -305,7 +329,7 @@ void Upstream_TxOkInterrupt(void)
&CurrentWorkingPacket->CommandClass, &CurrentWorkingPacket->CommandClass,
CurrentWorkingPacket->Length)) != HAL_OK) CurrentWorkingPacket->Length)) != HAL_OK)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; UPSTREAM_SPI_FREAKOUT;
} }
break; break;
@ -320,12 +344,12 @@ void Upstream_TxOkInterrupt(void)
&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; UPSTREAM_SPI_FREAKOUT;
} }
break; break;
default: 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. //Called when we want to receive downstream packet, and a packet buffer has become free.
void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket) void Upstream_BeginPacketReception(UpstreamPacketTypeDef* freePacket)
{ {
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
if (UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_SIZE_WAIT) if (UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_SIZE_WAIT)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; UPSTREAM_SPI_FREAKOUT;
return;
} }
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_SIZE; UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_SIZE;
CurrentWorkingPacket = freePacket; CurrentWorkingPacket = freePacket;
@ -346,7 +376,7 @@ void Upstream_BeginPacketReception(UpstreamPacketTypeDef* 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; UPSTREAM_SPI_FREAKOUT;
} }
} }
@ -359,10 +389,9 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
SPI1_NSS_DEASSERT; SPI1_NSS_DEASSERT;
if ((UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_SIZE) && if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
(UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_PACKET))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; return;
} }
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_SIZE) if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_SIZE)
@ -370,7 +399,8 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
if ((CurrentWorkingPacket->Length < UPSTREAM_PACKET_LEN_MIN) || if ((CurrentWorkingPacket->Length < UPSTREAM_PACKET_LEN_MIN) ||
(CurrentWorkingPacket->Length > UPSTREAM_PACKET_LEN)) (CurrentWorkingPacket->Length > UPSTREAM_PACKET_LEN))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; UPSTREAM_SPI_FREAKOUT;
return;
} }
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_PACKET_WAIT; UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_PACKET_WAIT;
return; return;
@ -378,29 +408,53 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_PACKET) if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_PACKET)
{ {
UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE; if (ReceivePacketCallback == NULL)
if (((SentCommandClass != (CurrentWorkingPacket->CommandClass & COMMAND_CLASS_MASK)) &&
(SentCommandClass != COMMAND_CLASS_ERROR)) ||
(SentCommand != CurrentWorkingPacket->Command))
{ {
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, //USB interface may want to receive another packet immediately,
//so clear ReceivePacketCallback before the call. //so clear ReceivePacketCallback before the call.
//It is the callback's responsibility to release the packet buffer we are passing to it! //It is the callback's responsibility to release the packet buffer we are passing to it!
tempPacketCallback = ReceivePacketCallback; tempPacketCallback = ReceivePacketCallback;
ReceivePacketCallback = NULL; ReceivePacketCallback = NULL;
tempPacketCallback(CurrentWorkingPacket); tempPacketCallback(CurrentWorkingPacket);
return;
} }
//case default:
UPSTREAM_SPI_FREAKOUT;
} }
//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; 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
}
} }

@ -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.
}

@ -33,9 +33,8 @@
****************************************************************************** ******************************************************************************
*/ */
/* Includes ------------------------------------------------------------------*/
#include <usbd_descriptors.h> #include "usbd_descriptors.h"
#include "usb_device.h" #include "usb_device.h"
#include "usbd_core.h" #include "usbd_core.h"
#include "usbd_msc.h" #include "usbd_msc.h"
@ -43,23 +42,18 @@
/* USB Device Core handle declaration */ /* USB Device Core handle declaration */
USBD_HandleTypeDef hUsbDeviceFS; USBD_HandleTypeDef hUsbDeviceFS;
/* init function */
void USB_Device_Init(void) void USB_Device_Init(void)
{ {
/* Init Device Library,Add Supported Class and Start the library*/ USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC);
USBD_Start(&hUsbDeviceFS); // USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC);
// USBD_Start(&hUsbDeviceFS);
} }
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Loading…
Cancel
Save