aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src')
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/main.c102
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/system_stm32f37x.c380
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/usb_istr.c236
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/usb_scsi.c440
4 files changed, 1158 insertions, 0 deletions
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/main.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/main.c
new file mode 100644
index 0000000..cc8eeec
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/main.c
@@ -0,0 +1,102 @@
+/**
+ ******************************************************************************
+ * @file main.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief Custom HID demo main file
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "hw_config.h"
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+__IO uint8_t PrevXferComplete = 1;
+__IO uint32_t TimingDelay = 0;
+/* Private function prototypes -----------------------------------------------*/
+void Delay(__IO uint32_t nCount);
+
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name : main.
+* Description : main routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+int main(void)
+{
+ Set_System();
+
+ USB_Interrupts_Config();
+
+ Set_USBClock();
+
+ USB_Init();
+
+ while (1)
+ {
+ }
+}
+
+/*******************************************************************************
+* Function Name : Delay
+* Description : Inserts a delay time.
+* Input : nCount: specifies the delay time length.
+* Output : None
+* Return : None
+*******************************************************************************/
+void Delay(__IO uint32_t nCount)
+{
+ TimingDelay = nCount;
+ for(; nCount!= 0;nCount--);
+}
+
+#ifdef USE_FULL_ASSERT
+/*******************************************************************************
+* Function Name : assert_failed
+* Description : Reports the name of the source file and the source line number
+* where the assert_param error has occurred.
+* Input : - file: pointer to the source file name
+* - line: assert_param error line source number
+* Output : None
+* Return : None
+*******************************************************************************/
+void assert_failed(uint8_t* file, uint32_t line)
+{
+ /* User can add his own implementation to report the file name and line number,
+ ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+
+ /* Infinite loop */
+ while(1)
+ {
+ }
+}
+#endif
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/system_stm32f37x.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/system_stm32f37x.c
new file mode 100644
index 0000000..943f188
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/system_stm32f37x.c
@@ -0,0 +1,380 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f37x.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
+ * This file contains the system clock configuration for STM32F37x devices,
+ * and is generated by the clock configuration tool
+ * STM32f37x_Clock_Configuration_V1.0.0.xls
+ *
+ * 1. This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+ * and Divider factors, AHB/APBx prescalers and Flash settings),
+ * depending on the configuration made in the clock xls tool.
+ * This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32f37x.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * 2. After each device reset the HSI (8 MHz Range) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32f37x.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 3. If the system clock source selected by user fails to startup, the SystemInit()
+ * function will do nothing and HSI still used as system clock source. User can
+ * add some code to deal with this issue inside the SetSysClock() function.
+ *
+ * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" defined
+ * in "stm32f37x.h" file. When HSE is used as system clock source, directly or
+ * through PLL, and you are using different crystal you have to adapt the HSE
+ * value to your own configuration.
+ *
+ * 5. This file configures the system clock as follows:
+ *=============================================================================
+ * Supported STM32F37x device
+ *=============================================================================
+ * System Clock source | PLL (HSE)
+ *-----------------------------------------------------------------------------
+ * SYSCLK(Hz) | 72000000
+ *-----------------------------------------------------------------------------
+ * HCLK(Hz) | 72000000
+ *-----------------------------------------------------------------------------
+ * AHB Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB2 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB1 Prescaler | 2
+ *-----------------------------------------------------------------------------
+ * HSE Frequency(Hz) | 8000000
+ *----------------------------------------------------------------------------
+ * PLLMUL | 9
+ *-----------------------------------------------------------------------------
+ * PREDIV | 1
+ *-----------------------------------------------------------------------------
+ * USB Clock | ENABLE
+ *-----------------------------------------------------------------------------
+ * Flash Latency(WS) | 2
+ *-----------------------------------------------------------------------------
+ * Prefetch Buffer | ON
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup STM32F37x_System
+ * @{
+ */
+
+/** @addtogroup STM32F37x_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f37x.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_Defines
+ * @{
+ */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_Variables
+ * @{
+ */
+uint32_t SystemCoreClock = 72000000;
+__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_FunctionPrototypes
+ * @{
+ */
+
+static void SetSysClock(void);
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontrollers system.
+ * Initialize the Embedded Flash Interface, the PLL and update the
+ * SystemCoreClock variable.
+ * @param None
+ * @retval None
+ */
+void SystemInit (void)
+{
+ /* FPU settings ------------------------------------------------------------*/
+ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
+ #endif
+
+ /* Set HSION bit */
+ RCC->CR |= (uint32_t)0x00000001;
+
+ /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, SDADCPRE and MCOSEL[2:0] bits */
+ RCC->CFGR &= (uint32_t)0x00FF0000;
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+ /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */
+ RCC->CFGR &= (uint32_t)0xFF80FFFF;
+
+ /* Reset PREDIV1[3:0] bits */
+ RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
+
+ /* Reset USARTSW[1:0], I2CSW and CECSW bits */
+ RCC->CFGR3 &= (uint32_t)0xFFF0F8C;
+
+ /* Disable all interrupts */
+ RCC->CIR = 0x00000000;
+
+/* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
+ SetSysClock();
+
+
+#ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
+#else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
+#endif
+}
+
+/**
+ * @brief Update SystemCoreClock according to Clock Register Values
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f37x.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f37x.h file (default value
+ * 8 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate (void)
+{
+ uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ case 0x04: /* HSE used as system clock */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ case 0x08: /* PLL used as system clock */
+ /* Get PLL clock source and multiplication factor ----------------------*/
+ pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
+ pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+ pllmull = ( pllmull >> 18) + 2;
+
+ if (pllsource == 0x00)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
+ }
+ else
+ {
+ prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
+ }
+ break;
+ default: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK clock frequency ----------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+ /* HCLK clock frequency */
+ SystemCoreClock >>= tmp;
+}
+
+/**
+ * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash
+ * settings.
+ * @note This function should be called only once the RCC clock configuration
+ * is reset to the default reset state (done in SystemInit() function).
+ * @param None
+ * @retval None
+ */
+static void SetSysClock(void)
+{
+ __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+
+/******************************************************************************/
+/* PLL (clocked by HSE) used as System clock source */
+/******************************************************************************/
+
+ /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------*/
+ /* Enable HSE */
+ RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+
+ /* Wait till HSE is ready and if Time out is reached exit */
+ do
+ {
+ HSEStatus = RCC->CR & RCC_CR_HSERDY;
+ StartUpCounter++;
+ } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+ if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+ {
+ HSEStatus = (uint32_t)0x01;
+ }
+ else
+ {
+ HSEStatus = (uint32_t)0x00;
+ }
+
+ if (HSEStatus == (uint32_t)0x01)
+ {
+ /* Enable Prefetch Buffer and set Flash Latency */
+ FLASH->ACR = FLASH_ACR_PRFTBE | (uint32_t)FLASH_ACR_LATENCY_1;
+
+ /* HCLK = SYSCLK / 1 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+
+ /* PCLK2 = HCLK / 1 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+
+ /* PCLK1 = HCLK / 2 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
+
+ /* PLL configuration */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
+ RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL9);
+
+ /* Enable PLL */
+ RCC->CR |= RCC_CR_PLLON;
+
+ /* Wait till PLL is ready */
+ while((RCC->CR & RCC_CR_PLLRDY) == 0)
+ {
+ }
+
+ /* Select PLL as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
+
+ /* Wait till PLL is used as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
+ {
+ }
+ }
+ else
+ { /* If HSE fails to start-up, the application will have wrong clock
+ configuration. User can add here some code to deal with this error */
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/usb_istr.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/usb_istr.c
new file mode 100644
index 0000000..bb1cf25
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/usb_istr.c
@@ -0,0 +1,236 @@
+/**
+ ******************************************************************************
+ * @file usb_istr.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief ISTR events interrupt service routines
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_prop.h"
+#include "usb_pwr.h"
+#include "usb_istr.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint16_t wIstr; /* ISTR register last read value */
+__IO uint8_t bIntPackSOF = 0; /* SOFs received between 2 consecutive packets */
+__IO uint32_t esof_counter =0; /* expected SOF counter */
+__IO uint32_t wCNTR=0;
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* function pointers to non-control endpoints service routines */
+void (*pEpInt_IN[7])(void) =
+ {
+ EP1_IN_Callback,
+ EP2_IN_Callback,
+ EP3_IN_Callback,
+ EP4_IN_Callback,
+ EP5_IN_Callback,
+ EP6_IN_Callback,
+ EP7_IN_Callback,
+ };
+
+void (*pEpInt_OUT[7])(void) =
+ {
+ EP1_OUT_Callback,
+ EP2_OUT_Callback,
+ EP3_OUT_Callback,
+ EP4_OUT_Callback,
+ EP5_OUT_Callback,
+ EP6_OUT_Callback,
+ EP7_OUT_Callback,
+ };
+
+/*******************************************************************************
+* Function Name : USB_Istr
+* Description : ISTR events interrupt service routine
+* Input :
+* Output :
+* Return :
+*******************************************************************************/
+void USB_Istr(void)
+{
+ uint32_t i=0;
+ __IO uint32_t EP[8];
+
+ wIstr = _GetISTR();
+
+#if (IMR_MSK & ISTR_CTR)
+ if (wIstr & ISTR_CTR & wInterrupt_Mask)
+ {
+ /* servicing of the endpoint correct transfer interrupt */
+ /* clear of the CTR flag into the sub */
+ CTR_LP();
+#ifdef CTR_CALLBACK
+ CTR_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_RESET)
+ if (wIstr & ISTR_RESET & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_RESET);
+ Device_Property.Reset();
+#ifdef RESET_CALLBACK
+ RESET_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_DOVR)
+ if (wIstr & ISTR_DOVR & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_DOVR);
+#ifdef DOVR_CALLBACK
+ DOVR_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_ERR)
+ if (wIstr & ISTR_ERR & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_ERR);
+#ifdef ERR_CALLBACK
+ ERR_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_WKUP)
+ if (wIstr & ISTR_WKUP & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_WKUP);
+ Resume(RESUME_EXTERNAL);
+#ifdef WKUP_CALLBACK
+ WKUP_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_SUSP)
+ if (wIstr & ISTR_SUSP & wInterrupt_Mask)
+ {
+
+ /* check if SUSPEND is possible */
+ if (fSuspendEnabled)
+ {
+ Suspend();
+ }
+ else
+ {
+ /* if not possible then resume after xx ms */
+ Resume(RESUME_LATER);
+ }
+ /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
+ _SetISTR((uint16_t)CLR_SUSP);
+#ifdef SUSP_CALLBACK
+ SUSP_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_SOF)
+ if (wIstr & ISTR_SOF & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_SOF);
+ bIntPackSOF++;
+
+#ifdef SOF_CALLBACK
+ SOF_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_ESOF)
+ if (wIstr & ISTR_ESOF & wInterrupt_Mask)
+ {
+ /* clear ESOF flag in ISTR */
+ _SetISTR((uint16_t)CLR_ESOF);
+
+ if ((_GetFNR()&FNR_RXDP)!=0)
+ {
+ /* increment ESOF counter */
+ esof_counter ++;
+
+ /* test if we enter in ESOF more than 3 times with FSUSP =0 and RXDP =1=>> possible missing SUSP flag*/
+ if ((esof_counter >3)&&((_GetCNTR()&CNTR_FSUSP)==0))
+ {
+ /* this a sequence to apply a force RESET*/
+
+ /*Store CNTR value */
+ wCNTR = _GetCNTR();
+
+ /*Store endpoints registers status */
+ for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i);
+
+ /*apply FRES */
+ wCNTR|=CNTR_FRES;
+ _SetCNTR(wCNTR);
+
+ /*clear FRES*/
+ wCNTR&=~CNTR_FRES;
+ _SetCNTR(wCNTR);
+
+ /*poll for RESET flag in ISTR*/
+ while((_GetISTR()&ISTR_RESET) == 0);
+
+ /* clear RESET flag in ISTR */
+ _SetISTR((uint16_t)CLR_RESET);
+
+ /*restore Enpoints*/
+ for (i=0;i<8;i++)
+ _SetENDPOINT(i, EP[i]);
+
+ esof_counter = 0;
+ }
+ }
+ else
+ {
+ esof_counter = 0;
+ }
+
+ /* resume handling timing is made with ESOFs */
+ Resume(RESUME_ESOF); /* request without change of the machine state */
+
+#ifdef ESOF_CALLBACK
+ ESOF_Callback();
+#endif
+ }
+#endif
+} /* USB_Istr */
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/usb_scsi.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/usb_scsi.c
new file mode 100644
index 0000000..986b81f
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src/usb_scsi.c
@@ -0,0 +1,440 @@
+/**
+ ******************************************************************************
+ * @file usb_scsi.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief All processing related to the SCSI commands
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "hw_config.h"
+#include "usb_scsi.h"
+#include "mass_mal.h"
+#include "usb_bot.h"
+#include "usb_regs.h"
+#include "memory.h"
+#include "platform_config.h"
+#include "usb_lib.h"
+
+#ifdef USE_STM3210E_EVAL
+ #include "nand_if.h"
+#endif /* USE_STM3210E_EVAL */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* External variables --------------------------------------------------------*/
+extern uint8_t Bulk_Data_Buff[64]; /* data buffer*/
+extern uint8_t Bot_State;
+extern Bulk_Only_CBW CBW;
+extern Bulk_Only_CSW CSW;
+extern uint32_t Mass_Memory_Size[2];
+extern uint32_t Mass_Block_Size[2];
+extern uint32_t Mass_Block_Count[2];
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name : SCSI_Inquiry_Cmd
+* Description : SCSI Inquiry Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_Inquiry_Cmd(uint8_t lun)
+{
+ uint8_t* Inquiry_Data;
+ uint16_t Inquiry_Data_Length;
+
+ if (CBW.CB[1] & 0x01)/*Evpd is set*/
+ {
+ Inquiry_Data = Page00_Inquiry_Data;
+ Inquiry_Data_Length = 5;
+ }
+ else
+ {
+ if ( lun == 0)
+ {
+ Inquiry_Data = Standard_Inquiry_Data;
+ }
+ else
+ {
+ Inquiry_Data = Standard_Inquiry_Data2;
+ }
+ if (CBW.CB[4] <= STANDARD_INQUIRY_DATA_LEN)
+ Inquiry_Data_Length = CBW.CB[4];
+ else
+ Inquiry_Data_Length = STANDARD_INQUIRY_DATA_LEN;
+ }
+ Transfer_Data_Request(Inquiry_Data, Inquiry_Data_Length);
+}
+
+/*******************************************************************************
+* Function Name : SCSI_ReadFormatCapacity_Cmd
+* Description : SCSI ReadFormatCapacity Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_ReadFormatCapacity_Cmd(uint8_t lun)
+{
+ if (MAL_GetStatus(lun) != 0 )
+ {
+ Set_Scsi_Sense_Data(CBW.bLUN, NOT_READY, MEDIUM_NOT_PRESENT);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
+ Bot_Abort(DIR_IN);
+ return;
+ }
+ ReadFormatCapacity_Data[4] = (uint8_t)(Mass_Block_Count[lun] >> 24);
+ ReadFormatCapacity_Data[5] = (uint8_t)(Mass_Block_Count[lun] >> 16);
+ ReadFormatCapacity_Data[6] = (uint8_t)(Mass_Block_Count[lun] >> 8);
+ ReadFormatCapacity_Data[7] = (uint8_t)(Mass_Block_Count[lun]);
+
+ ReadFormatCapacity_Data[9] = (uint8_t)(Mass_Block_Size[lun] >> 16);
+ ReadFormatCapacity_Data[10] = (uint8_t)(Mass_Block_Size[lun] >> 8);
+ ReadFormatCapacity_Data[11] = (uint8_t)(Mass_Block_Size[lun]);
+ Transfer_Data_Request(ReadFormatCapacity_Data, READ_FORMAT_CAPACITY_DATA_LEN);
+}
+
+/*******************************************************************************
+* Function Name : SCSI_ReadCapacity10_Cmd
+* Description : SCSI ReadCapacity10 Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_ReadCapacity10_Cmd(uint8_t lun)
+{
+ if (MAL_GetStatus(lun))
+ {
+ Set_Scsi_Sense_Data(CBW.bLUN, NOT_READY, MEDIUM_NOT_PRESENT);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
+ Bot_Abort(DIR_IN);
+ return;
+ }
+
+ ReadCapacity10_Data[0] = (uint8_t)((Mass_Block_Count[lun] - 1) >> 24);
+ ReadCapacity10_Data[1] = (uint8_t)((Mass_Block_Count[lun] - 1) >> 16);
+ ReadCapacity10_Data[2] = (uint8_t)((Mass_Block_Count[lun] - 1) >> 8);
+ ReadCapacity10_Data[3] = (uint8_t)(Mass_Block_Count[lun] - 1);
+
+ ReadCapacity10_Data[4] = (uint8_t)(Mass_Block_Size[lun] >> 24);
+ ReadCapacity10_Data[5] = (uint8_t)(Mass_Block_Size[lun] >> 16);
+ ReadCapacity10_Data[6] = (uint8_t)(Mass_Block_Size[lun] >> 8);
+ ReadCapacity10_Data[7] = (uint8_t)(Mass_Block_Size[lun]);
+ Transfer_Data_Request(ReadCapacity10_Data, READ_CAPACITY10_DATA_LEN);
+}
+
+/*******************************************************************************
+* Function Name : SCSI_ModeSense6_Cmd
+* Description : SCSI ModeSense6 Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_ModeSense6_Cmd (uint8_t lun)
+{
+ Transfer_Data_Request(Mode_Sense6_data, MODE_SENSE6_DATA_LEN);
+}
+
+/*******************************************************************************
+* Function Name : SCSI_ModeSense10_Cmd
+* Description : SCSI ModeSense10 Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_ModeSense10_Cmd (uint8_t lun)
+{
+ Transfer_Data_Request(Mode_Sense10_data, MODE_SENSE10_DATA_LEN);
+}
+
+/*******************************************************************************
+* Function Name : SCSI_RequestSense_Cmd
+* Description : SCSI RequestSense Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_RequestSense_Cmd (uint8_t lun)
+{
+ uint8_t Request_Sense_data_Length;
+
+ if (CBW.CB[4] <= REQUEST_SENSE_DATA_LEN)
+ {
+ Request_Sense_data_Length = CBW.CB[4];
+ }
+ else
+ {
+ Request_Sense_data_Length = REQUEST_SENSE_DATA_LEN;
+ }
+ Transfer_Data_Request(Scsi_Sense_Data, Request_Sense_data_Length);
+}
+
+/*******************************************************************************
+* Function Name : Set_Scsi_Sense_Data
+* Description : Set Scsi Sense Data routine.
+* Input : uint8_t Sens_Key
+ uint8_t Asc.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void Set_Scsi_Sense_Data(uint8_t lun, uint8_t Sens_Key, uint8_t Asc)
+{
+ Scsi_Sense_Data[2] = Sens_Key;
+ Scsi_Sense_Data[12] = Asc;
+}
+
+/*******************************************************************************
+* Function Name : SCSI_Start_Stop_Unit_Cmd
+* Description : SCSI Start_Stop_Unit Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_Start_Stop_Unit_Cmd(uint8_t lun)
+{
+ Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
+}
+
+/*******************************************************************************
+* Function Name : SCSI_Read10_Cmd
+* Description : SCSI Read10 Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_Read10_Cmd(uint8_t lun , uint32_t LBA , uint32_t BlockNbr)
+{
+ if (Bot_State == BOT_IDLE)
+ {
+ if (!(SCSI_Address_Management(CBW.bLUN, SCSI_READ10, LBA, BlockNbr)))/*address out of range*/
+ {
+ return;
+ }
+
+ if ((CBW.bmFlags & 0x80) != 0)
+ {
+ Bot_State = BOT_DATA_IN;
+ Read_Memory(lun, LBA , BlockNbr);
+ }
+ else
+ {
+ Bot_Abort(BOTH_DIR);
+ Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
+ }
+ return;
+ }
+ else if (Bot_State == BOT_DATA_IN)
+ {
+ Read_Memory(lun , LBA , BlockNbr);
+ }
+}
+
+/*******************************************************************************
+* Function Name : SCSI_Write10_Cmd
+* Description : SCSI Write10 Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_Write10_Cmd(uint8_t lun , uint32_t LBA , uint32_t BlockNbr)
+{
+ if (Bot_State == BOT_IDLE)
+ {
+ if (!(SCSI_Address_Management(CBW.bLUN, SCSI_WRITE10 , LBA, BlockNbr)))/*address out of range*/
+ {
+ return;
+ }
+
+ if ((CBW.bmFlags & 0x80) == 0)
+ {
+ Bot_State = BOT_DATA_OUT;
+ SetEPRxStatus(ENDP2, EP_RX_VALID);
+ }
+ else
+ {
+ Bot_Abort(DIR_IN);
+ Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+ }
+ return;
+ }
+ else if (Bot_State == BOT_DATA_OUT)
+ {
+ Write_Memory(lun , LBA , BlockNbr);
+ }
+}
+
+/*******************************************************************************
+* Function Name : SCSI_Verify10_Cmd
+* Description : SCSI Verify10 Command routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_Verify10_Cmd(uint8_t lun)
+{
+ if ((CBW.dDataLength == 0) && !(CBW.CB[1] & BLKVFY))/* BLKVFY not set*/
+ {
+ Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
+ }
+ else
+ {
+ Bot_Abort(BOTH_DIR);
+ Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+ }
+}
+/*******************************************************************************
+* Function Name : SCSI_Valid_Cmd
+* Description : Valid Commands routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_Valid_Cmd(uint8_t lun)
+{
+ if (CBW.dDataLength != 0)
+ {
+ Bot_Abort(BOTH_DIR);
+ Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_COMMAND);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+ }
+ else
+ Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
+}
+/*******************************************************************************
+* Function Name : SCSI_Valid_Cmd
+* Description : Valid Commands routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_TestUnitReady_Cmd(uint8_t lun)
+{
+ if (MAL_GetStatus(lun))
+ {
+ Set_Scsi_Sense_Data(CBW.bLUN, NOT_READY, MEDIUM_NOT_PRESENT);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
+ Bot_Abort(DIR_IN);
+ return;
+ }
+ else
+ {
+ Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
+ }
+}
+/*******************************************************************************
+* Function Name : SCSI_Format_Cmd
+* Description : Format Commands routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_Format_Cmd(uint8_t lun)
+{
+ if (MAL_GetStatus(lun))
+ {
+ Set_Scsi_Sense_Data(CBW.bLUN, NOT_READY, MEDIUM_NOT_PRESENT);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
+ Bot_Abort(DIR_IN);
+ return;
+ }
+#ifdef USE_STM3210E_EVAL
+ else
+ {
+ NAND_Format();
+ Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
+ }
+#endif
+}
+/*******************************************************************************
+* Function Name : SCSI_Invalid_Cmd
+* Description : Invalid Commands routine
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SCSI_Invalid_Cmd(uint8_t lun)
+{
+ if (CBW.dDataLength == 0)
+ {
+ Bot_Abort(DIR_IN);
+ }
+ else
+ {
+ if ((CBW.bmFlags & 0x80) != 0)
+ {
+ Bot_Abort(DIR_IN);
+ }
+ else
+ {
+ Bot_Abort(BOTH_DIR);
+ }
+ }
+ Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_COMMAND);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+}
+
+/*******************************************************************************
+* Function Name : SCSI_Address_Management
+* Description : Test the received address.
+* Input : uint8_t Cmd : the command can be SCSI_READ10 or SCSI_WRITE10.
+* Output : None.
+* Return : Read\Write status (bool).
+*******************************************************************************/
+bool SCSI_Address_Management(uint8_t lun , uint8_t Cmd , uint32_t LBA , uint32_t BlockNbr)
+{
+ if ((LBA + BlockNbr) > Mass_Block_Count[lun] )
+ {
+ if (Cmd == SCSI_WRITE10)
+ {
+ Bot_Abort(BOTH_DIR);
+ }
+ Bot_Abort(DIR_IN);
+ Set_Scsi_Sense_Data(lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+ return (FALSE);
+ }
+
+ if (CBW.dDataLength != BlockNbr * Mass_Block_Size[lun])
+ {
+ if (Cmd == SCSI_WRITE10)
+ {
+ Bot_Abort(BOTH_DIR);
+ }
+ else
+ {
+ Bot_Abort(DIR_IN);
+ }
+ Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+ Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+ return (FALSE);
+ }
+ return (TRUE);
+}
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/