diff options
Diffstat (limited to 'thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Composite_Example/src')
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>© 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>© 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>© 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>© 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****/ |