Browse Source

add mass_storage for stm32_radio

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@269 bbd45198-f89e-11dd-88c7-29a3b14d5316
wuyangyong 15 years ago
parent
commit
aecf1601d8
55 changed files with 13411 additions and 127 deletions
  1. 99 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/fsmc_nand.h
  2. 48 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/hw_config.h
  3. 36 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/mass_mal.h
  4. 33 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/memory.h
  5. 67 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/nand_if.h
  6. 29 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/platform_config.h
  7. 72 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/stm32f10x_conf.h
  8. 87 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_bot.h
  9. 132 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_conf.h
  10. 49 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_desc.h
  11. 121 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_istr.h
  12. 58 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_prop.h
  13. 58 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_pwr.h
  14. 139 0
      bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_scsi.h
  15. 490 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/fsmc_nand.c
  16. 256 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/hw_config.c
  17. 84 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/mass_mal.c
  18. 168 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/memory.c
  19. 544 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/nand_if.c
  20. 145 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/scsi_data.c
  21. 347 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/usb_bot.c
  22. 161 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/usb_desc.c
  23. 55 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/usb_endp.c
  24. 174 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/usb_istr.c
  25. 39 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/usb_main.c
  26. 402 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/usb_prop.c
  27. 224 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/usb_pwr.c
  28. 433 0
      bsp/stm32_radio/Libraries/Mass_Storage/src/usb_scsi.c
  29. 259 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_cal.h
  30. 121 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_dev.h
  31. 54 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_int.h
  32. 87 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_pcd.h
  33. 1597 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_regs.h
  34. 243 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_core.h
  35. 80 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_def.h
  36. 49 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_init.h
  37. 33 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_int.h
  38. 50 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_lib.h
  39. 32 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_mem.h
  40. 671 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_regs.h
  41. 34 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_sil.h
  42. 74 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_type.h
  43. 1273 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/otgd_fs_cal.c
  44. 385 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/otgd_fs_dev.c
  45. 876 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/otgd_fs_int.c
  46. 445 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/otgd_fs_pcd.c
  47. 1088 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_core.c
  48. 63 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_init.c
  49. 188 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_int.c
  50. 75 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_mem.c
  51. 750 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_regs.c
  52. 126 0
      bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_sil.c
  53. 189 121
      bsp/stm32_radio/project.Uv2
  54. 6 6
      bsp/stm32_radio/sdcard.c
  55. 13 0
      bsp/stm32_radio/stm32f10x_it.c

+ 99 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/fsmc_nand.h

@@ -0,0 +1,99 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : fsmc_nand.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Header for fsmc_nand.c file.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __FSMC_NAND_H
+#define __FSMC_NAND_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct
+{
+  uint8_t Maker_ID;
+  uint8_t Device_ID;
+  uint8_t Third_ID;
+  uint8_t Fourth_ID;
+}NAND_IDTypeDef;
+
+typedef struct 
+{
+  uint16_t Zone;
+  uint16_t Block;
+  uint16_t Page;
+} NAND_ADDRESS;
+
+/* Exported constants --------------------------------------------------------*/
+/* NAND Area definition  for STM3210E-EVAL Board RevD */
+#define CMD_AREA                   (uint32_t)(1<<16)  /* A16 = CLE  high */
+#define ADDR_AREA                  (uint32_t)(1<<17)  /* A17 = ALE high */
+
+#define DATA_AREA                  ((uint32_t)0x00000000) 
+
+/* FSMC NAND memory command */
+#define	NAND_CMD_AREA_A            ((uint8_t)0x00)
+#define	NAND_CMD_AREA_B            ((uint8_t)0x01)
+#define NAND_CMD_AREA_C            ((uint8_t)0x50)
+#define NAND_CMD_AREA_TRUE1        ((uint8_t)0x30)
+
+#define NAND_CMD_WRITE0            ((uint8_t)0x80)
+#define NAND_CMD_WRITE_TRUE1       ((uint8_t)0x10)
+	
+#define NAND_CMD_ERASE0            ((uint8_t)0x60)
+#define NAND_CMD_ERASE1            ((uint8_t)0xD0)  
+
+#define NAND_CMD_READID            ((uint8_t)0x90)	
+#define NAND_CMD_STATUS            ((uint8_t)0x70)
+#define NAND_CMD_LOCK_STATUS       ((uint8_t)0x7A)
+#define NAND_CMD_RESET             ((uint8_t)0xFF)
+
+/* NAND memory status */
+#define NAND_VALID_ADDRESS         ((uint32_t)0x00000100)
+#define NAND_INVALID_ADDRESS       ((uint32_t)0x00000200)
+#define NAND_TIMEOUT_ERROR         ((uint32_t)0x00000400)
+#define NAND_BUSY                  ((uint32_t)0x00000000)
+#define NAND_ERROR                 ((uint32_t)0x00000001)
+#define NAND_READY                 ((uint32_t)0x00000040)
+
+/* FSMC NAND memory parameters */
+#define NAND_PAGE_SIZE             ((uint16_t)0x0200) /* 512 bytes per page w/o Spare Area */
+#define NAND_BLOCK_SIZE            ((uint16_t)0x0020) /* 32x512 bytes pages per block */
+#define NAND_ZONE_SIZE             ((uint16_t)0x0400) /* 1024 Block per zone */
+#define NAND_SPARE_AREA_SIZE       ((uint16_t)0x0010) /* last 16 bytes as spare area */
+#define NAND_MAX_ZONE              ((uint16_t)0x0004) /* 4 zones of 1024 block */
+
+/* FSMC NAND memory address computation */
+#define ADDR_1st_CYCLE(ADDR)       (uint8_t)((ADDR)& 0xFF)               /* 1st addressing cycle */
+#define ADDR_2nd_CYCLE(ADDR)       (uint8_t)(((ADDR)& 0xFF00) >> 8)      /* 2nd addressing cycle */
+#define ADDR_3rd_CYCLE(ADDR)       (uint8_t)(((ADDR)& 0xFF0000) >> 16)   /* 3rd addressing cycle */
+#define ADDR_4th_CYCLE(ADDR)       (uint8_t)(((ADDR)& 0xFF000000) >> 24) /* 4th addressing cycle */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void FSMC_NAND_Init(void);
+void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID);
+uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToWrite);
+uint32_t FSMC_NAND_ReadSmallPage (uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToRead);
+uint32_t FSMC_NAND_WriteSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaTowrite);
+uint32_t FSMC_NAND_ReadSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaToRead);
+uint32_t FSMC_NAND_EraseBlock(NAND_ADDRESS Address);
+uint32_t FSMC_NAND_Reset(void);
+uint32_t FSMC_NAND_GetStatus(void);
+uint32_t FSMC_NAND_ReadStatus(void);
+uint32_t FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address);
+
+#endif /* __FSMC_NAND_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 48 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/hw_config.h

@@ -0,0 +1,48 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : hw_config.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Hardware Configuration & Setup
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __HW_CONFIG_H
+#define __HW_CONFIG_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported define -----------------------------------------------------------*/
+#define BULK_MAX_PACKET_SIZE  0x00000040
+
+/* Exported functions ------------------------------------------------------- */
+void Set_System(void);
+void Set_USBClock(void);
+void Enter_LowPowerMode(void);
+void Leave_LowPowerMode(void);
+void USB_Interrupts_Config(void);
+void Led_Config(void);
+void Led_RW_ON(void);
+void Led_RW_OFF(void);
+void USB_Configured_LED(void);
+void USB_NotConfigured_LED(void);
+void USB_Cable_Config (FunctionalState NewState);
+void Get_SerialNum(void);
+void MAL_Config(void);
+void USB_Disconnect_Config(void);
+/* External variables --------------------------------------------------------*/
+
+#endif  /*__HW_CONFIG_H*/
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 36 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/mass_mal.h

@@ -0,0 +1,36 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : mass_mal.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Header for mass_mal.c file.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MASS_MAL_H
+#define __MASS_MAL_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+#define MAL_OK   0
+#define MAL_FAIL 1
+#define MAX_LUN  1
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+uint16_t MAL_Init (uint8_t lun);
+uint16_t MAL_GetStatus (uint8_t lun);
+uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length);
+uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length);
+#endif /* __MASS_MAL_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 33 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/memory.h

@@ -0,0 +1,33 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : memory.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Memory management layer
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __memory_H
+#define __memory_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+#define TXFR_IDLE     0
+#define TXFR_ONGOING  1
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void Write_Memory (uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length);
+void Read_Memory (uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length);
+#endif /* __memory_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 67 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/nand_if.h

@@ -0,0 +1,67 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : nand_if.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : All functions related to the NAND process
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __NAND_IF_H
+#define __NAND_IF_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+#define NAND_OK   0
+#define NAND_FAIL 1
+
+#define FREE_BLOCK  (1 << 12 )
+#define BAD_BLOCK   (1 << 13 )
+#define VALID_BLOCK (1 << 14 )
+#define USED_BLOCK  (1 << 15 )
+
+#define MAX_PHY_BLOCKS_PER_ZONE  1024
+#define MAX_LOG_BLOCKS_PER_ZONE  1000
+/* Private Structures---------------------------------------------------------*/
+typedef struct __SPARE_AREA {
+	uint16_t LogicalIndex;
+	uint16_t DataStatus;
+	uint16_t BlockStatus;
+} SPARE_AREA;	
+
+typedef enum {
+  WRITE_IDLE = 0,
+  POST_WRITE,
+  PRE_WRITE,
+  WRITE_CLEANUP,
+  WRITE_ONGOING  
+}WRITE_STATE;  
+
+typedef enum {
+  OLD_BLOCK = 0,
+  UNUSED_BLOCK
+}BLOCK_STATE; 
+
+/* Private macro --------------------------------------------------------------*/
+//#define WEAR_LEVELLING_SUPPORT
+#define WEAR_DEPTH         10
+#define PAGE_TO_WRITE      (Transfer_Length/512)
+/* Private variables ----------------------------------------------------------*/
+/* Private function prototypes ------------------------------------------------*/
+/* exported functions ---------------------------------------------------------*/
+uint16_t NAND_Init (void);
+uint16_t NAND_Write (uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length);
+uint16_t NAND_Read  (uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length);
+uint16_t NAND_Format (void);
+SPARE_AREA ReadSpareArea (uint32_t address);
+#endif
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 29 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/platform_config.h

@@ -0,0 +1,29 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : platform_config.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Evaluation board specific configuration file.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __PLATFORM_CONFIG_H
+#define __PLATFORM_CONFIG_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+
+#define USB_DISCONNECT                    GPIOA
+#define USB_DISCONNECT_PIN                GPIO_Pin_3
+#define RCC_APB2Periph_GPIO_DISCONNECT    RCC_APB2Periph_GPIOA
+
+#endif /* __PLATFORM_CONFIG_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 72 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/stm32f10x_conf.h

@@ -0,0 +1,72 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : stm32f10x_conf.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Library configuration file.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F10x_CONF_H
+#define __STM32F10x_CONF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Uncomment the line below to enable peripheral header file inclusion */
+/* #include "stm32f10x_adc.h" */
+/* #include "stm32f10x_bkp.h" */
+/* #include "stm32f10x_can.h" */
+/* #include "stm32f10x_crc.h" */
+/* #include "stm32f10x_dac.h" */
+/* #include "stm32f10x_dbgmcu.h" */
+#include "stm32f10x_dma.h"
+#include "stm32f10x_exti.h"
+#include "stm32f10x_flash.h"
+#include "stm32f10x_fsmc.h"
+#include "stm32f10x_gpio.h"
+/* #include "stm32f10x_i2c.h" */
+/* #include "stm32f10x_iwdg.h" */
+/* #include "stm32f10x_pwr.h" */
+#include "stm32f10x_rcc.h"
+/* #include "stm32f10x_rtc.h" */
+#include "stm32f10x_sdio.h"
+#include "stm32f10x_spi.h"
+/* #include "stm32f10x_tim.h" */
+#include "stm32f10x_usart.h" 
+/* #include "stm32f10x_wwdg.h" */
+#include "misc.h"   /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Uncomment the line below to expanse the "assert_param" macro in the 
+   Standard Peripheral Library drivers code */
+/* #define USE_FULL_ASSERT    1 */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef  USE_FULL_ASSERT
+
+/*******************************************************************************
+* Macro Name     : assert_param
+* Description    : The assert_param macro is used for function's parameters check.
+* Input          : - expr: If expr is false, it calls assert_failed function
+*                    which reports the name of the source file and the source
+*                    line number of the call that failed. 
+*                    If expr is true, it returns no value.
+* Return         : None
+*******************************************************************************/ 
+  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+  void assert_failed(uint8_t* file, uint32_t line);
+#else
+  #define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+#endif /* __STM32F10x_CONF_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 87 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_bot.h

@@ -0,0 +1,87 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_bot.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : BOT State Machine management
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_BOT_H
+#define __USB_BOT_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Bulk-only Command Block Wrapper */
+
+typedef struct _Bulk_Only_CBW
+{
+  uint32_t dSignature;
+  uint32_t dTag;
+  uint32_t dDataLength;
+  uint8_t  bmFlags;
+  uint8_t  bLUN;
+  uint8_t  bCBLength;
+  uint8_t  CB[16];
+}
+Bulk_Only_CBW;
+
+/* Bulk-only Command Status Wrapper */
+typedef struct _Bulk_Only_CSW
+{
+  uint32_t dSignature;
+  uint32_t dTag;
+  uint32_t dDataResidue;
+  uint8_t  bStatus;
+}
+Bulk_Only_CSW;
+/* Exported constants --------------------------------------------------------*/
+
+/*****************************************************************************/
+/*********************** Bulk-Only Transfer State machine ********************/
+/*****************************************************************************/
+#define BOT_IDLE                      0       /* Idle state */
+#define BOT_DATA_OUT                  1       /* Data Out state */
+#define BOT_DATA_IN                   2       /* Data In state */
+#define BOT_DATA_IN_LAST              3       /* Last Data In Last */
+#define BOT_CSW_Send                  4       /* Command Status Wrapper */
+#define BOT_ERROR                     5       /* error state */
+
+#define BOT_CBW_SIGNATURE             0x43425355
+#define BOT_CSW_SIGNATURE             0x53425355
+#define BOT_CBW_PACKET_LENGTH         31
+
+#define CSW_DATA_LENGTH               0x000D
+
+/* CSW Status Definitions */
+#define CSW_CMD_PASSED                0x00
+#define CSW_CMD_FAILED                0x01
+#define CSW_PHASE_ERROR               0x02
+
+#define SEND_CSW_DISABLE              0
+#define SEND_CSW_ENABLE               1
+
+#define DIR_IN                        0
+#define DIR_OUT                       1
+#define BOTH_DIR                      2
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void Mass_Storage_In (void);
+void Mass_Storage_Out (void);
+void CBW_Decode(void);
+void Transfer_Data_Request(uint8_t* Data_Pointer, uint16_t Data_Len);
+void Set_CSW (uint8_t CSW_Status, uint8_t Send_Permission);
+void Bot_Abort(uint8_t Direction);
+
+#endif /* __USB_BOT_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 132 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_conf.h

@@ -0,0 +1,132 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_conf.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Mass Storage Demo configuration header
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CONF_H
+#define __USB_CONF_H
+
+/*-------------------------------------------------------------*/
+/* EP_NUM */
+/* defines how many endpoints are used by the device */
+/*-------------------------------------------------------------*/
+#define EP_NUM                          (3)
+
+#ifndef STM32F10X_CL
+/*-------------------------------------------------------------*/
+/* --------------   Buffer Description Table  -----------------*/
+/*-------------------------------------------------------------*/
+/* buffer table base address */
+
+#define BTABLE_ADDRESS      (0x00)
+
+/* EP0  */
+/* rx/tx buffer base address */
+#define ENDP0_RXADDR        (0x18)
+#define ENDP0_TXADDR        (0x58)
+
+/* EP1  */
+/* tx buffer base address */
+#define ENDP1_TXADDR        (0x98)
+
+/* EP2  */
+/* Rx buffer base address */
+#define ENDP2_RXADDR        (0xD8)
+
+
+/* ISTR events */
+/* IMR_MSK */
+/* mask defining which events has to be handled */
+/* by the device application software */
+#define IMR_MSK (CNTR_CTRM  | CNTR_RESETM)
+#endif /* STM32F10X_CL */
+
+/* CTR service routines */
+/* associated to defined endpoints */
+//#define  EP1_IN_Callback   NOP_Process
+#define  EP2_IN_Callback   NOP_Process
+#define  EP3_IN_Callback   NOP_Process
+#define  EP4_IN_Callback   NOP_Process
+#define  EP5_IN_Callback   NOP_Process
+#define  EP6_IN_Callback   NOP_Process
+#define  EP7_IN_Callback   NOP_Process
+
+
+#define  EP1_OUT_Callback   NOP_Process
+//#define  EP2_OUT_Callback   NOP_Process
+#define  EP3_OUT_Callback  NOP_Process
+#define  EP4_OUT_Callback   NOP_Process
+#define  EP5_OUT_Callback   NOP_Process
+#define  EP6_OUT_Callback   NOP_Process
+#define  EP7_OUT_Callback   NOP_Process
+
+#ifdef STM32F10X_CL
+
+/* OTGD-FS-DEVICE IP interrupts Enable definitions */
+/* Uncomment the define to enable the selected interrupt */
+//#define INTR_MODEMISMATCH
+#define INTR_SOFINTR
+#define INTR_RXSTSQLVL           /* Mandatory */
+//#define INTR_NPTXFEMPTY
+//#define INTR_GINNAKEFF
+//#define INTR_GOUTNAKEFF
+//#define INTR_ERLYSUSPEND
+#define INTR_USBSUSPEND          /* Mandatory */
+#define INTR_USBRESET            /* Mandatory */
+#define INTR_ENUMDONE            /* Mandatory */
+//#define INTR_ISOOUTDROP
+#define INTR_EOPFRAME
+//#define INTR_EPMISMATCH
+#define INTR_INEPINTR            /* Mandatory */
+#define INTR_OUTEPINTR           /* Mandatory */
+//#define INTR_INCOMPLISOIN
+//#define INTR_INCOMPLISOOUT
+#define INTR_WKUPINTR            /* Mandatory */
+
+/* OTGD-FS-DEVICE IP interrupts subroutines */
+/* Comment the define to enable the selected interrupt subroutine and replace it
+   by user code */
+#define  INTR_MODEMISMATCH_Callback      NOP_Process
+#define  INTR_SOFINTR_Callback           NOP_Process
+#define  INTR_RXSTSQLVL_Callback         NOP_Process
+#define  INTR_NPTXFEMPTY_Callback        NOP_Process
+#define  INTR_NPTXFEMPTY_Callback        NOP_Process
+#define  INTR_GINNAKEFF_Callback         NOP_Process
+#define  INTR_GOUTNAKEFF_Callback        NOP_Process
+#define  INTR_ERLYSUSPEND_Callback       NOP_Process
+#define  INTR_USBSUSPEND_Callback        NOP_Process
+#define  INTR_USBRESET_Callback          NOP_Process
+#define  INTR_ENUMDONE_Callback          NOP_Process
+#define  INTR_ISOOUTDROP_Callback        NOP_Process
+#define  INTR_EOPFRAME_Callback          NOP_Process
+#define  INTR_EPMISMATCH_Callback        NOP_Process
+#define  INTR_INEPINTR_Callback          NOP_Process
+#define  INTR_OUTEPINTR_Callback         NOP_Process
+#define  INTR_INCOMPLISOIN_Callback      NOP_Process
+#define  INTR_INCOMPLISOOUT_Callback     NOP_Process
+#define  INTR_WKUPINTR_Callback          NOP_Process
+
+/* Isochronous data update */
+#define  INTR_RXSTSQLVL_ISODU_Callback   NOP_Process  
+
+/* Isochronous transfer parameters */
+/* Size of a single Isochronous buffer (size of a single transfer) */
+#define ISOC_BUFFER_SZE                  1
+/* Number of sub-buffers (number of single buffers/transfers), should be even */
+#define NUM_SUB_BUFFERS                  2
+
+#endif /* STM32F10X_CL */
+
+#endif /* __USB_CONF_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 49 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_desc.h

@@ -0,0 +1,49 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_desc.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Descriptor Header for Mass Storage Device
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DESC_H
+#define __USB_DESC_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported define -----------------------------------------------------------*/
+#define MASS_SIZ_DEVICE_DESC              18
+#define MASS_SIZ_CONFIG_DESC              32
+
+#define MASS_SIZ_STRING_LANGID            4
+#define MASS_SIZ_STRING_VENDOR            38
+#define MASS_SIZ_STRING_PRODUCT           38
+#define MASS_SIZ_STRING_SERIAL            26
+#define MASS_SIZ_STRING_INTERFACE         16
+
+/* Exported functions ------------------------------------------------------- */
+extern const uint8_t MASS_DeviceDescriptor[MASS_SIZ_DEVICE_DESC];
+extern const uint8_t MASS_ConfigDescriptor[MASS_SIZ_CONFIG_DESC];
+
+extern const uint8_t MASS_StringLangID[MASS_SIZ_STRING_LANGID];
+extern const uint8_t MASS_StringVendor[MASS_SIZ_STRING_VENDOR];
+extern const uint8_t MASS_StringProduct[MASS_SIZ_STRING_PRODUCT];
+extern uint8_t MASS_StringSerial[MASS_SIZ_STRING_SERIAL];
+extern const uint8_t MASS_StringInterface[MASS_SIZ_STRING_INTERFACE];
+
+#endif /* __USB_DESC_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+
+

+ 121 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_istr.h

@@ -0,0 +1,121 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_istr.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : This file includes the peripherals header files in the
+*                      user application.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_ISTR_H
+#define __USB_ISTR_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#ifndef STM32F10X_CL
+ void USB_Istr(void);
+#else /* STM32F10X_CL */
+ u32 STM32_PCD_OTG_ISR_Handler(void);
+#endif /* STM32F10X_CL */
+
+/* function prototypes Automatically built defining related macros */
+
+void EP1_IN_Callback(void);
+void EP2_IN_Callback(void);
+void EP3_IN_Callback(void);
+void EP4_IN_Callback(void);
+void EP5_IN_Callback(void);
+void EP6_IN_Callback(void);
+void EP7_IN_Callback(void);
+
+void EP1_OUT_Callback(void);
+void EP2_OUT_Callback(void);
+void EP3_OUT_Callback(void);
+void EP4_OUT_Callback(void);
+void EP5_OUT_Callback(void);
+void EP6_OUT_Callback(void);
+void EP7_OUT_Callback(void);
+
+#ifndef STM32F10X_CL
+
+#ifdef CTR_CALLBACK
+void CTR_Callback(void);
+#endif
+
+#ifdef DOVR_CALLBACK
+void DOVR_Callback(void);
+#endif
+
+#ifdef ERR_CALLBACK
+void ERR_Callback(void);
+#endif
+
+#ifdef WKUP_CALLBACK
+void WKUP_Callback(void);
+#endif
+
+#ifdef SUSP_CALLBACK
+void SUSP_Callback(void);
+#endif
+
+#ifdef RESET_CALLBACK
+void RESET_Callback(void);
+#endif
+
+#ifdef SOF_CALLBACK
+void SOF_Callback(void);
+#endif
+
+#ifdef ESOF_CALLBACK
+void ESOF_Callback(void);
+#endif
+
+#else /* STM32F10X_CL */
+
+/* Interrupt subroutines user callbacks prototypes.
+   These callbacks are called into the respective interrupt sunroutine functinos
+   and can be tailored for various user application purposes.
+     Note: Make sure that the correspondant interrupt is enabled through the 
+     definition in usb_conf.h file */ 
+void INTR_MODEMISMATCH_Callback(void);
+void INTR_SOFINTR_Callback(void);
+void INTR_RXSTSQLVL_Callback(void);
+void INTR_NPTXFEMPTY_Callback(void);
+void INTR_GINNAKEFF_Callback(void);
+void INTR_GOUTNAKEFF_Callback(void);
+void INTR_ERLYSUSPEND_Callback(void);
+void INTR_USBSUSPEND_Callback(void);
+void INTR_USBRESET_Callback(void);
+void INTR_ENUMDONE_Callback(void);
+void INTR_ISOOUTDROP_Callback(void);
+void INTR_EOPFRAME_Callback(void);
+void INTR_EPMISMATCH_Callback(void);
+void INTR_INEPINTR_Callback(void);
+void INTR_OUTEPINTR_Callback(void);
+void INTR_INCOMPLISOIN_Callback(void);
+void INTR_INCOMPLISOOUT_Callback(void);
+void INTR_WKUPINTR_Callback(void);
+
+/* Isochronous data update */
+void INTR_RXSTSQLVL_ISODU_Callback(void); 
+
+#endif /* STM32F10X_CL */
+
+
+#endif /*__USB_ISTR_H*/
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 58 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_prop.h

@@ -0,0 +1,58 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_prop.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : All processing related to Mass Storage Demo (Endpoint 0)
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __usb_prop_H
+#define __usb_prop_H
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+
+/* Exported constants --------------------------------------------------------*/
+#define Mass_Storage_GetConfiguration          NOP_Process
+/* #define Mass_Storage_SetConfiguration          NOP_Process*/
+#define Mass_Storage_GetInterface              NOP_Process
+#define Mass_Storage_SetInterface              NOP_Process
+#define Mass_Storage_GetStatus                 NOP_Process
+/* #define Mass_Storage_ClearFeature              NOP_Process*/
+#define Mass_Storage_SetEndPointFeature        NOP_Process
+#define Mass_Storage_SetDeviceFeature          NOP_Process
+/*#define Mass_Storage_SetDeviceAddress          NOP_Process*/
+
+/* MASS Storage Requests*/
+#define GET_MAX_LUN                0xFE
+#define MASS_STORAGE_RESET         0xFF
+#define LUN_DATA_LENGTH            1
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void MASS_init(void);
+void MASS_Reset(void);
+void Mass_Storage_SetConfiguration(void);
+void Mass_Storage_ClearFeature(void);
+void Mass_Storage_SetDeviceAddress (void);
+void MASS_Status_In (void);
+void MASS_Status_Out (void);
+RESULT MASS_Data_Setup(uint8_t);
+RESULT MASS_NoData_Setup(uint8_t);
+RESULT MASS_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting);
+uint8_t *MASS_GetDeviceDescriptor(uint16_t );
+uint8_t *MASS_GetConfigDescriptor(uint16_t);
+uint8_t *MASS_GetStringDescriptor(uint16_t);
+uint8_t *Get_Max_Lun(uint16_t Length);
+
+#endif /* __usb_prop_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 58 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_pwr.h

@@ -0,0 +1,58 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_pwr.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Connection/disconnection & power management header
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_PWR_H
+#define __USB_PWR_H
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+/* Exported types ------------------------------------------------------------*/
+typedef enum _RESUME_STATE
+{
+  RESUME_EXTERNAL,
+  RESUME_INTERNAL,
+  RESUME_LATER,
+  RESUME_WAIT,
+  RESUME_START,
+  RESUME_ON,
+  RESUME_OFF,
+  RESUME_ESOF
+} RESUME_STATE;
+
+typedef enum _DEVICE_STATE
+{
+  UNCONNECTED,
+  ATTACHED,
+  POWERED,
+  SUSPENDED,
+  ADDRESSED,
+  CONFIGURED
+} DEVICE_STATE;
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void Suspend(void);
+void Resume_Init(void);
+void Resume(RESUME_STATE eResumeSetVal);
+RESULT PowerOn(void);
+RESULT PowerOff(void);
+
+/* External variables --------------------------------------------------------*/
+extern  __IO uint32_t bDeviceState; /* USB device status */
+extern __IO bool fSuspendEnabled;  /* true when suspend is possible */
+
+#endif  /*__USB_PWR_H*/
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 139 - 0
bsp/stm32_radio/Libraries/Mass_Storage/inc/usb_scsi.h

@@ -0,0 +1,139 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_scsi.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : All processing related to the SCSI commands
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_SCSI_H
+#define __USB_SCSI_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* SCSI Commands */
+#define SCSI_FORMAT_UNIT                            0x04
+#define SCSI_INQUIRY                                0x12
+#define SCSI_MODE_SELECT6                           0x15
+#define SCSI_MODE_SELECT10                          0x55
+#define SCSI_MODE_SENSE6                            0x1A
+#define SCSI_MODE_SENSE10                           0x5A
+#define SCSI_ALLOW_MEDIUM_REMOVAL                   0x1E
+#define SCSI_READ6                                  0x08
+#define SCSI_READ10                                 0x28
+#define SCSI_READ12                                 0xA8
+#define SCSI_READ16                                 0x88
+
+#define SCSI_READ_CAPACITY10                        0x25
+#define SCSI_READ_CAPACITY16                        0x9E
+
+#define SCSI_REQUEST_SENSE                          0x03
+#define SCSI_START_STOP_UNIT                        0x1B
+#define SCSI_TEST_UNIT_READY                        0x00
+#define SCSI_WRITE6                                 0x0A
+#define SCSI_WRITE10                                0x2A
+#define SCSI_WRITE12                                0xAA
+#define SCSI_WRITE16                                0x8A
+
+#define SCSI_VERIFY10                               0x2F
+#define SCSI_VERIFY12                               0xAF
+#define SCSI_VERIFY16                               0x8F
+
+#define SCSI_SEND_DIAGNOSTIC                        0x1D
+#define SCSI_READ_FORMAT_CAPACITIES                 0x23
+
+#define NO_SENSE		                    0
+#define RECOVERED_ERROR		                    1
+#define NOT_READY		                    2
+#define MEDIUM_ERROR		                    3
+#define HARDWARE_ERROR		                    4
+#define ILLEGAL_REQUEST		                    5
+#define UNIT_ATTENTION		                    6
+#define DATA_PROTECT		                    7
+#define BLANK_CHECK		                    8
+#define VENDOR_SPECIFIC		                    9
+#define COPY_ABORTED		                    10
+#define ABORTED_COMMAND		                    11
+#define VOLUME_OVERFLOW		                    13
+#define MISCOMPARE		                    14
+
+
+#define INVALID_COMMAND                             0x20
+#define INVALID_FIELED_IN_COMMAND                   0x24
+#define PARAMETER_LIST_LENGTH_ERROR                 0x1A
+#define INVALID_FIELD_IN_PARAMETER_LIST             0x26
+#define ADDRESS_OUT_OF_RANGE                        0x21
+#define MEDIUM_NOT_PRESENT 			    0x3A
+#define MEDIUM_HAVE_CHANGED			    0x28
+
+#define READ_FORMAT_CAPACITY_DATA_LEN               0x0C
+#define READ_CAPACITY10_DATA_LEN                    0x08
+#define MODE_SENSE10_DATA_LEN                       0x08
+#define MODE_SENSE6_DATA_LEN                        0x04
+#define REQUEST_SENSE_DATA_LEN                      0x12
+#define STANDARD_INQUIRY_DATA_LEN                   0x24
+#define BLKVFY                                      0x04
+
+extern  uint8_t Page00_Inquiry_Data[];
+extern  uint8_t Standard_Inquiry_Data[];
+extern  uint8_t Standard_Inquiry_Data2[];
+extern  uint8_t Mode_Sense6_data[];
+extern  uint8_t Mode_Sense10_data[];
+extern  uint8_t Scsi_Sense_Data[];
+extern  uint8_t ReadCapacity10_Data[];
+extern  uint8_t ReadFormatCapacity_Data [];
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void SCSI_Inquiry_Cmd(uint8_t lun);
+void SCSI_ReadFormatCapacity_Cmd(uint8_t lun);
+void SCSI_ReadCapacity10_Cmd(uint8_t lun);
+void SCSI_RequestSense_Cmd (uint8_t lun);
+void SCSI_Start_Stop_Unit_Cmd(uint8_t lun);
+void SCSI_ModeSense6_Cmd (uint8_t lun);
+void SCSI_ModeSense10_Cmd (uint8_t lun);
+void SCSI_Write10_Cmd(uint8_t lun , uint32_t LBA , uint32_t BlockNbr);
+void SCSI_Read10_Cmd(uint8_t lun , uint32_t LBA , uint32_t BlockNbr);
+void SCSI_Verify10_Cmd(uint8_t lun);
+
+void SCSI_Invalid_Cmd(uint8_t lun);
+void SCSI_Valid_Cmd(uint8_t lun);
+bool SCSI_Address_Management(uint8_t lun , uint8_t Cmd , uint32_t LBA , uint32_t BlockNbr);
+
+void Set_Scsi_Sense_Data(uint8_t lun , uint8_t Sens_Key, uint8_t Asc);
+void SCSI_TestUnitReady_Cmd (uint8_t lun);
+void SCSI_Format_Cmd (uint8_t lun);
+
+//#define SCSI_TestUnitReady_Cmd           SCSI_Valid_Cmd
+#define SCSI_Prevent_Removal_Cmd         SCSI_Valid_Cmd
+
+/* Invalid (Unsupported) commands */
+#define SCSI_READ_CAPACITY16_Cmd         SCSI_Invalid_Cmd
+//#define SCSI_FormatUnit_Cmd              SCSI_Invalid_Cmd
+#define SCSI_Write6_Cmd                  SCSI_Invalid_Cmd
+#define SCSI_Write16_Cmd                 SCSI_Invalid_Cmd
+#define SCSI_Write12_Cmd                 SCSI_Invalid_Cmd
+#define SCSI_Read6_Cmd                   SCSI_Invalid_Cmd
+#define SCSI_Read12_Cmd                  SCSI_Invalid_Cmd
+#define SCSI_Read16_Cmd                  SCSI_Invalid_Cmd
+#define SCSI_Send_Diagnostic_Cmd         SCSI_Invalid_Cmd
+#define SCSI_Mode_Select6_Cmd            SCSI_Invalid_Cmd
+#define SCSI_Mode_Select10_Cmd           SCSI_Invalid_Cmd
+#define SCSI_Verify12_Cmd                SCSI_Invalid_Cmd
+#define SCSI_Verify16_Cmd                SCSI_Invalid_Cmd
+
+#endif /* __USB_SCSI_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 490 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/fsmc_nand.c

@@ -0,0 +1,490 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : fsmc_nand.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : This file provides a set of functions needed to drive the
+*                      NAND512W3A2 memory mounted on STM3210E-EVAL board.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+/* Includes ------------------------------------------------------------------*/
+#include "fsmc_nand.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+#define FSMC_Bank_NAND     FSMC_Bank2_NAND
+#define Bank_NAND_ADDR     Bank2_NAND_ADDR 
+#define Bank2_NAND_ADDR    ((uint32_t)0x70000000)
+
+/* Private macro -------------------------------------------------------------*/
+#define ROW_ADDRESS (Address.Page + (Address.Block + (Address.Zone * NAND_ZONE_SIZE)) * NAND_BLOCK_SIZE)
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+* Function Name  : FSMC_NAND_Init
+* Description    : Configures the FSMC and GPIOs to interface with the NAND memory.
+*                  This function must be called before any write/read operation
+*                  on the NAND.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void FSMC_NAND_Init(void)
+{
+  GPIO_InitTypeDef GPIO_InitStructure; 
+  FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
+  FSMC_NAND_PCCARDTimingInitTypeDef  p;
+  
+  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | 
+                         RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
+  
+/*-- GPIO Configuration ------------------------------------------------------*/
+/* CLE, ALE, D0->D3, NOE, NWE and NCE2  NAND pin configuration  */
+  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 |  
+                                 GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | 
+                                 GPIO_Pin_7;                                  
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+
+  GPIO_Init(GPIOD, &GPIO_InitStructure); 
+
+/* D4->D7 NAND pin configuration  */  
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
+
+  GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+
+/* NWAIT NAND pin configuration */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;   							 
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+
+  GPIO_Init(GPIOD, &GPIO_InitStructure); 
+
+/* INT2 NAND pin configuration */  
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;   							 
+  GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+  /*-- FSMC Configuration ------------------------------------------------------*/
+  p.FSMC_SetupTime = 0x1;
+  p.FSMC_WaitSetupTime = 0x3;
+  p.FSMC_HoldSetupTime = 0x2;
+  p.FSMC_HiZSetupTime = 0x1;
+
+  FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
+  FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
+  FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
+  FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;
+  FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;
+  FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
+  FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
+  FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
+  FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
+
+  FSMC_NANDInit(&FSMC_NANDInitStructure);
+
+  /* FSMC NAND Bank Cmd Test */
+  FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_ReadID
+* Description    : Reads NAND memory's ID.
+* Input          : - NAND_ID: pointer to a NAND_IDTypeDef structure which will hold
+*                    the Manufacturer and Device ID.
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID)
+{
+  uint32_t data = 0;
+
+  /* Send Command to the command area */ 	
+  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = 0x90;
+  *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
+
+   /* Sequence to read ID from NAND flash */	
+   data = *(__IO uint32_t *)(Bank_NAND_ADDR | DATA_AREA);
+
+   NAND_ID->Maker_ID   = ADDR_1st_CYCLE (data);
+   NAND_ID->Device_ID  = ADDR_2nd_CYCLE (data);
+   NAND_ID->Third_ID   = ADDR_3rd_CYCLE (data);
+   NAND_ID->Fourth_ID  = ADDR_4th_CYCLE (data);  
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_WriteSmallPage
+* Description    : This routine is for writing one or several 512 Bytes Page size.
+* Input          : - pBuffer: pointer on the Buffer containing data to be written   
+*                  - Address: First page address
+*                  - NumPageToWrite: Number of page to write  
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*                  And the new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToWrite)
+{
+  uint32_t index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
+  uint32_t status = NAND_READY, size = 0x00;
+
+  while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
+  {
+    /* Page write command and address */
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
+
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;  
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);  
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);  
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);  
+
+    /* Calculate the size */
+    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);
+
+    /* Write data */
+    for(; index < size; index++)
+    {
+      *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
+    }
+    
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
+
+    /* Check status for successful operation */
+    status = FSMC_NAND_GetStatus();
+    
+    if(status == NAND_READY)
+    {
+      numpagewritten++;
+
+      NumPageToWrite--;
+
+      /* Calculate Next small page Address */
+      addressstatus = FSMC_NAND_AddressIncrement(&Address);    
+    }    
+  }
+  
+  return (status | addressstatus);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_ReadSmallPage
+* Description    : This routine is for sequential read from one or several 
+*                  512 Bytes Page size.
+* Input          : - pBuffer: pointer on the Buffer to fill  
+*                  - Address: First page address
+*                  - NumPageToRead: Number of page to read
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*                  And the new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+uint32_t FSMC_NAND_ReadSmallPage(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToRead)
+{
+  uint32_t index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;
+  uint32_t status = NAND_READY, size = 0x00;
+
+  while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
+  {	   
+    /* Page Read command and page address */
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A; 
+   
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00; 
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS); 
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS); 
+    
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1; 
+
+    /* Calculate the size */
+    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
+    
+    /* Get Data into Buffer */    
+    for(; index < size; index++)
+    {
+      pBuffer[index]= *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
+    }
+
+    numpageread++;
+    
+    NumPageToRead--;
+
+    /* Calculate page address */           			 
+    addressstatus = FSMC_NAND_AddressIncrement(&Address);
+  }
+
+  status = FSMC_NAND_GetStatus();
+  
+  return (status | addressstatus);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_WriteSpareArea
+* Description    : This routine write the spare area information for the specified 
+*                  pages addresses.
+* Input          : - pBuffer: pointer on the Buffer containing data to be written 
+*                  - Address: First page address
+*                  - NumSpareAreaTowrite: Number of Spare Area to write
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*                  And the new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+uint32_t FSMC_NAND_WriteSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaTowrite)
+{
+  uint32_t index = 0x00, numsparesreawritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
+  uint32_t status = NAND_READY, size = 0x00; 
+
+  while((NumSpareAreaTowrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
+  {
+    /* Page write Spare area command and address */
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_C;
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
+
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00; 
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS); 
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS); 
+
+    /* Calculate the size */ 
+    size = NAND_SPARE_AREA_SIZE + (NAND_SPARE_AREA_SIZE * numsparesreawritten);
+
+    /* Write the data */ 
+    for(; index < size; index++)
+    {
+      *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
+    }
+    
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
+
+    /* Check status for successful operation */
+    status = FSMC_NAND_GetStatus();
+
+    if(status == NAND_READY)
+    {
+      numsparesreawritten++;      
+
+      NumSpareAreaTowrite--;  
+    
+      /* Calculate Next page Address */
+      addressstatus = FSMC_NAND_AddressIncrement(&Address);
+    }       
+  }
+  
+  return (status | addressstatus);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_ReadSpareArea
+* Description    : This routine read the spare area information from the specified
+*                  pages addresses.
+* Input          : - pBuffer: pointer on the Buffer to fill  
+*                  - Address: First page address
+*                  - NumSpareAreaToRead: Number of Spare Area to read
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*                  And the new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+uint32_t FSMC_NAND_ReadSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaToRead)
+{
+  uint32_t numsparearearead = 0x00, index = 0x00, addressstatus = NAND_VALID_ADDRESS;
+  uint32_t status = NAND_READY, size = 0x00;
+
+  while((NumSpareAreaToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
+  {     
+    /* Page Read command and page address */     
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_C;
+
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00; 
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);     
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);     
+    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);    
+
+    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;
+
+    /* Data Read */
+    size = NAND_SPARE_AREA_SIZE +  (NAND_SPARE_AREA_SIZE * numsparearearead);
+	
+    /* Get Data into Buffer */
+    for ( ;index < size; index++)
+    {
+      pBuffer[index] = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
+    }
+    
+    numsparearearead++;
+    
+    NumSpareAreaToRead--;
+
+    /* Calculate page address */           			 
+    addressstatus = FSMC_NAND_AddressIncrement(&Address);
+  }
+
+  status = FSMC_NAND_GetStatus();
+
+  return (status | addressstatus);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_EraseBlock
+* Description    : This routine erase complete block from NAND FLASH
+* Input          : - Address: Any address into block to be erased
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*******************************************************************************/
+uint32_t FSMC_NAND_EraseBlock(NAND_ADDRESS Address)
+{
+  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;
+
+  *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
+  *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
+  *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
+		
+  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1; 
+
+  return (FSMC_NAND_GetStatus());
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_Reset
+* Description    : This routine reset the NAND FLASH
+* Input          : None
+* Output         : None
+* Return         : NAND_READY
+*******************************************************************************/
+uint32_t FSMC_NAND_Reset(void)
+{
+  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_RESET;
+
+  return (NAND_READY);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_GetStatus
+* Description    : Get the NAND operation status
+* Input          : None
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation    
+*******************************************************************************/
+uint32_t FSMC_NAND_GetStatus(void)
+{
+  uint32_t timeout = 0x1000000, status = NAND_READY;
+
+  status = FSMC_NAND_ReadStatus(); 
+
+  /* Wait for a NAND operation to complete or a TIMEOUT to occur */
+  while ((status != NAND_READY) &&( timeout != 0x00))
+  {
+     status = FSMC_NAND_ReadStatus();
+     timeout --;      
+  }
+
+  if(timeout == 0x00)
+  {          
+    status =  NAND_TIMEOUT_ERROR;      
+  } 
+
+  /* Return the operation status */
+  return (status);      
+}
+/******************************************************************************
+* Function Name  : FSMC_NAND_ReadStatus
+* Description    : Reads the NAND memory status using the Read status command 
+* Input          : None
+* Output         : None
+* Return         : The status of the NAND memory. This parameter can be:
+*                   - NAND_BUSY: when memory is busy
+*                   - NAND_READY: when memory is ready for the next operation    
+*                   - NAND_ERROR: when the previous operation gererates error   
+*******************************************************************************/
+uint32_t FSMC_NAND_ReadStatus(void)
+{
+  uint32_t data = 0x00, status = NAND_BUSY;
+
+  /* Read status operation ------------------------------------ */
+  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;
+  data = *(__IO uint8_t *)(Bank_NAND_ADDR);
+
+  if((data & NAND_ERROR) == NAND_ERROR)
+  {
+    status = NAND_ERROR;
+  } 
+  else if((data & NAND_READY) == NAND_READY)
+  {
+    status = NAND_READY;
+  }
+  else
+  {
+    status = NAND_BUSY; 
+  }
+  
+  return (status);
+}
+
+/******************************************************************************
+* Function Name  : NAND_AddressIncrement
+* Description    : Increment the NAND memory address
+* Input          : - Address: address to be incremented.
+* Output         : None
+* Return         : The new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+uint32_t FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address)
+{
+  uint32_t status = NAND_VALID_ADDRESS;
+ 
+  Address->Page++;
+
+  if(Address->Page == NAND_BLOCK_SIZE)
+  {
+    Address->Page = 0;
+    Address->Block++;
+    
+    if(Address->Block == NAND_ZONE_SIZE)
+    {
+      Address->Block = 0;
+      Address->Zone++;
+
+      if(Address->Zone == NAND_MAX_ZONE)
+      {
+        status = NAND_INVALID_ADDRESS;
+      }
+    }
+  } 
+  
+  return (status);
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 256 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/hw_config.c

@@ -0,0 +1,256 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : hw_config.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : Hardware Configuration & Setup
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "hw_config.h"
+#include "platform_config.h"
+#include "mass_mal.h"
+#include "usb_desc.h"
+#include "usb_pwr.h"
+
+void Set_System(void)
+{
+    /* Enable and GPIOD clock */
+    USB_Disconnect_Config();
+
+    /* MAL configuration */
+    MAL_Config();
+}
+
+/*******************************************************************************
+* Function Name  : Set_USBClock
+* Description    : Configures USB Clock input (48MHz)
+* Input          : None.
+* Return         : None.
+*******************************************************************************/
+void Set_USBClock(void)
+{
+    /* USBCLK = PLLCLK */
+    RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
+
+    /* Enable USB clock */
+    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
+}
+
+/*******************************************************************************
+* Function Name  : Enter_LowPowerMode
+* Description    : Power-off system clocks and power while entering suspend mode
+* Input          : None.
+* Return         : None.
+*******************************************************************************/
+void Enter_LowPowerMode(void)
+{
+    /* Set the device state to suspend */
+    bDeviceState = SUSPENDED;
+}
+
+/*******************************************************************************
+* Function Name  : Leave_LowPowerMode
+* Description    : Restores system clocks and power while exiting suspend mode
+* Input          : None.
+* Return         : None.
+*******************************************************************************/
+void Leave_LowPowerMode(void)
+{
+    DEVICE_INFO *pInfo = &Device_Info;
+
+    /* Set the device state to the correct state */
+    if (pInfo->Current_Configuration != 0)
+    {
+        /* Device configured */
+        bDeviceState = CONFIGURED;
+    }
+    else
+    {
+        bDeviceState = ATTACHED;
+    }
+
+}
+
+/*******************************************************************************
+* Function Name  : USB_Interrupts_Config
+* Description    : Configures the USB interrupts
+* Input          : None.
+* Return         : None.
+*******************************************************************************/
+void USB_Interrupts_Config(void)
+{
+    NVIC_InitTypeDef NVIC_InitStructure;
+
+    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
+
+    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+
+    NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+
+#if 0
+    NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+#endif /* USE_STM3210E_EVAL */
+
+}
+
+/*******************************************************************************
+* Function Name  : Led_Config
+* Description    : configure the Read/Write LEDs.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Led_Config(void)
+{
+}
+
+/*******************************************************************************
+* Function Name  : Led_RW_ON
+* Description    : Turn ON the Read/Write LEDs.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Led_RW_ON(void)
+{
+    //GPIO_SetBits(USB_LED_PORT, GPIO_Pin_8);
+}
+
+/*******************************************************************************
+* Function Name  : Led_RW_OFF
+* Description    : Turn off the Read/Write LEDs.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Led_RW_OFF(void)
+{
+    //GPIO_ResetBits(USB_LED_PORT, GPIO_Pin_8);
+}
+/*******************************************************************************
+* Function Name  : USB_Configured_LED
+* Description    : Turn ON the Read/Write LEDs.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void USB_Configured_LED(void)
+{
+    //GPIO_SetBits(USB_LED_PORT, GPIO_Pin_6);
+}
+
+/*******************************************************************************
+* Function Name  : USB_NotConfigured_LED
+* Description    : Turn off the Read/Write LEDs.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void USB_NotConfigured_LED(void)
+{
+    //GPIO_ResetBits(USB_LED_PORT, GPIO_Pin_6);
+}
+
+/*******************************************************************************
+* Function Name  : USB_Cable_Config
+* Description    : Software Connection/Disconnection of USB Cable.
+* Input          : None.
+* Return         : Status
+*******************************************************************************/
+void USB_Cable_Config (FunctionalState NewState)
+{
+    if (NewState != DISABLE)
+    {
+        GPIO_SetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
+    }
+    else
+    {
+        GPIO_ResetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
+    }
+}
+
+/*******************************************************************************
+* Function Name  : Get_SerialNum.
+* Description    : Create the serial number string descriptor.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Get_SerialNum(void)
+{
+    uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
+
+    Device_Serial0 = *(__IO uint32_t*)(0x1FFFF7E8);
+    Device_Serial1 = *(__IO uint32_t*)(0x1FFFF7EC);
+    Device_Serial2 = *(__IO uint32_t*)(0x1FFFF7F0);
+
+    if (Device_Serial0 != 0)
+    {
+        MASS_StringSerial[2] = (uint8_t)(Device_Serial0 & 0x000000FF);
+        MASS_StringSerial[4] = (uint8_t)((Device_Serial0 & 0x0000FF00) >> 8);
+        MASS_StringSerial[6] = (uint8_t)((Device_Serial0 & 0x00FF0000) >> 16);
+        MASS_StringSerial[8] = (uint8_t)((Device_Serial0 & 0xFF000000) >> 24);
+
+        MASS_StringSerial[10] = (uint8_t)(Device_Serial1 & 0x000000FF);
+        MASS_StringSerial[12] = (uint8_t)((Device_Serial1 & 0x0000FF00) >> 8);
+        MASS_StringSerial[14] = (uint8_t)((Device_Serial1 & 0x00FF0000) >> 16);
+        MASS_StringSerial[16] = (uint8_t)((Device_Serial1 & 0xFF000000) >> 24);
+
+        MASS_StringSerial[18] = (uint8_t)(Device_Serial2 & 0x000000FF);
+        MASS_StringSerial[20] = (uint8_t)((Device_Serial2 & 0x0000FF00) >> 8);
+        MASS_StringSerial[22] = (uint8_t)((Device_Serial2 & 0x00FF0000) >> 16);
+        MASS_StringSerial[24] = (uint8_t)((Device_Serial2 & 0xFF000000) >> 24);
+    }
+}
+
+/*******************************************************************************
+* Function Name  : MAL_Config
+* Description    : MAL_layer configuration
+* Input          : None.
+* Return         : None.
+*******************************************************************************/
+void MAL_Config(void)
+{
+    MAL_Init(0);
+}
+
+/*******************************************************************************
+* Function Name  : USB_Disconnect_Config
+* Description    : Disconnect pin configuration
+* Input          : None.
+* Return         : None.
+*******************************************************************************/
+void USB_Disconnect_Config(void)
+{
+    GPIO_InitTypeDef GPIO_InitStructure;
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_DISCONNECT, ENABLE);
+
+    /* config USB cable pin */
+    GPIO_InitStructure.GPIO_Pin   = USB_DISCONNECT_PIN;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
+    GPIO_Init(USB_DISCONNECT, &GPIO_InitStructure);
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 84 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/mass_mal.c

@@ -0,0 +1,84 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : mass_mal.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : Medium Access Layer interface
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "platform_config.h"
+#include "sdcard.h"
+#include "mass_mal.h"
+#include "rtthread.h"
+
+uint32_t Mass_Memory_Size[2];
+uint32_t Mass_Block_Size[2];
+uint32_t Mass_Block_Count[2];
+
+rt_device_t dev_sdio = RT_NULL;
+
+uint16_t MAL_Init(uint8_t lun)
+{
+    uint16_t status = MAL_OK;
+
+    switch (lun)
+    {
+    case 0:
+        status = MAL_OK;
+        break;
+    default:
+        return MAL_FAIL;
+    }
+    return status;
+}
+
+uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)
+{
+
+    switch (lun)
+    {
+    case 0:
+    {
+        dev_sdio->write(dev_sdio,Memory_Offset,Writebuff,Transfer_Length);
+    }
+    break;
+    default:
+        return MAL_FAIL;
+    }
+    return MAL_OK;
+}
+
+uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length)
+{
+
+    switch (lun)
+    {
+    case 0:
+    {
+        dev_sdio->read(dev_sdio,Memory_Offset,Readbuff,Transfer_Length);
+    }
+    break;
+    default:
+        return MAL_FAIL;
+    }
+    return MAL_OK;
+}
+
+uint16_t MAL_GetStatus (uint8_t lun)
+{
+    if(lun == 0)
+    {
+        return MAL_OK;
+    }
+    return MAL_FAIL;
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 168 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/memory.c

@@ -0,0 +1,168 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : memory.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Memory management layer
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "memory.h"
+#include "usb_scsi.h"
+#include "usb_bot.h"
+#include "usb_regs.h"
+#include "usb_mem.h"
+#include "usb_conf.h"
+#include "hw_config.h"
+#include "mass_mal.h"
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint32_t Block_Read_count = 0;
+__IO uint32_t Block_offset;
+__IO uint32_t Counter = 0;
+uint32_t  Idx;
+uint32_t Data_Buffer[BULK_MAX_PACKET_SIZE *2]; /* 512 bytes*/
+uint8_t TransferState = TXFR_IDLE;
+/* Extern variables ----------------------------------------------------------*/
+extern uint8_t Bulk_Data_Buff[BULK_MAX_PACKET_SIZE];  /* data buffer*/
+extern uint16_t Data_Len;
+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];
+
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : Read_Memory
+* Description    : Handle the Read operation from the microSD card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Read_Memory(uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length)
+{
+  static uint32_t Offset, Length;
+
+  if (TransferState == TXFR_IDLE )
+  {
+    Offset = Memory_Offset * Mass_Block_Size[lun];
+    Length = Transfer_Length * Mass_Block_Size[lun];
+    TransferState = TXFR_ONGOING;
+  }
+
+  if (TransferState == TXFR_ONGOING )
+  {
+    if (!Block_Read_count)
+    {
+      MAL_Read(lun ,
+               Offset ,
+               Data_Buffer,
+               Mass_Block_Size[lun]);
+
+      USB_SIL_Write(EP1_IN, (uint8_t *)Data_Buffer, BULK_MAX_PACKET_SIZE);
+
+      Block_Read_count = Mass_Block_Size[lun] - BULK_MAX_PACKET_SIZE;
+      Block_offset = BULK_MAX_PACKET_SIZE;
+    }
+    else
+    {
+      USB_SIL_Write(EP1_IN, (uint8_t *)Data_Buffer + Block_offset, BULK_MAX_PACKET_SIZE);
+
+      Block_Read_count -= BULK_MAX_PACKET_SIZE;
+      Block_offset += BULK_MAX_PACKET_SIZE;
+    }
+
+    SetEPTxCount(ENDP1, BULK_MAX_PACKET_SIZE);
+    SetEPTxStatus(ENDP1, EP_TX_VALID);
+    Offset += BULK_MAX_PACKET_SIZE;
+    Length -= BULK_MAX_PACKET_SIZE;
+
+    CSW.dDataResidue -= BULK_MAX_PACKET_SIZE;
+    Led_RW_ON();
+  }
+  if (Length == 0)
+  {
+    Block_Read_count = 0;
+    Block_offset = 0;
+    Offset = 0;
+    Bot_State = BOT_DATA_IN_LAST;
+    TransferState = TXFR_IDLE;
+    Led_RW_OFF();
+  }
+}
+
+/*******************************************************************************
+* Function Name  : Write_Memory
+* Description    : Handle the Write operation to the microSD card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Write_Memory (uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length)
+{
+
+  static uint32_t W_Offset, W_Length;
+
+  uint32_t temp =  Counter + 64;
+
+  if (TransferState == TXFR_IDLE )
+  {
+    W_Offset = Memory_Offset * Mass_Block_Size[lun];
+    W_Length = Transfer_Length * Mass_Block_Size[lun];
+    TransferState = TXFR_ONGOING;
+  }
+
+  if (TransferState == TXFR_ONGOING )
+  {
+
+    for (Idx = 0 ; Counter < temp; Counter++)
+    {
+      *((uint8_t *)Data_Buffer + Counter) = Bulk_Data_Buff[Idx++];
+    }
+
+    W_Offset += Data_Len;
+    W_Length -= Data_Len;
+
+    if (!(W_Length % Mass_Block_Size[lun]))
+    {
+      Counter = 0;
+      MAL_Write(lun ,
+                W_Offset - Mass_Block_Size[lun],
+                Data_Buffer,
+                Mass_Block_Size[lun]);
+    }
+
+    CSW.dDataResidue -= Data_Len;
+  #ifndef STM32F10X_CL
+    SetEPRxStatus(ENDP2, EP_RX_VALID); /* enable the next transaction*/   
+  #endif /* STM32F10X_CL */
+
+    Led_RW_ON();
+  }
+
+  if ((W_Length == 0) || (Bot_State == BOT_CSW_Send))
+  {
+    Counter = 0;
+    Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
+    TransferState = TXFR_IDLE;
+    Led_RW_OFF();
+  }
+}
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 544 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/nand_if.c

@@ -0,0 +1,544 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : nand_if.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : manage NAND operationx state machine
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#include "platform_config.h"
+
+#ifdef USE_STM3210E_EVAL
+/* Includes ------------------------------------------------------------------*/
+#include "nand_if.h"
+#include "mass_mal.h"
+#include "fsmc_nand.h"
+#include "memory.h"
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* extern variables-----------------------------------------------------------*/
+extern uint32_t SCSI_LBA;
+extern uint32_t SCSI_BlkLen;
+/* Private variables ---------------------------------------------------------*/
+uint16_t LUT[1024]; //Look Up Table Buffer
+WRITE_STATE Write_State;
+BLOCK_STATE Block_State;
+NAND_ADDRESS wAddress, fAddress;
+uint16_t  phBlock, LogAddress, Initial_Page, CurrentZone = 0;
+uint16_t  Written_Pages = 0;
+
+uint16_t LUT[1024]; //Look Up Table Buffer
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+static uint16_t NAND_CleanLUT(uint8_t ZoneNbr);
+static NAND_ADDRESS NAND_GetAddress(uint32_t Address);
+static uint16_t NAND_GetFreeBlock(void);
+static uint16_t NAND_Write_Cleanup(void);
+SPARE_AREA ReadSpareArea(uint32_t address);
+static uint16_t NAND_Copy(NAND_ADDRESS Address_Src, NAND_ADDRESS Address_Dest, uint16_t PageToCopy);
+static NAND_ADDRESS NAND_ConvertPhyAddress(uint32_t Address);
+static uint16_t NAND_BuildLUT(uint8_t ZoneNbr);
+
+/*******************************************************************************
+* Function Name  : NAND_Init
+* Description    : Init NAND Interface
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+uint16_t NAND_Init(void)
+{
+  uint16_t Status = NAND_OK;
+
+  FSMC_NAND_Init();
+  Status = NAND_BuildLUT(0);
+  Write_State = WRITE_IDLE;
+  return Status;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_Write
+* Description    : write one sector by once
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+uint16_t NAND_Write(uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)
+{
+  /* check block status and calculate start and end addreses */
+  wAddress    = NAND_GetAddress(Memory_Offset / 512);
+
+  /*check Zone: if second zone is requested build second LUT*/
+  if (wAddress.Zone != CurrentZone)
+  {
+    CurrentZone = wAddress.Zone;
+    NAND_BuildLUT(CurrentZone);
+  }
+
+  phBlock     = LUT[wAddress.Block]; /* Block Index + flags */
+  LogAddress  = wAddress.Block ; /* save logical block */
+
+  /*  IDLE state  */
+  /****************/
+  if ( Write_State == WRITE_IDLE)
+  {/* Idle state */
+
+    if (phBlock & USED_BLOCK)
+    { /* USED BLOCK */
+
+      Block_State = OLD_BLOCK;
+      /* Get a free Block for swap */
+      fAddress.Block = NAND_GetFreeBlock();
+      fAddress.Zone  = wAddress.Zone;
+      Initial_Page = fAddress.Page  = wAddress.Page;
+
+      /* write the new page */
+      FSMC_NAND_WriteSmallPage((uint8_t *)Writebuff, fAddress, PAGE_TO_WRITE);
+      Written_Pages++;
+
+      /* get physical block */
+      wAddress.Block = phBlock & 0x3FF;
+
+
+      if (Written_Pages == SCSI_BlkLen)
+      {
+        NAND_Write_Cleanup();
+        Written_Pages = 0;
+        return NAND_OK;
+      }
+      else
+      {
+        if (wAddress.Page == (NAND_BLOCK_SIZE - 1))
+        {
+          NAND_Write_Cleanup();
+          return NAND_OK;
+        }
+        Write_State = WRITE_ONGOING;
+        return NAND_OK;
+      }
+    }
+    else
+    {/* UNUSED BLOCK */
+
+      Block_State = UNUSED_BLOCK;
+      /* write the new page */
+      wAddress.Block = phBlock & 0x3FF;
+      FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , wAddress, PAGE_TO_WRITE);
+
+      Written_Pages++;
+      if (Written_Pages == SCSI_BlkLen)
+      {
+        Written_Pages = 0;
+        NAND_Write_Cleanup();
+        return NAND_OK;
+      }
+      else
+      {
+        Write_State = WRITE_ONGOING;
+        return NAND_OK;
+      }
+    }
+  }
+  /* WRITE state */
+  /***************/
+  if ( Write_State == WRITE_ONGOING)
+  {/* Idle state */
+    if (phBlock & USED_BLOCK)
+    { /* USED BLOCK */
+
+      wAddress.Block = phBlock & 0x3FF;
+      Block_State = OLD_BLOCK;
+      fAddress.Page  = wAddress.Page;
+
+      /* check if next pages are in next block */
+      if (wAddress.Page == (NAND_BLOCK_SIZE - 1))
+      {
+        /* write Last page  */
+        FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , fAddress, PAGE_TO_WRITE);
+        Written_Pages++;
+        if (Written_Pages == SCSI_BlkLen)
+        {
+          Written_Pages = 0;
+        }
+        /* Clean up and Update the LUT */
+        NAND_Write_Cleanup();
+        Write_State = WRITE_IDLE;
+        return NAND_OK;
+      }
+
+      /* write next page */
+      FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , fAddress, PAGE_TO_WRITE);
+      Written_Pages++;
+      if (Written_Pages == SCSI_BlkLen)
+      {
+        Write_State = WRITE_IDLE;
+        NAND_Write_Cleanup();
+        Written_Pages = 0;
+      }
+
+    }
+    else
+    {/* UNUSED BLOCK */
+      wAddress.Block = phBlock & 0x3FF;
+      /* check if it is the last page in prev block */
+      if (wAddress.Page == (NAND_BLOCK_SIZE - 1))
+      {
+        /* write Last page  */
+        FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , wAddress, PAGE_TO_WRITE);
+        Written_Pages++;
+        if (Written_Pages == SCSI_BlkLen)
+        {
+          Written_Pages = 0;
+        }
+
+        /* Clean up and Update the LUT */
+        NAND_Write_Cleanup();
+        Write_State = WRITE_IDLE;
+
+
+
+        return NAND_OK;
+      }
+      /* write next page in same block */
+      FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , wAddress, PAGE_TO_WRITE);
+      Written_Pages++;
+      if (Written_Pages == SCSI_BlkLen)
+      {
+        Write_State = WRITE_IDLE;
+        NAND_Write_Cleanup();
+        Written_Pages = 0;
+      }
+    }
+  }
+  return NAND_OK;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_Read
+* Description    : Read sectors
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+uint16_t NAND_Read(uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length)
+{
+  NAND_ADDRESS phAddress;
+
+  phAddress = NAND_GetAddress(Memory_Offset / 512);
+
+  if (phAddress.Zone != CurrentZone)
+  {
+    CurrentZone = phAddress.Zone;
+    NAND_BuildLUT(CurrentZone);
+  }
+
+  if (LUT [phAddress.Block] & BAD_BLOCK)
+  {
+    return NAND_FAIL;
+  }
+  else
+  {
+    phAddress.Block = LUT [phAddress.Block] & ~ (USED_BLOCK | VALID_BLOCK);
+    FSMC_NAND_ReadSmallPage ( (uint8_t *)Readbuff , phAddress, Transfer_Length / 512);
+  }
+  return NAND_OK;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_CleanLUT
+* Description    : Erase old blocks & rebuild the look up table
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static uint16_t NAND_CleanLUT (uint8_t ZoneNbr)
+{
+#ifdef WEAR_LEVELLING_SUPPORT
+  uint16_t BlockIdx, LUT_Item;
+#endif
+  /* Rebuild the LUT for the current zone */
+  NAND_BuildLUT (ZoneNbr);
+
+#ifdef WEAR_LEVELLING_SUPPORT
+  /* Wear Leveling : circular use of free blocks */
+  LUT_Item = LUT [BlockIdx]
+             for (BlockIdx == MAX_LOG_BLOCKS_PER_ZONE ; BlockIdx < MAX_LOG_BLOCKS_PER_ZONE + WEAR_DEPTH ; BlockIdx++)
+             {
+               LUT [BlockIdx] = LUT [BlockIdx + 1];
+             }
+             LUT [ MAX_LOG_BLOCKS_PER_ZONE + WEAR_DEPTH - 1] = LUT_Item ;
+#endif
+
+  return NAND_OK;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_GetAddress
+* Description    : Translate logical address into a phy one
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static NAND_ADDRESS NAND_GetAddress (uint32_t Address)
+{
+  NAND_ADDRESS Address_t;
+
+  Address_t.Page  = Address & (NAND_BLOCK_SIZE - 1);
+  Address_t.Block = Address / NAND_BLOCK_SIZE;
+  Address_t.Zone = 0;
+
+  while (Address_t.Block >= MAX_LOG_BLOCKS_PER_ZONE)
+  {
+    Address_t.Block -= MAX_LOG_BLOCKS_PER_ZONE;
+    Address_t.Zone++;
+  }
+  return Address_t;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_GetFreeBlock
+* Description    : Look for a free block for data exchange
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static uint16_t NAND_GetFreeBlock (void)
+{
+  return LUT[MAX_LOG_BLOCKS_PER_ZONE]& ~(USED_BLOCK | VALID_BLOCK);
+}
+
+/*******************************************************************************
+* Function Name  : ReadSpareArea
+* Description    : Check used block
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+SPARE_AREA ReadSpareArea (uint32_t address)
+{
+  SPARE_AREA t;
+  uint8_t Buffer[16];
+  NAND_ADDRESS address_s;
+  address_s = NAND_ConvertPhyAddress(address);
+  FSMC_NAND_ReadSpareArea(Buffer , address_s, 1) ;
+
+  t = *(SPARE_AREA *)Buffer;
+
+  return t;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_Copy
+* Description    : Copy page
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static uint16_t NAND_Copy (NAND_ADDRESS Address_Src, NAND_ADDRESS Address_Dest, uint16_t PageToCopy)
+{
+  uint8_t Copybuff[512];
+  for ( ; PageToCopy > 0 ; PageToCopy-- )
+  {
+    FSMC_NAND_ReadSmallPage  ((uint8_t *)Copybuff, Address_Src , 1 );
+    FSMC_NAND_WriteSmallPage ((uint8_t *)Copybuff, Address_Dest, 1);
+    FSMC_NAND_AddressIncrement(&Address_Src);
+    FSMC_NAND_AddressIncrement(&Address_Dest);
+  }
+
+  return NAND_OK;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_Format
+* Description    : Format the entire NAND flash
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+uint16_t NAND_Format (void)
+{
+  NAND_ADDRESS phAddress;
+  SPARE_AREA  SpareArea;
+  uint32_t BlockIndex;
+
+  for (BlockIndex = 0 ; BlockIndex < NAND_ZONE_SIZE * NAND_MAX_ZONE; BlockIndex++)
+  {
+    phAddress = NAND_ConvertPhyAddress(BlockIndex * NAND_BLOCK_SIZE );
+    SpareArea = ReadSpareArea(BlockIndex * NAND_BLOCK_SIZE);
+   
+    if((SpareArea.DataStatus != 0)||(SpareArea.BlockStatus != 0)){
+        FSMC_NAND_EraseBlock (phAddress);
+    }  
+  }
+  NAND_BuildLUT(0);
+  return NAND_OK;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_Write_Cleanup
+* Description    : None
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static uint16_t NAND_Write_Cleanup (void)
+{
+  uint16_t  tempSpareArea [8];
+  uint16_t  Page_Back;
+
+  if ( Block_State == OLD_BLOCK )
+  {
+    /* precopy old first pages */
+    if (Initial_Page != 0)
+    {
+      Page_Back = wAddress.Page;
+      fAddress.Page = wAddress.Page = 0;
+      NAND_Copy (wAddress, fAddress, Initial_Page);
+      wAddress.Page =  Page_Back ;
+    }
+
+    /* postcopy remaining pages */
+    if ((NAND_BLOCK_SIZE - (wAddress.Page + 1)) != 0)
+    {
+      FSMC_NAND_AddressIncrement(&wAddress);
+      fAddress.Page = wAddress.Page;
+      NAND_Copy (wAddress, fAddress, NAND_BLOCK_SIZE - wAddress.Page);
+    }
+
+    /* assign logical address to new block */
+    tempSpareArea [0] = LogAddress | USED_BLOCK ;
+    tempSpareArea [1] = 0xFFFF;
+    tempSpareArea [2] = 0xFFFF;
+
+    fAddress.Page     = 0x00;
+    FSMC_NAND_WriteSpareArea( (uint8_t *)tempSpareArea , fAddress , 1);
+
+    /* erase old block */
+    FSMC_NAND_EraseBlock(wAddress);
+    NAND_CleanLUT(wAddress.Zone);
+  }
+  else
+  {/* unused block case */
+    /* assign logical address to the new used block */
+    tempSpareArea [0] = LogAddress | USED_BLOCK ;
+    tempSpareArea [1] = 0xFFFF;
+    tempSpareArea [2] = 0xFFFF;
+
+    wAddress.Page     = 0x00;
+    FSMC_NAND_WriteSpareArea((uint8_t *)tempSpareArea , wAddress, 1);
+    NAND_CleanLUT(wAddress.Zone);
+  }
+  return NAND_OK;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_ConvertPhyAddress
+* Description    : None
+* Input          : physical Address
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static NAND_ADDRESS NAND_ConvertPhyAddress (uint32_t Address)
+{
+  NAND_ADDRESS Address_t;
+
+  Address_t.Page  = Address & (NAND_BLOCK_SIZE - 1);
+  Address_t.Block = Address / NAND_BLOCK_SIZE;
+  Address_t.Zone = 0;
+
+  while (Address_t.Block >= MAX_PHY_BLOCKS_PER_ZONE)
+  {
+    Address_t.Block -= MAX_PHY_BLOCKS_PER_ZONE;
+    Address_t.Zone++;
+  }
+  return Address_t;
+}
+
+/*******************************************************************************
+* Function Name  : NAND_BuildLUT
+* Description    : Build the look up table
+* Input          : None
+* Output         : None
+* Return         : Status
+* !!!! NOTE : THIS ALGORITHM IS A SUBJECT OF PATENT FOR STMICROELECTRONICS !!!!!
+*******************************************************************************/
+static uint16_t NAND_BuildLUT (uint8_t ZoneNbr)
+{
+
+  uint16_t  pBadBlock, pCurrentBlock, pFreeBlock;
+  SPARE_AREA  SpareArea;
+  /*****************************************************************************
+                                  1st step : Init.
+  *****************************************************************************/
+  /*Init the LUT (assume all blocks free) */
+  for (pCurrentBlock = 0 ; pCurrentBlock < MAX_PHY_BLOCKS_PER_ZONE ; pCurrentBlock++)
+  {
+    LUT[pCurrentBlock] = FREE_BLOCK;  /* 12th bit is set to 1 */
+  }
+
+  /* Init Pointers */
+  pBadBlock    = MAX_PHY_BLOCKS_PER_ZONE - 1;
+  pCurrentBlock = 0;
+
+  /*****************************************************************************
+                         2nd step : locate used and bad blocks
+  *****************************************************************************/
+
+  while (pCurrentBlock < MAX_PHY_BLOCKS_PER_ZONE)
+  {
+
+    SpareArea = ReadSpareArea(pCurrentBlock * NAND_BLOCK_SIZE + (ZoneNbr * NAND_BLOCK_SIZE * MAX_PHY_BLOCKS_PER_ZONE));
+
+    if ((SpareArea.DataStatus == 0) || (SpareArea.BlockStatus == 0))
+    {
+
+      LUT[pBadBlock--]    |= pCurrentBlock | (uint16_t)BAD_BLOCK ;
+      LUT[pCurrentBlock] &= (uint16_t)~FREE_BLOCK;
+      if (pBadBlock == MAX_LOG_BLOCKS_PER_ZONE)
+      {
+        return NAND_FAIL;
+      }
+    }
+    else if (SpareArea.LogicalIndex != 0xFFFF)
+    {
+
+      LUT[SpareArea.LogicalIndex & 0x3FF] |= pCurrentBlock | VALID_BLOCK | USED_BLOCK;
+      LUT[pCurrentBlock] &= (uint16_t)( ~FREE_BLOCK);
+    }
+    pCurrentBlock++ ;
+  }
+
+  /*****************************************************************************
+     3rd step : locate Free Blocks by scanning the LUT already built partially
+  *****************************************************************************/
+  pFreeBlock = 0;
+  for (pCurrentBlock = 0 ; pCurrentBlock < MAX_PHY_BLOCKS_PER_ZONE ; pCurrentBlock++ )
+  {
+
+    if ( !(LUT[pCurrentBlock]& USED_BLOCK))
+    {
+      do
+      {
+        if (LUT[pFreeBlock] & FREE_BLOCK)
+        {
+
+          LUT [pCurrentBlock] |= pFreeBlock;
+          LUT [pFreeBlock]   &= ~FREE_BLOCK;
+          break;
+        }
+        pFreeBlock++;
+      }
+      while ( pFreeBlock < MAX_PHY_BLOCKS_PER_ZONE );
+    }
+  }
+  return NAND_OK;
+}
+#endif
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 145 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/scsi_data.c

@@ -0,0 +1,145 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : scsi_data.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : Initialization of the SCSI data
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_scsi.h"
+#include "memory.h"
+uint8_t Page00_Inquiry_Data[] =
+  {
+    0x00, /* PERIPHERAL QUALIFIER & PERIPHERAL DEVICE TYPE*/
+    0x00,
+    0x00,
+    0x00,
+    0x00 /* Supported Pages 00*/
+  };
+uint8_t Standard_Inquiry_Data[] =
+  {
+    0x00,          /* Direct Access Device */
+    0x80,          /* RMB = 1: Removable Medium */
+    0x02,          /* Version: No conformance claim to standard */
+    0x02,
+
+    36 - 4,          /* Additional Length */
+    0x00,          /* SCCS = 1: Storage Controller Component */
+    0x00,
+    0x00,
+    /* Vendor Identification */
+    'S', 'T', 'M', ' ', 'C', 'M', '-', '3',
+    /* Product Identification */
+    'S', 'D', ' ', 'F', 'l', 'a', 's', 'h', ' ',
+    'D', 'i', 's', 'k', ' ', ' ', ' ',
+    /* Product Revision Level */
+    '1', '.', '0', ' '
+  };
+uint8_t Standard_Inquiry_Data2[] =
+  {
+    0x00,          /* Direct Access Device *///磁盘设备
+    //其中最高位D7为RMB。RMB=0,表示不可移除设备。如果RMB=1,则为可移除设备。
+    0x80,          /* RMB = 1: Removable Medium */
+
+    0x02,          /* Version: No conformance claim to standard */
+    0x02,          //数据响应格式
+
+    36 - 4,          //附加数据长度,为31字节
+    0x00,          /* SCCS = 1: Storage Controller Component */
+    0x00,
+    0x00,
+    /* Vendor Identification */
+    'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ',
+    /* Product Identification */
+    'N', 'A', 'N', 'D', ' ', 'F', 'l', 'a', 's', 'h', ' ',
+    'D', 'i', 's', 'k', ' ',
+    /* Product Revision Level */
+    '1', '.', '0', ' '
+  };
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+uint8_t Mode_Sense6_data[] =
+  {
+    0x03,
+    0x00,
+    0x00,
+    0x00,
+  };
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+uint8_t Mode_Sense10_data[] =
+  {
+    0x00,
+    0x06,
+    0x00,
+    0x00,
+    0x00,
+    0x00,
+    0x00,
+    0x00
+  };
+uint8_t Scsi_Sense_Data[] =
+  {
+    0x70, /*RespCode*/
+    0x00, /*SegmentNumber*/
+    NO_SENSE, /* Sens_Key*/
+    0x00,
+    0x00,
+    0x00,
+    0x00, /*Information*/
+    0x0A, /*AdditionalSenseLength*/
+    0x00,
+    0x00,
+    0x00,
+    0x00, /*CmdInformation*/
+    NO_SENSE, /*Asc*/
+    0x00, /*ASCQ*/
+    0x00, /*FRUC*/
+    0x00, /*TBD*/
+    0x00,
+    0x00 /*SenseKeySpecific*/
+  };
+uint8_t ReadCapacity10_Data[] =
+  {
+    /* Last Logical Block */
+    0,
+    0,
+    0,
+    0,
+
+    /* Block Length */
+    0,
+    0,
+    0,
+    0
+  };
+
+uint8_t ReadFormatCapacity_Data [] =
+  {
+    0x00,
+    0x00,
+    0x00,
+    0x08, /* Capacity List Length */
+
+    /* Block Count */
+    0,
+    0,
+    0,
+    0,
+
+    /* Block Length */
+    0x02,/* Descriptor Code: Formatted Media */
+    0,
+    0,
+    0
+  };
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 347 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/usb_bot.c

@@ -0,0 +1,347 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_bot.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : BOT State Machine management
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_scsi.h"
+#include "hw_config.h"
+#include "usb_regs.h"
+#include "usb_mem.h"
+#include "usb_conf.h"
+#include "usb_bot.h"
+#include "memory.h"
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+uint8_t Bot_State;
+uint8_t Bulk_Data_Buff[BULK_MAX_PACKET_SIZE];  /* data buffer*/
+uint16_t Data_Len;
+Bulk_Only_CBW CBW;
+Bulk_Only_CSW CSW;
+uint32_t SCSI_LBA , SCSI_BlkLen;
+extern uint32_t Max_Lun;
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : Mass_Storage_In
+* Description    : Mass Storage IN transfer.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Mass_Storage_In (void)
+{
+    switch (Bot_State)
+    {
+    case BOT_CSW_Send:
+    case BOT_ERROR:
+        Bot_State = BOT_IDLE;
+        SetEPRxStatus(ENDP2, EP_RX_VALID);/* enable the Endpoint to recive the next cmd*/
+        break;
+    case BOT_DATA_IN:
+        switch (CBW.CB[0])
+        {
+        case SCSI_READ10:
+            SCSI_Read10_Cmd(CBW.bLUN , SCSI_LBA , SCSI_BlkLen);
+            break;
+        }
+        break;
+    case BOT_DATA_IN_LAST:
+        Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
+        SetEPRxStatus(ENDP2, EP_RX_VALID);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : Mass_Storage_Out
+* Description    : Mass Storage OUT transfer.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Mass_Storage_Out (void)
+{
+    uint8_t CMD;
+    CMD = CBW.CB[0];//得到上一次的?
+    //得到端点2接收到的数据长度
+    Data_Len = GetEPRxCount(ENDP2);
+
+    //print(" MS_Out:");//print_dec(Data_Len);
+
+    //读出数据到 Bulk_Data_Buff
+    PMAToUserBufferCopy(Bulk_Data_Buff, ENDP2_RXADDR, Data_Len);
+
+    switch (Bot_State)
+    {
+    case BOT_IDLE://空闲状态  进入CBW解码
+        //print("BOT_IDLE");
+        CBW_Decode();
+        break;
+    case BOT_DATA_OUT://数据输出状态
+        //print("BOT_DATA_OUT");
+        if (CMD == SCSI_WRITE10)
+        {
+            //print(" CMD == SCSI_WRITE10");
+            SCSI_Write10_Cmd(CBW.bLUN , SCSI_LBA , SCSI_BlkLen);
+            break;
+        }
+        Bot_Abort(DIR_OUT);
+        Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+        Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE);
+        break;
+    default:
+        Bot_Abort(BOTH_DIR);
+        Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+        Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE);
+        break;
+    }
+}
+
+/*******************************************************************************
+* Function Name  : CBW_Decode
+* Description    : Decode the received CBW and call the related SCSI command
+*                 routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void CBW_Decode(void)
+{
+    uint32_t Counter;
+
+    //从Bulk_Data_Buff复制数据到CBW
+    for (Counter = 0; Counter < Data_Len; Counter++)
+    {
+        *((uint8_t *)&CBW + Counter) = Bulk_Data_Buff[Counter];
+    }
+    //复制TAG用于返回
+    CSW.dTag = CBW.dTag;
+    CSW.dDataResidue = CBW.dDataLength;
+    //如果数据长度不等于CBW的长度
+    if (Data_Len != BOT_CBW_PACKET_LENGTH)
+    {
+        //print(" Data_Len != BOT_CBW_PACKET_LENGTH");
+        Bot_Abort(BOTH_DIR);
+        /* reset the CBW.dSignature to desible the clear feature until receiving a Mass storage reset*/
+        CBW.dSignature = 0;
+        Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, PARAMETER_LIST_LENGTH_ERROR);
+        Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+        return;
+    }
+
+    //读写数据
+    if ((CBW.CB[0] == SCSI_READ10 ) || (CBW.CB[0] == SCSI_WRITE10 ))
+    {
+        /* Calculate Logical Block Address */
+        //计算逻辑块地址 每个扇区512字节
+        SCSI_LBA = (CBW.CB[2] << 24) | (CBW.CB[3] << 16) | (CBW.CB[4] <<  8) | CBW.CB[5];
+        /* Calculate the Number of Blocks to transfer */
+        //计算传送的块大小 以扇区为单位?
+        SCSI_BlkLen = (CBW.CB[7] <<  8) | CBW.CB[8];
+    }
+
+    //USBC
+    if (CBW.dSignature == BOT_CBW_SIGNATURE)
+    {
+        /* Valid CBW */
+        //有效但参数错误
+        if ((CBW.bLUN > Max_Lun) || (CBW.bCBLength < 1) || (CBW.bCBLength > 16))
+        {
+            Bot_Abort(BOTH_DIR);
+            Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+            Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+        }
+        else
+        {
+            switch (CBW.CB[0])
+            {
+            case SCSI_REQUEST_SENSE:
+                SCSI_RequestSense_Cmd (CBW.bLUN);
+                break;
+            case SCSI_INQUIRY:
+                SCSI_Inquiry_Cmd(CBW.bLUN);
+                break;
+            case SCSI_START_STOP_UNIT:
+                SCSI_Start_Stop_Unit_Cmd(CBW.bLUN);
+                break;
+            case SCSI_ALLOW_MEDIUM_REMOVAL:
+                SCSI_Start_Stop_Unit_Cmd(CBW.bLUN);
+                break;
+            case SCSI_MODE_SENSE6:
+                SCSI_ModeSense6_Cmd (CBW.bLUN);
+                break;
+            case SCSI_MODE_SENSE10:
+                SCSI_ModeSense10_Cmd (CBW.bLUN);
+                break;
+            case SCSI_READ_FORMAT_CAPACITIES:
+                SCSI_ReadFormatCapacity_Cmd(CBW.bLUN);
+                break;
+            case SCSI_READ_CAPACITY10:
+                SCSI_ReadCapacity10_Cmd(CBW.bLUN);
+                break;
+            case SCSI_TEST_UNIT_READY:
+                SCSI_TestUnitReady_Cmd(CBW.bLUN);
+                break;
+            case SCSI_READ10:
+            //读数据
+                SCSI_Read10_Cmd(CBW.bLUN, SCSI_LBA , SCSI_BlkLen);
+                break;
+            case SCSI_WRITE10:
+                //写数据
+                SCSI_Write10_Cmd(CBW.bLUN, SCSI_LBA , SCSI_BlkLen);
+                break;
+            case SCSI_VERIFY10:
+                SCSI_Verify10_Cmd(CBW.bLUN);
+                break;
+            case SCSI_FORMAT_UNIT:
+                SCSI_Format_Cmd(CBW.bLUN);
+                break;
+                /*Unsupported command*/
+
+            case SCSI_MODE_SELECT10:
+                SCSI_Mode_Select10_Cmd(CBW.bLUN);
+                break;
+            case SCSI_MODE_SELECT6:
+                SCSI_Mode_Select6_Cmd(CBW.bLUN);
+                break;
+
+            case SCSI_SEND_DIAGNOSTIC:
+                SCSI_Send_Diagnostic_Cmd(CBW.bLUN);
+                break;
+            case SCSI_READ6:
+                SCSI_Read6_Cmd(CBW.bLUN);
+                break;
+            case SCSI_READ12:
+                SCSI_Read12_Cmd(CBW.bLUN);
+                break;
+            case SCSI_READ16:
+                SCSI_Read16_Cmd(CBW.bLUN);
+                break;
+            case SCSI_READ_CAPACITY16:
+                SCSI_READ_CAPACITY16_Cmd(CBW.bLUN);
+                break;
+            case SCSI_WRITE6:
+                SCSI_Write6_Cmd(CBW.bLUN);
+                break;
+            case SCSI_WRITE12:
+                SCSI_Write12_Cmd(CBW.bLUN);
+                break;
+            case SCSI_WRITE16:
+                SCSI_Write16_Cmd(CBW.bLUN);
+                break;
+            case SCSI_VERIFY12:
+                SCSI_Verify12_Cmd(CBW.bLUN);
+                break;
+            case SCSI_VERIFY16:
+                SCSI_Verify16_Cmd(CBW.bLUN);
+                break;
+
+            default:
+            {
+                Bot_Abort(BOTH_DIR);
+                Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_COMMAND);
+                Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+            }
+            }
+        }
+    }
+    else
+    {
+        //无效的CBW
+        /* Invalid CBW */
+        Bot_Abort(BOTH_DIR);
+        Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_COMMAND);
+        Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
+    }
+}
+
+/*******************************************************************************
+* Function Name  : Transfer_Data_Request
+* Description    : Send the request response to the PC HOST.
+* Input          : uint8_t* Data_Address : point to the data to transfer.
+*                  uint16_t Data_Length : the nember of Bytes to transfer.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Transfer_Data_Request(uint8_t* Data_Pointer, uint16_t Data_Len)
+{
+    UserToPMABufferCopy(Data_Pointer, ENDP1_TXADDR, Data_Len);
+
+    SetEPTxCount(ENDP1, Data_Len);
+    SetEPTxStatus(ENDP1, EP_TX_VALID);
+    Bot_State = BOT_DATA_IN_LAST;
+    CSW.dDataResidue -= Data_Len;
+    CSW.bStatus = CSW_CMD_PASSED;
+}
+
+/*******************************************************************************
+* Function Name  : Set_CSW
+* Description    : Set the SCW with the needed fields.
+* Input          : uint8_t CSW_Status this filed can be CSW_CMD_PASSED,CSW_CMD_FAILED,
+*                  or CSW_PHASE_ERROR.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Set_CSW (uint8_t CSW_Status, uint8_t Send_Permission)
+{
+    CSW.dSignature = BOT_CSW_SIGNATURE;
+    CSW.bStatus = CSW_Status;
+
+    UserToPMABufferCopy(((uint8_t *)& CSW), ENDP1_TXADDR, CSW_DATA_LENGTH);
+
+    SetEPTxCount(ENDP1, CSW_DATA_LENGTH);
+    Bot_State = BOT_ERROR;
+    if (Send_Permission)
+    {
+        Bot_State = BOT_CSW_Send;
+        SetEPTxStatus(ENDP1, EP_TX_VALID);
+    }
+
+}
+
+/*******************************************************************************
+* Function Name  : Bot_Abort
+* Description    : Stall the needed Endpoint according to the selected direction.
+* Input          : Endpoint direction IN, OUT or both directions
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Bot_Abort(uint8_t Direction)
+{
+    switch (Direction)
+    {
+    case DIR_IN :
+        SetEPTxStatus(ENDP1, EP_TX_STALL);
+        break;
+    case DIR_OUT :
+        SetEPRxStatus(ENDP2, EP_RX_STALL);
+        break;
+    case BOTH_DIR :
+        SetEPTxStatus(ENDP1, EP_TX_STALL);
+        SetEPRxStatus(ENDP2, EP_RX_STALL);
+        break;
+    default:
+        break;
+    }
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 161 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/usb_desc.c

@@ -0,0 +1,161 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_desc.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : Descriptors for Mass Storage Device
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_desc.h"
+
+const uint8_t MASS_DeviceDescriptor[MASS_SIZ_DEVICE_DESC] =
+{
+    0x12,   /* bLength  */
+    0x01,   /* bDescriptorType */
+    0x00,   /* bcdUSB, version 2.00 */
+    0x02,
+    0x00,   /* bDeviceClass : each interface define the device class */
+    0x00,   /* bDeviceSubClass */
+    0x00,   /* bDeviceProtocol */
+    0x40,   /* bMaxPacketSize0 0x40 = 64 */
+    0x83,   /* idVendor     (0483) */
+    0x04,
+    0x20,   /* idProduct */
+    0x57,
+    0x00,   /* bcdDevice 2.00*/
+    0x02,
+    1,              /* index of string Manufacturer  */
+    /**/
+    2,              /* index of string descriptor of product*/
+    /* */
+    3,              /* */
+    /* */
+    /* */
+    0x01    /*bNumConfigurations */
+};
+
+const uint8_t MASS_ConfigDescriptor[MASS_SIZ_CONFIG_DESC] =
+{
+
+    0x09,   /* bLength: Configuation Descriptor size */
+    0x02,   /* bDescriptorType: Configuration */
+    MASS_SIZ_CONFIG_DESC,
+
+    0x00,
+    0x01,   /* bNumInterfaces: 1 interface */
+    0x01,   /* bConfigurationValue: */
+    /*      Configuration value */
+    0x00,   /* iConfiguration: */
+    /*      Index of string descriptor */
+    /*      describing the configuration */
+    0xC0,   /* bmAttributes: */
+    /*      bus powered */
+    100,   /* MaxPower 100 mA */
+
+    /*****************接口描述符*******************/
+//bLength字段。接口描述符的长度为9字节。
+    0x09,
+
+//bDescriptorType字段。接口描述符的编号为0x04。
+    0x04,
+
+//bInterfaceNumber字段。该接口的编号,第一个接口,编号为0。
+    0x00,
+
+//bAlternateSetting字段。该接口的备用编号,为0。
+    0x00,
+
+//bNumEndpoints字段。非0端点的数目。该接口有2个批量端点
+    0x02,
+
+//bInterfaceClass字段。该接口所使用的类。大容量存储设备接口类的代码为0x08。
+    0x08,
+
+//bInterfaceSubClass字段。该接口所使用的子类。SCSI透明命令集的子类代码为0x06。
+    0x06,
+
+//bInterfaceProtocol字段。协议为仅批量传输,代码为0x50。
+    0x50,
+
+//iConfiguration字段。该接口的字符串索引值。
+    4,          /* iInterface: */
+
+    /*************标准批量数据输入端点描述符****************/
+    /* 18 */
+    0x07,   /*Endpoint descriptor length = 7*/
+    0x05,   /*Endpoint descriptor type *///bDescriptorType字段。端点描述符编号为0x05。
+
+//bEndpointAddress字段。端点的地址。我们使用D12的输入端点2。
+//D7位表示数据方向,输入端点D7为1。所以输入端点2的地址为0x82。
+    0x81,   /*Endpoint address (IN, address 1) */
+
+    //bmAttributes字段。D1~D0为端点传输类型选择。
+//该端点为批端点。批量端点的编号为2。其它位保留为0。
+    0x02,   /*Bulk endpoint type */
+
+    0x40,   /*Maximum packet size (64 bytes) */
+    0x00,
+    0x00,   /*Polling interval in milliseconds */
+
+    /*************标准批量数据输出端点描述符****************/
+    /* 25 */
+    0x07,   /*Endpoint descriptor length = 7 */
+    0x05,   /*Endpoint descriptor type */
+    0x02,   /*Endpoint address (OUT, address 2) */
+    0x02,   /*Bulk endpoint type */
+    0x40,   /*Maximum packet size (64 bytes) */
+    0x00,
+    0x00     /*Polling interval in milliseconds*/
+    /*32*/
+};
+const uint8_t MASS_StringLangID[MASS_SIZ_STRING_LANGID] =
+{
+    MASS_SIZ_STRING_LANGID,
+    0x03,
+    0x09,
+    0x04
+}
+;      /* LangID = 0x0409: U.S. English */
+const uint8_t MASS_StringVendor[MASS_SIZ_STRING_VENDOR] =
+{
+    MASS_SIZ_STRING_VENDOR, /* Size of manufaturer string */
+    0x03,           /* bDescriptorType = String descriptor */
+    /* Manufacturer: "STMicroelectronics" */
+    'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
+    'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
+    'c', 0, 's', 0
+};
+const uint8_t MASS_StringProduct[MASS_SIZ_STRING_PRODUCT] =
+{
+    MASS_SIZ_STRING_PRODUCT,
+    0x03,
+    /* Product name: "STM32F10x:USB Mass Storage" */
+    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'M', 0, 'a', 0, 's', 0,
+    's', 0, ' ', 0, 'S', 0, 't', 0, 'o', 0, 'r', 0, 'a', 0, 'g', 0, 'e', 0
+
+};
+
+uint8_t MASS_StringSerial[MASS_SIZ_STRING_SERIAL] =
+{
+    MASS_SIZ_STRING_SERIAL,
+    0x03,
+    /* STM3210 */
+    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
+};
+const uint8_t MASS_StringInterface[MASS_SIZ_STRING_INTERFACE] =
+{
+    MASS_SIZ_STRING_INTERFACE,
+    0x03,
+    /* Interface 0: "ST Mass" */
+    'S', 0, 'T', 0, ' ', 0, 'M', 0, 'a', 0, 's', 0, 's', 0
+};
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 55 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/usb_endp.c

@@ -0,0 +1,55 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_endp.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : Endpoint routines
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_bot.h"
+#include "usb_istr.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : EP1_IN_Callback
+* Description    : EP1 IN Callback Routine
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void EP1_IN_Callback(void)
+{
+    // IN
+    Mass_Storage_In();
+}
+
+/*******************************************************************************
+* Function Name  : EP2_OUT_Callback.
+* Description    : EP2 OUT Callback Routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void EP2_OUT_Callback(void)
+{
+    // OUT 收到主机发来的数据或命令
+    Mass_Storage_Out();
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 174 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/usb_istr.c

@@ -0,0 +1,174 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_istr.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : ISTR events interrupt service routines
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+#include "usb_type.h"
+#include "usb_regs.h"
+#include "usb_pwr.h"
+#include "usb_istr.h"
+#include "usb_init.h"
+#include "usb_int.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 */
+
+/* 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          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void USB_Istr(void)
+{
+
+  wIstr = _GetISTR();
+
+#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)
+  {
+    _SetISTR((uint16_t)CLR_ESOF);
+    /* resume handling timing is made with ESOFs */
+    Resume(RESUME_ESOF); /* request without change of the machine state */
+
+#ifdef ESOF_CALLBACK
+    ESOF_Callback();
+#endif
+  }
+#endif
+  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#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
+} /* USB_Istr */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 39 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/usb_main.c

@@ -0,0 +1,39 @@
+#include "stm32f10x.h"
+#include "usb_lib.h"
+#include "usb_istr.h"
+#include "hw_config.h"
+#include "usb_pwr.h"
+
+#include "rtthread.h"
+
+extern uint32_t Mass_Memory_Size[2];
+extern uint32_t Mass_Block_Size[2];
+extern uint32_t Mass_Block_Count[2];
+extern rt_device_t dev_sdio;
+
+#include <finsh.h>
+#include "sdcard.h"
+void USB_cable(void)
+{
+    rt_device_t dev = RT_NULL;
+    SD_CardInfo * sdio_info = RT_NULL;
+    dev = rt_device_find("sd0");
+    if(dev != RT_NULL)
+    {
+        dev_sdio = dev;
+        sdio_info = (SD_CardInfo *)dev->private;
+        Mass_Memory_Size[0] = sdio_info->CardCapacity;
+        Mass_Block_Size[0]  = sdio_info->CardBlockSize;
+        Mass_Block_Count[0] = Mass_Memory_Size[0] / Mass_Block_Size[0];
+
+        Set_System();
+        Set_USBClock();
+        USB_Interrupts_Config();
+        USB_Init();
+    }
+    else
+    {
+        rt_kprintf("\r\nNo find the device sd0 !!!!");
+    }
+}
+FINSH_FUNCTION_EXPORT(USB_cable, cable_the_usb);

+ 402 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/usb_prop.c

@@ -0,0 +1,402 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_prop.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : All processing related to Mass Storage Demo
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_desc.h"
+#include "usb_pwr.h"
+#include "usb_bot.h"
+#include "hw_config.h"
+#include "memory.h"
+#include "mass_mal.h"
+#include "usb_prop.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+#ifdef USE_STM3210B_EVAL
+uint32_t Max_Lun = 0;
+#else  //USE_STM3210E_EVAL
+uint32_t Max_Lun = 1;
+#endif
+
+DEVICE Device_Table =
+{
+    EP_NUM,
+    1
+};
+
+DEVICE_PROP Device_Property =
+{
+    MASS_init,
+    MASS_Reset,
+    MASS_Status_In,
+    MASS_Status_Out,
+    MASS_Data_Setup,
+    MASS_NoData_Setup,
+    MASS_Get_Interface_Setting,
+    MASS_GetDeviceDescriptor,
+    MASS_GetConfigDescriptor,
+    MASS_GetStringDescriptor,
+    0,
+    0x40 /*MAX PACKET SIZE*/
+};
+
+USER_STANDARD_REQUESTS User_Standard_Requests =
+{
+    Mass_Storage_GetConfiguration,
+    Mass_Storage_SetConfiguration,
+    Mass_Storage_GetInterface,
+    Mass_Storage_SetInterface,
+    Mass_Storage_GetStatus,
+    Mass_Storage_ClearFeature,
+    Mass_Storage_SetEndPointFeature,
+    Mass_Storage_SetDeviceFeature,
+    Mass_Storage_SetDeviceAddress
+};
+
+ONE_DESCRIPTOR Device_Descriptor =
+{
+    (uint8_t*)MASS_DeviceDescriptor,
+    MASS_SIZ_DEVICE_DESC
+};
+
+ONE_DESCRIPTOR Config_Descriptor =
+{
+    (uint8_t*)MASS_ConfigDescriptor,
+    MASS_SIZ_CONFIG_DESC
+};
+
+ONE_DESCRIPTOR String_Descriptor[5] =
+{
+    {(uint8_t*)MASS_StringLangID, MASS_SIZ_STRING_LANGID},
+    {(uint8_t*)MASS_StringVendor, MASS_SIZ_STRING_VENDOR},
+    {(uint8_t*)MASS_StringProduct, MASS_SIZ_STRING_PRODUCT},
+    {(uint8_t*)MASS_StringSerial, MASS_SIZ_STRING_SERIAL},
+    {(uint8_t*)MASS_StringInterface, MASS_SIZ_STRING_INTERFACE},
+};
+
+/* Extern variables ----------------------------------------------------------*/
+extern unsigned char Bot_State;
+extern Bulk_Only_CBW CBW;
+
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+* Function Name  : MASS_init
+* Description    : Mass Storage init routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void MASS_init()
+{
+    /* Update the serial number string descriptor with the data from the unique
+    ID*/
+    Get_SerialNum();
+
+    pInformation->Current_Configuration = 0;
+
+    /* Connect the device */
+    PowerOn();
+
+    /* USB interrupts initialization */
+    /* clear pending interrupts */
+    _SetISTR(0);
+    wInterrupt_Mask = IMR_MSK;
+    /* set interrupts mask */
+    _SetCNTR(wInterrupt_Mask);
+
+    bDeviceState = UNCONNECTED;
+}
+
+/*******************************************************************************
+* Function Name  : MASS_Reset
+* Description    : Mass Storage reset routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void MASS_Reset()
+{
+    /* Set the device as not configured */
+    Device_Info.Current_Configuration = 0;
+
+    /* Current Feature initialization */
+    pInformation->Current_Feature = MASS_ConfigDescriptor[7];
+
+    SetBTABLE(BTABLE_ADDRESS);
+
+    /* Initialize Endpoint 0 */
+    SetEPType(ENDP0, EP_CONTROL);
+    SetEPTxStatus(ENDP0, EP_TX_NAK);
+    SetEPRxAddr(ENDP0, ENDP0_RXADDR);
+    SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
+    SetEPTxAddr(ENDP0, ENDP0_TXADDR);
+    Clear_Status_Out(ENDP0);
+    SetEPRxValid(ENDP0);
+
+    /* Initialize Endpoint 1 */
+    SetEPType(ENDP1, EP_BULK);
+    SetEPTxAddr(ENDP1, ENDP1_TXADDR);
+    SetEPTxStatus(ENDP1, EP_TX_NAK);
+    SetEPRxStatus(ENDP1, EP_RX_DIS);
+
+    /* Initialize Endpoint 2 */
+    SetEPType(ENDP2, EP_BULK);
+    SetEPRxAddr(ENDP2, ENDP2_RXADDR);
+    SetEPRxCount(ENDP2, Device_Property.MaxPacketSize);
+    SetEPRxStatus(ENDP2, EP_RX_VALID);
+    SetEPTxStatus(ENDP2, EP_TX_DIS);
+
+
+    SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
+    SetEPRxValid(ENDP0);
+
+    /* Set the device to response on default address */
+    SetDeviceAddress(0);
+
+    bDeviceState = ATTACHED;
+
+    CBW.dSignature = BOT_CBW_SIGNATURE;
+    Bot_State = BOT_IDLE;
+    //USB_NotConfigured_LED();
+}
+
+/*******************************************************************************
+* Function Name  : Mass_Storage_SetConfiguration
+* Description    : Handle the SetConfiguration request.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Mass_Storage_SetConfiguration(void)
+{
+    if (pInformation->Current_Configuration != 0)
+    {
+        /* Device configured */
+        bDeviceState = CONFIGURED;
+
+        ClearDTOG_TX(ENDP1);
+        ClearDTOG_RX(ENDP2);
+        Bot_State = BOT_IDLE; /* set the Bot state machine to the IDLE state */
+    }
+}
+
+/*******************************************************************************
+* Function Name  : Mass_Storage_ClearFeature
+* Description    : Handle the ClearFeature request.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Mass_Storage_ClearFeature(void)
+{
+    /* when the host send a CBW with invalid signature or invalid length the two
+       Endpoints (IN & OUT) shall stall until receiving a Mass Storage Reset     */
+    if (CBW.dSignature != BOT_CBW_SIGNATURE)
+        Bot_Abort(BOTH_DIR);
+}
+
+/*******************************************************************************
+* Function Name  : Mass_Storage_SetConfiguration.
+* Description    : Udpade the device state to addressed.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Mass_Storage_SetDeviceAddress (void)
+{
+    bDeviceState = ADDRESSED;
+}
+/*******************************************************************************
+* Function Name  : MASS_Status_In
+* Description    : Mass Storage Status IN routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void MASS_Status_In(void)
+{
+    return;
+}
+
+/*******************************************************************************
+* Function Name  : MASS_Status_Out
+* Description    : Mass Storage Status OUT routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void MASS_Status_Out(void)
+{
+    return;
+}
+
+/*******************************************************************************
+* Function Name  : MASS_Data_Setup.
+* Description    : Handle the data class specific requests..
+* Input          : RequestNo.
+* Output         : None.
+* Return         : RESULT.
+*******************************************************************************/
+RESULT MASS_Data_Setup(uint8_t RequestNo)
+{
+    uint8_t    *(*CopyRoutine)(uint16_t);
+
+    //print("MASS_Data_Setup");
+    CopyRoutine = NULL;
+    if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+            && (RequestNo == GET_MAX_LUN) && (pInformation->USBwValue == 0)
+            && (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x01))
+    {
+        //print(" Get_Max_Lun\r\n");
+        CopyRoutine = Get_Max_Lun;
+    }
+    else
+    {
+        return USB_UNSUPPORT;
+    }
+
+    if (CopyRoutine == NULL)
+    {
+        return USB_UNSUPPORT;
+    }
+
+    pInformation->Ctrl_Info.CopyData = CopyRoutine;
+    pInformation->Ctrl_Info.Usb_wOffset = 0;
+    (*CopyRoutine)(0);
+
+    return USB_SUCCESS;
+
+}
+
+/*******************************************************************************
+* Function Name  : MASS_NoData_Setup.
+* Description    : Handle the no data class specific requests.
+* Input          : RequestNo.
+* Output         : None.
+* Return         : RESULT.
+*******************************************************************************/
+RESULT MASS_NoData_Setup(uint8_t RequestNo)
+{
+    if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+            && (RequestNo == MASS_STORAGE_RESET) && (pInformation->USBwValue == 0)
+            && (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x00))
+    {
+        /* Initialize Endpoint 1 */
+        ClearDTOG_TX(ENDP1);
+
+        /* Initialize Endpoint 2 */
+        ClearDTOG_RX(ENDP2);
+
+        /*intialise the CBW signature to enable the clear feature*/
+        CBW.dSignature = BOT_CBW_SIGNATURE;
+        Bot_State = BOT_IDLE;
+
+        return USB_SUCCESS;
+    }
+    return USB_UNSUPPORT;
+}
+
+/*******************************************************************************
+* Function Name  : MASS_Get_Interface_Setting
+* Description    : Test the interface and the alternate setting according to the
+*                  supported one.
+* Input          : uint8_t Interface, uint8_t AlternateSetting.
+* Output         : None.
+* Return         : RESULT.
+*******************************************************************************/
+RESULT MASS_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
+{
+    if (AlternateSetting > 0)
+    {
+        return USB_UNSUPPORT;/* in this application we don't have AlternateSetting*/
+    }
+    else if (Interface > 0)
+    {
+        return USB_UNSUPPORT;/*in this application we have only 1 interfaces*/
+    }
+    return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : MASS_GetDeviceDescriptor
+* Description    : Get the device descriptor.
+* Input          : uint16_t Length.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+uint8_t *MASS_GetDeviceDescriptor(uint16_t Length)
+{
+    return Standard_GetDescriptorData(Length, &Device_Descriptor );
+}
+
+/*******************************************************************************
+* Function Name  : MASS_GetConfigDescriptor
+* Description    : Get the configuration descriptor.
+* Input          : uint16_t Length.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+uint8_t *MASS_GetConfigDescriptor(uint16_t Length)
+{
+    return Standard_GetDescriptorData(Length, &Config_Descriptor );
+}
+
+/*******************************************************************************
+* Function Name  : MASS_GetStringDescriptor
+* Description    : Get the string descriptors according to the needed index.
+* Input          : uint16_t Length.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+uint8_t *MASS_GetStringDescriptor(uint16_t Length)
+{
+    uint8_t wValue0 = pInformation->USBwValue0;
+
+    if (wValue0 > 5)
+    {
+        return NULL;
+    }
+    else
+    {
+        return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
+    }
+}
+
+/*******************************************************************************
+* Function Name  : Get_Max_Lun
+* Description    : Handle the Get Max Lun request.
+* Input          : uint16_t Length.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+uint8_t *Get_Max_Lun(uint16_t Length)
+{
+    if (Length == 0)
+    {
+        pInformation->Ctrl_Info.Usb_wLength = LUN_DATA_LENGTH;
+        return 0;
+    }
+    else
+    {
+        return((uint8_t*)(&Max_Lun));
+    }
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 224 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/usb_pwr.c

@@ -0,0 +1,224 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_pwr.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : Connection/disconnection & power management
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+#include "usb_lib.h"
+#include "usb_conf.h"
+#include "usb_pwr.h"
+#include "hw_config.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */
+__IO bool fSuspendEnabled = TRUE;  /* true when suspend is possible */
+
+struct
+{
+  __IO RESUME_STATE eState;
+  __IO uint8_t bESOFcnt;
+}
+ResumeS;
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : PowerOn
+* Description    :
+* Input          : None.
+* Output         : None.
+* Return         : USB_SUCCESS.
+*******************************************************************************/
+RESULT PowerOn(void)
+{
+  uint16_t wRegVal;
+
+  /*** cable plugged-in ? ***/
+  /*while(!CablePluggedIn());*/
+  USB_Cable_Config(ENABLE);
+
+  /*** CNTR_PWDN = 0 ***/
+  wRegVal = CNTR_FRES;
+  _SetCNTR(wRegVal);
+
+  /*** CNTR_FRES = 0 ***/
+  wInterrupt_Mask = 0;
+  _SetCNTR(wInterrupt_Mask);
+  /*** Clear pending interrupts ***/
+  _SetISTR(0);
+  /*** Set interrupt mask ***/
+  wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
+  _SetCNTR(wInterrupt_Mask);
+
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : PowerOff
+* Description    : handles switch-off conditions
+* Input          : None.
+* Output         : None.
+* Return         : USB_SUCCESS.
+*******************************************************************************/
+RESULT PowerOff()
+{
+  /* disable all ints and force USB reset */
+  _SetCNTR(CNTR_FRES);
+  /* clear interrupt status register */
+  _SetISTR(0);
+  /* Disable the Pull-Up*/
+  USB_Cable_Config(DISABLE);
+  /* switch-off device */
+  _SetCNTR(CNTR_FRES + CNTR_PDWN);
+  /* sw variables reset */
+  /* ... */
+
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : Suspend
+* Description    : sets suspend mode operating conditions
+* Input          : None.
+* Output         : None.
+* Return         : USB_SUCCESS.
+*******************************************************************************/
+void Suspend(void)
+{
+  uint16_t wCNTR;
+  /* suspend preparation */
+  /* ... */
+
+  /* macrocell enters suspend mode */
+  wCNTR = _GetCNTR();
+  wCNTR |= CNTR_FSUSP;
+  _SetCNTR(wCNTR);
+
+  /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
+  /* power reduction */
+  /* ... on connected devices */
+
+
+  /* force low-power mode in the macrocell */
+  wCNTR = _GetCNTR();
+  wCNTR |= CNTR_LPMODE;
+  _SetCNTR(wCNTR);
+
+  /* switch-off the clocks */
+  /* ... */
+  Enter_LowPowerMode();
+
+}
+
+/*******************************************************************************
+* Function Name  : Resume_Init
+* Description    : Handles wake-up restoring normal operations
+* Input          : None.
+* Output         : None.
+* Return         : USB_SUCCESS.
+*******************************************************************************/
+void Resume_Init(void)
+{
+  uint16_t wCNTR;
+  /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
+  /* restart the clocks */
+  /* ...  */
+
+  /* CNTR_LPMODE = 0 */
+  wCNTR = _GetCNTR();
+  wCNTR &= (~CNTR_LPMODE);
+  _SetCNTR(wCNTR);
+
+  /* restore full power */
+  /* ... on connected devices */
+  Leave_LowPowerMode();
+
+  /* reset FSUSP bit */
+  _SetCNTR(IMR_MSK);
+
+  /* reverse suspend preparation */
+  /* ... */
+
+}
+
+/*******************************************************************************
+* Function Name  : Resume
+* Description    : This is the state machine handling resume operations and
+*                 timing sequence. The control is based on the Resume structure
+*                 variables and on the ESOF interrupt calling this subroutine
+*                 without changing machine state.
+* Input          : a state machine value (RESUME_STATE)
+*                  RESUME_ESOF doesn't change ResumeS.eState allowing
+*                  decrementing of the ESOF counter in different states.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Resume(RESUME_STATE eResumeSetVal)
+{
+  uint16_t wCNTR;
+
+  if (eResumeSetVal != RESUME_ESOF)
+    ResumeS.eState = eResumeSetVal;
+
+  switch (ResumeS.eState)
+  {
+    case RESUME_EXTERNAL:
+      Resume_Init();
+      ResumeS.eState = RESUME_OFF;
+      break;
+    case RESUME_INTERNAL:
+      Resume_Init();
+      ResumeS.eState = RESUME_START;
+      break;
+    case RESUME_LATER:
+      ResumeS.bESOFcnt = 2;
+      ResumeS.eState = RESUME_WAIT;
+      break;
+    case RESUME_WAIT:
+      ResumeS.bESOFcnt--;
+      if (ResumeS.bESOFcnt == 0)
+        ResumeS.eState = RESUME_START;
+      break;
+    case RESUME_START:
+      wCNTR = _GetCNTR();
+      wCNTR |= CNTR_RESUME;
+      _SetCNTR(wCNTR);
+      ResumeS.eState = RESUME_ON;
+      ResumeS.bESOFcnt = 10;
+      break;
+    case RESUME_ON:
+      ResumeS.bESOFcnt--;
+      if (ResumeS.bESOFcnt == 0)
+      {
+        wCNTR = _GetCNTR();
+        wCNTR &= (~CNTR_RESUME);
+        _SetCNTR(wCNTR);
+        ResumeS.eState = RESUME_OFF;
+      }
+      break;
+    case RESUME_OFF:
+    case RESUME_ESOF:
+    default:
+      ResumeS.eState = RESUME_OFF;
+      break;
+  }
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 433 - 0
bsp/stm32_radio/Libraries/Mass_Storage/src/usb_scsi.c

@@ -0,0 +1,433 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_scsi.c
+* Author             : MCD Application Team
+* Version            : V3.0.1
+* Date               : 04/27/2009
+* Description        : All processing related to the SCSI commands
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* 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 "nand_if.h"
+#include "platform_config.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* External variables --------------------------------------------------------*/
+extern uint8_t Bulk_Data_Buff[BULK_MAX_PACKET_SIZE];  /* 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)
+  {
+      /*address out of range*/
+    if (!(SCSI_Address_Management(CBW.bLUN, SCSI_READ10, LBA, BlockNbr)))
+    {
+      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 2009 STMicroelectronics *****END OF FILE****/

+ 259 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_cal.h

@@ -0,0 +1,259 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otgd_fs_cal.h
+* Author             : STMicroelectronics
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Header of OTG FS Device Core Access Layer interface.
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef __OTG_CORE_H__
+#define __OTG_CORE_H__
+
+#ifdef STM32F10X_CL
+
+#include "stm32f10x.h"
+#include "usb_type.h"
+
+#if defined ( __CC_ARM   )
+  #define __packed        __packed                     /*!< packing keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+  #define __packed        __packed                     /*!< packing keyword for IAR Compiler */
+
+#elif defined   (  __GNUC__  )
+  #define __packed        __attribute__ ((__packed__)) /*!< packing keyword for GNU Compiler */
+
+#endif /* __CC_ARM */
+
+/*******************************************************************************
+                                define and types
+*******************************************************************************/
+
+#define DEVICE_MODE_ENABLED
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+
+#define DEV_EP_TX_DIS       0x0000
+#define DEV_EP_TX_STALL     0x0010
+#define DEV_EP_TX_NAK       0x0020
+#define DEV_EP_TX_VALID     0x0030
+ 
+#define DEV_EP_RX_DIS       0x0000
+#define DEV_EP_RX_STALL     0x1000
+#define DEV_EP_RX_NAK       0x2000
+#define DEV_EP_RX_VALID     0x3000
+
+/*****************          GLOBAL DEFINES          ***************************/
+
+#define GAHBCFG_TXFEMPTYLVL_EMPTY              1
+#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY          0
+
+#define GAHBCFG_GLBINT_ENABLE                  1
+#define GAHBCFG_INT_DMA_BURST_SINGLE           0
+#define GAHBCFG_INT_DMA_BURST_INCR             1
+#define GAHBCFG_INT_DMA_BURST_INCR4            3
+#define GAHBCFG_INT_DMA_BURST_INCR8            5
+#define GAHBCFG_INT_DMA_BURST_INCR16           7
+#define GAHBCFG_DMAENABLE                      1
+#define GAHBCFG_TXFEMPTYLVL_EMPTY              1
+#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY          0
+
+#define GRXSTS_PKTSTS_IN                       2
+#define GRXSTS_PKTSTS_IN_XFER_COMP             3
+#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR          5
+#define GRXSTS_PKTSTS_CH_HALTED                7
+
+#define DEVICE_MODE                            0
+#define HOST_MODE                              1
+
+/*****************           DEVICE DEFINES         ***************************/
+
+#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ     0
+#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ     1
+#define DSTS_ENUMSPD_LS_PHY_6MHZ               2
+#define DSTS_ENUMSPD_FS_PHY_48MHZ              3
+
+#define DCFG_FRAME_INTERVAL_80                 0
+#define DCFG_FRAME_INTERVAL_85                 1
+#define DCFG_FRAME_INTERVAL_90                 2
+#define DCFG_FRAME_INTERVAL_95                 3
+
+#define DEP0CTL_MPS_64                         0
+#define DEP0CTL_MPS_32                         1
+#define DEP0CTL_MPS_16                         2
+#define DEP0CTL_MPS_8                          3
+
+#define EP_SPEED_LOW                           0
+#define EP_SPEED_FULL                          1
+#define EP_SPEED_HIGH                          2
+
+#define EP_TYPE_CTRL                           0
+#define EP_TYPE_ISOC                           1
+#define EP_TYPE_BULK                           2
+#define EP_TYPE_INTR                           3
+
+#define STS_GOUT_NAK                           1
+#define STS_DATA_UPDT                          2
+#define STS_XFER_COMP                          3
+#define STS_SETUP_COMP                         4
+#define STS_SETUP_UPDT                         6
+
+
+
+
+typedef enum {
+
+  USB_OTG_OK,
+  USB_OTG_FAIL
+
+}USB_OTG_Status;
+
+typedef struct USB_OTG_hc
+{
+  uint8_t       hc_num;
+  uint8_t       dev_addr ;
+  uint8_t        ep_num;
+  uint8_t       ep_is_in;
+  uint8_t       speed;
+  uint8_t       ep_type;
+  uint16_t       max_packet;
+  uint8_t       data_pid;
+  uint16_t       multi_count;
+  uint8_t        *xfer_buff;
+  uint32_t       xfer_len;
+}
+USB_OTG_HC , *PUSB_OTG_HC;
+
+typedef struct USB_OTG_ep
+{
+  uint8_t        num;
+  uint8_t        is_in;
+  uint32_t       tx_fifo_num;
+  uint32_t       type;
+  uint8_t        data_pid_start;
+  uint8_t        even_odd_frame;
+  uint32_t       maxpacket;
+  uint8_t        *xfer_buff;
+  uint32_t       xfer_len;
+  uint32_t       xfer_count;
+}
+
+USB_OTG_EP , *PUSB_OTG_EP;
+
+/********************************************************************************
+                                      MACRO'S
+********************************************************************************/
+
+#define CLEAR_IN_EP_INTR(epnum,intr) \
+  diepint.d32=0; \
+  diepint.b.intr = 1; \
+  WRITE_REG32(&core_regs.inep_regs[epnum]->dev_in_ep_int,diepint.d32);
+
+#define CLEAR_OUT_EP_INTR(epnum,intr) \
+  doepint.d32=0; \
+  doepint.b.intr = 1; \
+  WRITE_REG32(&core_regs.outep_regs[epnum]->dev_out_ep_int,doepint.d32);
+
+
+#define READ_REG32(reg)  (*(__IO uint32_t *)reg)
+
+#define WRITE_REG32(reg,value) (*(__IO uint32_t *)reg = value)
+
+#define MODIFY_REG32(reg,clear_mask,set_mask) \
+  WRITE_REG32(reg, (((READ_REG32(reg)) & ~clear_mask) | set_mask ) )
+
+
+#define uDELAY(usec)  udelay(usec)
+#define mDELAY(msec)  uDELAY(msec * 1000)
+
+#define _OTGD_FS_GATE_PHYCLK     *(__IO uint32_t*)(0x50000E00) = 0x03
+#define _OTGD_FS_UNGATE_PHYCLK   *(__IO uint32_t*)(0x50000E00) = 0x00
+
+/*******************************************************************************
+                   this can be changed for real time base
+*******************************************************************************/
+static void udelay (const uint32_t usec)
+{
+  uint32_t count = 0;
+  const uint32_t utime = usec * 10;
+  do
+  {
+    if ( ++count > utime )
+    {
+      return ;
+    }
+  }
+  while (1);
+}
+/********************************************************************************
+                     EXPORTED FUNCTIONS FROM THE OTGD_FS_CAL LAYER
+********************************************************************************/
+USB_OTG_Status  OTGD_FS_CoreInit(void);
+USB_OTG_Status  OTGD_FS_SetAddress(uint32_t BaseAddress);
+USB_OTG_Status  OTGD_FS_EnableGlobalInt(void);
+USB_OTG_Status  OTGD_FS_DisableGlobalInt(void);
+
+USB_OTG_Status  USB_OTG_CoreInitHost(void);
+USB_OTG_Status  USB_OTG_EnableHostInt(void);
+USB_OTG_Status  USB_OTG_DisableHostInt(void);
+
+void*  OTGD_FS_ReadPacket(uint8_t *dest, uint16_t bytes);
+USB_OTG_Status OTGD_FS_WritePacket(uint8_t *src, uint8_t ch_ep_num, uint16_t bytes);
+
+USB_OTG_Status  USB_OTG_HcInit(USB_OTG_HC *hc);
+USB_OTG_Status  USB_OTG_StartXfer(USB_OTG_HC *hc);
+
+uint32_t USB_OTG_ResetPort( void);
+
+uint32_t USB_OTG_ReadHPRT0(void);
+uint32_t OTGD_FS_ReadDevAllInEPItr(void);
+uint32_t OTGD_FS_ReadCoreItr(void);
+uint32_t OTGD_FS_ReadOtgItr (void);
+uint32_t USB_OTG_ReadHostAllChannels_intr (void);
+uint8_t IsHostMode(void);
+uint8_t IsDeviceMode(void);
+USB_OTG_Status USB_OTG_HcInit(USB_OTG_HC *hc);
+USB_OTG_Status USB_OTG_HcHalt(uint8_t hc_num);
+
+USB_OTG_Status  OTGD_FS_FlushTxFifo (uint32_t num);
+USB_OTG_Status  OTGD_FS_FlushRxFifo (void);
+USB_OTG_Status  OTGD_FS_SetHostMode (void);
+
+USB_OTG_Status OTGD_FS_PhyInit(void);
+USB_OTG_Status USB_OTG_HcStartXfer(USB_OTG_HC *hc);
+
+USB_OTG_Status OTGD_FS_CoreInitDev (void);
+USB_OTG_Status  OTGD_FS_EnableDevInt(void);
+USB_OTG_Status  OTGD_FS_EP0Activate(void);
+USB_OTG_Status  OTGD_FS_EPActivate(USB_OTG_EP *ep);
+USB_OTG_Status  OTGD_FS_EPDeactivate(USB_OTG_EP *ep);
+
+USB_OTG_Status  OTGD_FS_EPStartXfer(USB_OTG_EP *ep);
+USB_OTG_Status OTGD_FS_EP0StartXfer(USB_OTG_EP *ep);
+
+USB_OTG_Status  OTGD_FS_EPSetStall(USB_OTG_EP *ep);
+USB_OTG_Status  OTGD_FS_EPClearStall(USB_OTG_EP *ep);
+uint32_t OTGD_FS_ReadDevAllOutEp_itr(void);
+uint32_t OTGD_FS_ReadDevOutEP_itr(USB_OTG_EP *ep);
+uint32_t OTGD_FS_ReadDevAllInEPItr(void);
+
+
+uint32_t OTGD_FS_Dev_GetEPStatus(USB_OTG_EP *ep);
+void OTGD_FS_Dev_SetEPStatus(USB_OTG_EP *ep, uint32_t Status);
+void OTGD_FS_Dev_SetRemoteWakeup(void);
+void OTGD_FS_Dev_ResetRemoteWakeup(void);
+
+#endif /* STM32F10X_CL */
+
+#endif
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 121 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_dev.h

@@ -0,0 +1,121 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otg_dev.h
+* Author             : STMicroelectronics
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : linking defines
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __OTG_DEV_H__
+#define __OTG_DEV_H__
+
+#ifdef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+#include "usb_type.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* Endpoint types */
+#define OTG_DEV_EP_TYPE_CONTROL       0
+#define OTG_DEV_EP_TYPE_ISOC          1
+#define OTG_DEV_EP_TYPE_BULK          2
+#define OTG_DEV_EP_TYPE_INT           3
+
+/* Endpoint Addresses (w/direction) */
+#define EP0_OUT                    0x00  
+#define EP0_IN                     0x80  
+#define EP1_OUT                    0x01  
+#define EP1_IN                     0x81  
+#define EP2_OUT                    0x02  
+#define EP2_IN                     0x82  
+#define EP3_OUT                    0x03  
+#define EP3_IN                     0x83  
+
+
+/*-*-*-*-*-*-*-*-*-* Replace the usb_regs.h defines -*-*-*-*-*-*-*-*-*-*-*-*-*/
+/* endpoints enumeration */
+#define ENDP0   ((uint8_t)0)
+#define ENDP1   ((uint8_t)1)
+#define ENDP2   ((uint8_t)2)
+#define ENDP3   ((uint8_t)3)
+#define ENDP4   ((uint8_t)4)
+#define ENDP5   ((uint8_t)5)
+#define ENDP6   ((uint8_t)6)
+#define ENDP7   ((uint8_t)7)
+
+/* EP Transmit status defines */
+#define EP_TX_DIS              DEV_EP_TX_DIS)  /* EndPoint TX DISabled */
+#define EP_TX_STALL            DEV_EP_TX_STALL /* EndPoint TX STALLed */
+#define EP_TX_NAK              DEV_EP_TX_NAK   /* EndPoint TX NAKed */
+#define EP_TX_VALID            DEV_EP_TX_VALID /* EndPoint TX VALID */
+
+/* EP Transmit status defines */
+#define EP_RX_DIS              DEV_EP_RX_DIS   /* EndPoint RX DISabled */
+#define EP_RX_STALL            DEV_EP_RX_STALL /* EndPoint RX STALLed */
+#define EP_RX_NAK              DEV_EP_RX_NAK   /* EndPoint RX NAKed */
+#define EP_RX_VALID            DEV_EP_RX_VALID /* EndPoint RX VALID */
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+/* Exported macro ------------------------------------------------------------*/
+#define _GetEPTxStatus(bEpNum)        ((uint16_t)OTG_DEV_GetEPTxStatus(bEpNum))
+#define _GetEPRxStatus(bEpNum)        ((uint16_t)OTG_DEV_GetEPRxStatus(bEpNum))
+
+#define _SetEPTxStatus(bEpNum,wState) (OTG_DEV_SetEPTxStatus(bEpNum, wState))
+#define _SetEPRxStatus(bEpNum,wState) (OTG_DEV_SetEPRxStatus(bEpNum, wState))
+
+#define _SetEPTxValid(bEpNum)         (OTG_DEV_SetEPTxStatus(bEpNum, EP_TX_VALID))
+#define _SetEPRxValid(bEpNum)         (OTG_DEV_SetEPRxStatus(bEpNum, EP_RX_VALID))
+
+#define _GetTxStallStatus(bEpNum)     (OTG_DEV_GetEPTxStatus(bEpNum) == EP_TX_STALL)
+#define _GetRxStallStatus(bEpNum)     (OTG_DEV_GetEPRxStatus(bEpNum) == EP_RX_STALL) 
+
+/* Define the callbacks for updating the USB state machine */
+#define OTGD_FS_DEVICE_RESET              Device_Property.Reset()
+
+/* Exported define -----------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+void OTG_DEV_Init(void);
+void OTG_DEV_EP_Init(uint8_t bEpAdd, uint8_t bEpType, uint16_t wEpMaxPackSize);
+
+void OTG_DEV_SetEPRxStatus(uint8_t bEpnum, uint32_t status);
+void OTG_DEV_SetEPTxStatus(uint8_t bEpnum, uint32_t status); 
+uint32_t OTG_DEV_GetEPRxStatus(uint8_t bEpnum); 
+uint32_t OTG_DEV_GetEPTxStatus(uint8_t bEpnum); 
+
+void USB_DevDisconnect(void);
+void USB_DevConnect(void);
+
+
+/*-*-*-*-*-*-*-*-*-* Replace the usb_regs.h prototypes *-*-*-*-*-*-*-*-*-*-*-*/
+void SetEPTxStatus(uint8_t bEpNum, uint16_t wState);
+void SetEPRxStatus(uint8_t bEpNum, uint16_t wState);
+uint16_t GetEPTxStatus(uint8_t bEpNum);
+uint16_t GetEPRxStatus(uint8_t bEpNum);
+void SetEPTxValid(uint8_t bEpNum);
+void SetEPRxValid(uint8_t bEpNum);
+uint16_t GetTxStallStatus(uint8_t bEpNum);
+uint16_t GetRxStallStatus(uint8_t bEpNum);
+void SetEPTxCount(uint8_t bEpNum, uint16_t wCount);
+void SetEPRxCount(uint8_t bEpNum, uint16_t wCount);
+
+uint16_t ToWord(uint8_t, uint8_t);
+uint16_t ByteSwap(uint16_t);
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+#endif /* STM32F10X_CL */
+
+#endif /* __OTG_DEV_H__ */
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 54 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_int.h

@@ -0,0 +1,54 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otgd_fs_int.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Endpoint interrupt's service routines prototypes.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_INT_H
+#define __USB_INT_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#ifdef STM32F10X_CL
+
+/* Interrupt Handlers functions */
+uint32_t OTGD_FS_Handle_ModeMismatch_ISR(void);
+uint32_t OTGD_FS_Handle_Sof_ISR(void);
+uint32_t OTGD_FS_Handle_RxStatusQueueLevel_ISR(void);
+uint32_t OTGD_FS_Handle_NPTxFE_ISR(void);
+uint32_t OTGD_FS_Handle_GInNakEff_ISR(void);
+uint32_t OTGD_FS_Handle_GOutNakEff_ISR(void);
+uint32_t OTGD_FS_Handle_EarlySuspend_ISR(void);
+uint32_t OTGD_FS_Handle_USBSuspend_ISR(void);
+uint32_t OTGD_FS_Handle_UsbReset_ISR(void);
+uint32_t OTGD_FS_Handle_EnumDone_ISR(void);
+uint32_t OTGD_FS_Handle_IsoOutDrop_ISR(void);
+uint32_t OTGD_FS_Handle_EOPF_ISR(void);
+uint32_t OTGD_FS_Handle_EPMismatch_ISR(void);
+uint32_t OTGD_FS_Handle_InEP_ISR(void);
+uint32_t OTGD_FS_Handle_OutEP_ISR(void);
+uint32_t OTGD_FS_Handle_IncomplIsoIn_ISR(void);
+uint32_t OTGD_FS_Handle_IncomplIsoOut_ISR(void);
+uint32_t OTGD_FS_Handle_Wakeup_ISR(void);
+
+#endif /* STM32F10X_CL */
+
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_INT_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 87 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_pcd.h

@@ -0,0 +1,87 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otgd_fs_pcd.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Header file of the High Layer device mode interface and 
+*                      wrapping layer
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __USB_OTG_PCD_H__
+#define __USB_OTG_PCD_H__
+
+#include "otgd_fs_regs.h"
+
+#define MAX_EP0_SIZE                    0x40
+#define MAX_PACKET_SIZE                 0x400
+
+
+#define USB_ENDPOINT_XFER_CONTROL       0
+#define USB_ENDPOINT_XFER_ISOC          1
+#define USB_ENDPOINT_XFER_BULK          2
+#define USB_ENDPOINT_XFER_INT           3
+#define USB_ENDPOINT_XFERTYPE_MASK      3
+
+
+/********************************************************************************
+                              ENUMERATION TYPE
+********************************************************************************/
+enum usb_device_speed {
+  USB_SPEED_UNKNOWN = 0,
+  USB_SPEED_LOW, USB_SPEED_FULL,
+  USB_SPEED_HIGH
+};
+/********************************************************************************
+                              Data structure type
+********************************************************************************/
+typedef struct usb_ep_descriptor
+{
+  uint8_t  bLength;
+  uint8_t  bDescriptorType;
+  uint8_t  bEndpointAddress;
+  uint8_t  bmAttributes;
+  uint16_t wMaxPacketSize;
+  uint8_t  bInterval;
+}
+EP_DESCRIPTOR , *PEP_DESCRIPTOR;
+/********************************************************************************
+                     USBF LAYER UNION AND STRUCTURES
+********************************************************************************/
+typedef struct USB_OTG_USBF
+{
+
+  USB_OTG_EP ep0;
+  uint8_t     ep0state;
+  USB_OTG_EP in_ep[ MAX_TX_FIFOS - 1];
+  USB_OTG_EP out_ep[ MAX_TX_FIFOS - 1];
+}
+USB_OTG_PCD_DEV , *USB_OTG_PCD_PDEV;
+/********************************************************************************
+                     EXPORTED FUNCTION FROM THE USB_OTG LAYER
+********************************************************************************/
+void  OTGD_FS_PCD_Init(void);
+void  OTGD_FS_PCD_DevConnect (void);
+void  OTGD_FS_PCD_DevDisconnect (void);
+void  OTGD_FS_PCD_EP_SetAddress (uint8_t address);
+uint32_t   OTGD_FS_PCD_EP_Open(EP_DESCRIPTOR *epdesc);
+uint32_t   OTGD_FS_PCD_EP_Close  ( uint8_t  ep_addr);
+uint32_t   OTGD_FS_PCD_EP_Read  ( uint8_t  ep_addr, uint8_t  *pbuf, uint32_t   buf_len);
+uint32_t   OTGD_FS_PCD_EP_Write ( uint8_t  ep_addr, uint8_t  *pbuf, uint32_t   buf_len);
+uint32_t   OTGD_FS_PCD_EP_Stall (uint8_t   epnum);
+uint32_t   OTGD_FS_PCD_EP_ClrStall (uint8_t epnum);
+uint32_t   OTGD_FS_PCD_EP_Flush (uint8_t epnum);
+uint32_t   OTGD_FS_PCD_Handle_ISR(void);
+
+USB_OTG_EP* OTGD_FS_PCD_GetOutEP(uint32_t ep_num) ;
+USB_OTG_EP* OTGD_FS_PCD_GetInEP(uint32_t ep_num);
+void OTGD_FS_PCD_EP0_OutStart(void);
+
+#endif
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 1597 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/otgd_fs_regs.h

@@ -0,0 +1,1597 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otgd_fs_regs.h
+* Author             : STMicroelectronics
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : USB OTG IP hardware registers.
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __USB_OTG_REGS_H__
+#define __USB_OTG_REGS_H__
+
+#ifdef STM32F10X_CL
+
+#include "stm32f10x.h"
+#include "usb_type.h"
+
+#define USB_OTG_FS1_BASE_ADDR                0x50000000
+
+#define USB_OTG_CORE_GLOBAL_REGS_OFFSET      0x000
+#define USB_OTG_DEV_GLOBAL_REG_OFFSET        0x800
+#define USB_OTG_DEV_IN_EP_REG_OFFSET         0x900
+#define USB_OTG_EP_REG_OFFSET                0x20
+#define USB_OTG_DEV_OUT_EP_REG_OFFSET        0xB00
+#define USB_OTG_HOST_GLOBAL_REG_OFFSET       0x400
+#define USB_OTG_HOST_PORT_REGS_OFFSET        0x440
+#define USB_OTG_HOST_CHAN_REGS_OFFSET        0x500
+#define USB_OTG_CHAN_REGS_OFFSET             0x20
+#define USB_OTG_PCGCCTL_OFFSET               0xE00
+#define USB_OTG_DATA_FIFO_OFFSET             0x1000
+#define USB_OTG_DATA_FIFO_SIZE               0x1000
+
+#define MAX_PERIO_FIFOS                      8
+#define MAX_TX_FIFOS                         4
+#define MAX_EPS_CHANNELS                     8
+
+#define DEV_NP_TX_FIFO_SIZE                  160
+#define RX_FIFO_SIZE                         160
+#define TX_FIFO_SIZE                         160
+
+/*******************************************************************************
+ * USB_OTG Core registers .
+ * The USB_OTG_core_regs structure defines the size
+ * and relative field offsets for the Core Global registers.
+ ******************************************************************************/
+typedef struct _USB_OTG_common_regs  //000h
+{
+
+  __IO uint32_t otg_ctl;      /* USB_OTG Control and Status Register    000h*/
+  __IO uint32_t otg_int;      /* USB_OTG Interrupt Register             004h*/
+  __IO uint32_t ahb_cfg;      /* Core AHB Configuration Register    008h*/
+  __IO uint32_t usb_cfg;      /* Core USB Configuration Register    00Ch*/
+  __IO uint32_t rst_ctl;      /* Core Reset Register                010h*/
+  __IO uint32_t int_sts;      /* Core Interrupt Register            014h*/
+  __IO uint32_t int_msk;      /* Core Interrupt Mask Register       018h*/
+  __IO uint32_t rx_stsr;      /* Receive Sts Q Read Register        01Ch*/
+  __IO uint32_t rx_stsp;      /* Receive Sts Q Read & POP Register  020h*/
+  __IO uint32_t rx_fifo_siz;  /* Receive FIFO Size Register         024h*/
+  __IO uint32_t np_tx_fifo_siz;   /* Non Periodic Tx FIFO Size Register 028h*/
+  __IO uint32_t np_tx_sts;    /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/
+  __IO uint32_t i2c_ctl;      /* I2C Access Register                030h*/
+  __IO uint32_t phy_vnd_ctl;  /* PHY Vendor Control Register        034h*/
+  __IO uint32_t gpio;         /* General Purpose IO Register        038h*/
+  __IO uint32_t usr_id;       /* User ID Register                   03Ch*/
+  __IO uint32_t snps_id;      /* Synopsys ID Register               040h*/
+  __IO uint32_t hw_cfg1;      /* User HW Config1 Register (RO)      044h*/
+  __IO uint32_t hw_cfg2;      /* User HW Config2 Register (RO)      048h*/
+  __IO uint32_t hw_cfg3;      /* User HW Config3 Register (RO)      04Ch*/
+  __IO uint32_t hw_cfg4;      /* User HW Config4 Register (RO)      050h*/
+  uint32_t  reserved[43];          /* Reserved                      054h-0FFh*/
+  __IO uint32_t host_p_tx_fifo_siz; /* Host Periodic Tx FIFO Size Reg     100h*/
+  __IO uint32_t dev_p_tx_fsiz_dieptxf[15];/* dev Periodic Transmit FIFO */
+
+}
+USB_OTG_common_regs;
+
+/*******************************************************************************
+ * dev Registers
+ * dev Global Registers : Offsets 800h-BFFh
+ * The following structures define the size and relative field offsets
+ * for the dev Mode Registers.
+ * These registers are visible only in dev mode and must not be
+ * accessed in Host mode, as the results are unknown
+ ******************************************************************************/
+typedef struct _USB_OTG_dev_regs // 800h
+{
+
+  __IO uint32_t dev_cfg;         /* dev Configuration Register   800h*/
+  __IO uint32_t dev_ctl;         /* dev Control Register         804h*/
+  __IO uint32_t dev_sts;         /* dev Status Register (RO)     808h*/
+  uint32_t reserved3;         /* Reserved                     80Ch*/
+  __IO uint32_t dev_in_ep_msk;   /* dev IN Endpoint Mask         810h*/
+  __IO uint32_t dev_out_ep_msk;  /* dev OUT Endpoint Mask        814h*/
+  __IO uint32_t dev_all_int;     /* dev All Endpoints Itr Reg    818h*/
+  __IO uint32_t dev_all_int_msk; /* dev All Endpoints Itr Mask   81Ch*/
+  uint32_t  Reserved8;       /* Reserved                     820h*/
+  __IO uint32_t Reserved9;       /* Reserved                     824h*/
+  __IO uint32_t dev_vbus_dis;    /* dev VBUS discharge Register  828h*/
+  __IO uint32_t dev_vbus_pulse;  /* dev VBUS Pulse Register      82Ch*/
+  __IO uint32_t dev_thr_ctl;     /* dev thr                      830h*/
+  __IO uint32_t dev_fifo_empty_msk; /* dev empty msk             834h*/
+
+}
+USB_OTG_dev_regs;
+/*******************************************************************************
+ * dev Logical IN Endpoint-Specific Registers: Offsets 900h-AFCh
+ * There will be one set of endpoint registers per logical endpointimplemented.
+ * These registers are visible only in dev mode and must not be
+ * accessed in Host mode, as the results are unknown
+*******************************************************************************/
+typedef struct _USB_OTG_dev_in_ep_regs
+{
+  __IO uint32_t dev_in_ep_ctl; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/
+  uint32_t reserved04;             /* Reserved                       900h + (ep_num * 20h) + 04h*/
+  __IO uint32_t dev_in_ep_int; /* dev IN Endpoint Itr Reg     900h + (ep_num * 20h) + 08h*/
+  uint32_t reserved0C;             /* Reserved                       900h + (ep_num * 20h) + 0Ch*/
+  __IO uint32_t dev_in_ep_txfer_siz; /* IN Endpoint Txfer Size   900h + (ep_num * 20h) + 10h*/
+  __IO uint32_t dev_in_ep_dma; /* IN Endpoint DMA Address Reg    900h + (ep_num * 20h) + 14h*/
+  __IO uint32_t dev_tx_fifo_sts;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/
+  uint32_t reserved18;             /* Reserved  900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/
+
+}
+USB_OTG_dev_in_ep_regs;
+
+/*******************************************************************************
+ * dev Logical OUT Endpoint-Specific Registers Offsets: B00h-CFCh
+ * There will be one set of endpoint registers per logical endpoint
+ * implemented.
+ * These registers are visible only in dev mode and must not be
+ * accessed in Host mode, as the results are unknown
+******************************************************************************/
+typedef struct _USB_OTG_dev_out_ep_regs
+{
+  __IO uint32_t dev_out_ep_ctl;       /* dev OUT Endpoint Control Reg  B00h + (ep_num * 20h) + 00h*/
+  __IO uint32_t dev_out_ep_frm_nbr;   /* dev OUT Endpoint Frame number B00h + (ep_num * 20h) + 04h*/
+  __IO uint32_t dev_out_ep_int;              /* dev OUT Endpoint Itr Reg      B00h + (ep_num * 20h) + 08h*/
+  uint32_t reserved0C;                    /* Reserved                         B00h + (ep_num * 20h) + 0Ch*/
+  __IO uint32_t dev_out_ep_txfer_siz; /* dev OUT Endpoint Txfer Size   B00h + (ep_num * 20h) + 10h*/
+  __IO uint32_t dev_out_ep_dma;              /* dev OUT Endpoint DMA Address  B00h + (ep_num * 20h) + 14h*/
+  uint32_t reserved18[2];                 /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/
+
+}
+USB_OTG_dev_out_ep_regs;
+/*******************************************************************************
+ * Host Mode Register Structures
+ * The Host Global Registers structure defines the size and relative
+ * field offsets for the Host Mode Global Registers.
+ * Host Global Registers offsets 400h-7FFh.
+*******************************************************************************/
+typedef struct _USB_OTG_host_regs
+{
+  __IO uint32_t host_cfg;             /* Host Configuration Register    400h*/
+  __IO uint32_t host_frm_intrvl;      /* Host Frame Interval Register   404h*/
+  __IO uint32_t host_frm_nbr;         /* Host Frame Nbr/Frame Remaining 408h*/
+  uint32_t reserved40C;                   /* Reserved                       40Ch*/
+  __IO uint32_t host_p_tx_sts;   /* Host Periodic Tx FIFO/ Queue Status 410h*/
+  __IO uint32_t host_all_int;   /* Host All Channels Interrupt Register 414h*/
+  __IO uint32_t host_all_int_msk;   /* Host All Channels Interrupt Mask 418h*/
+
+}
+USB_OTG_host_regs;
+
+/*******************************************************************************
+* Host Channel Specific Registers 500h-5FCh
+*******************************************************************************/
+typedef struct _USB_OTG_hc_regs
+{
+
+  __IO uint32_t hc_char;
+  __IO uint32_t hc_split;
+  __IO uint32_t hc_int;
+  __IO uint32_t hc_int_msk;
+  __IO uint32_t hc_txfer_siz;
+  __IO uint32_t hc_dma;
+  uint32_t reserved[2];
+
+}
+USB_OTG_hc_regs;
+/*******************************************************************************
+ * otg Core registers .
+ * The USB_OTG_core_regs structure defines the size
+ * and relative field offsets for the Core Global registers.
+ ******************************************************************************/
+typedef struct USB_OTG_core_regs  //000h
+{
+  USB_OTG_common_regs         *common_regs;
+  USB_OTG_dev_regs            *dev_regs;
+  USB_OTG_host_regs           *host_regs;
+  USB_OTG_dev_in_ep_regs      *inep_regs[MAX_EPS_CHANNELS];
+  USB_OTG_dev_out_ep_regs     *outep_regs[MAX_EPS_CHANNELS];
+  USB_OTG_hc_regs             *hc_regs[MAX_EPS_CHANNELS];
+  __IO uint32_t                    *hprt0;
+  __IO uint32_t                    *data_fifo[MAX_EPS_CHANNELS];
+  __IO uint32_t                    *pcgcctl;
+
+}
+USB_OTG_CORE_REGS , *pUSB_OTG_CORE_REGS;
+/******************************************************************************/
+
+typedef union _USB_OTG_OTG_ctl_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t sesreqscs :
+    1;
+uint32_t sesreq :
+    1;
+uint32_t reserved2_7 :
+    6;
+uint32_t hstnegscs :
+    1;
+uint32_t hnpreq :
+    1;
+uint32_t hstsethnpen :
+    1;
+uint32_t devhnpen :
+    1;
+uint32_t reserved12_15 :
+    4;
+uint32_t conidsts :
+    1;
+uint32_t reserved17 :
+    1;
+uint32_t asesvld :
+    1;
+uint32_t bsesvld :
+    1;
+uint32_t currmod :
+    1;
+uint32_t reserved21_31 :
+    11;
+  }
+  b;
+} USB_OTG_OTG_ctl_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_OTG_int_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t reserved0_1 :
+    2;
+uint32_t sesenddet :
+    1;
+uint32_t reserved3_7 :
+    5;
+uint32_t sesreqsucstschng :
+    1;
+uint32_t hstnegsucstschng :
+    1;
+uint32_t reserver10_16 :
+    7;
+uint32_t hstnegdet :
+    1;
+uint32_t adevtoutchng :
+    1;
+uint32_t debdone :
+    1;
+uint32_t reserved31_20 :
+    12;
+  }
+  b;
+} USB_OTG_OTG_int_data;
+
+
+/******************************************************************************/
+
+
+typedef union _USB_OTG_ahb_cfg_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t glblintrmsk :
+    1;
+uint32_t hburstlen :
+    4;
+uint32_t dmaenable :
+    1;
+uint32_t reserved :
+    1;
+uint32_t nptxfemplvl_txfemplvl :
+    1;
+uint32_t ptxfemplvl :
+    1;
+uint32_t reserved9_31 :
+    23;
+  }
+  b;
+} USB_OTG_ahb_cfg_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_usb_cfg_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t toutcal :
+    3;
+uint32_t phyif :
+    1;
+uint32_t ulpi_utmi_sel :
+    1;
+uint32_t fsintf :
+    1;
+uint32_t physel :
+    1;
+uint32_t ddrsel :
+    1;
+uint32_t srpcap :
+    1;
+uint32_t hnpcap :
+    1;
+uint32_t usbtrdtim :
+    4;
+uint32_t nptxfrwnden :
+    1;
+uint32_t phylpwrclksel :
+    1;
+uint32_t otgutmifssel :
+    1;
+uint32_t ulpi_fsls :
+    1;
+uint32_t ulpi_auto_res :
+    1;
+uint32_t ulpi_clk_sus_m :
+    1;
+uint32_t ulpi_ext_vbus_drv :
+    1;
+uint32_t ulpi_int_vbus_indicator :
+    1;
+uint32_t term_sel_dl_pulse :
+    1;
+uint32_t reserved :
+    6;
+uint32_t force_host :
+    1;
+uint32_t force_dev :
+    1;
+uint32_t corrupt_tx :
+    1;
+  }
+  b;
+} USB_OTG_usb_cfg_data;
+/******************************************************************************/
+
+typedef union _USB_OTG_rst_ctl_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t csftrst :
+    1;
+uint32_t hsftrst :
+    1;
+uint32_t hstfrm :
+    1;
+uint32_t intknqflsh :
+    1;
+uint32_t rxfflsh :
+    1;
+uint32_t txfflsh :
+    1;
+uint32_t txfnum :
+    5;
+uint32_t reserved11_29 :
+    19;
+uint32_t dmareq :
+    1;
+uint32_t ahbidle :
+    1;
+  }
+  b;
+} USB_OTG_rst_ctl_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_int_msk_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t reserved0 :
+    1;
+uint32_t modemismatch :
+    1;
+uint32_t otgintr :
+    1;
+uint32_t sofintr :
+    1;
+uint32_t rxstsqlvl :
+    1;
+uint32_t nptxfempty :
+    1;
+uint32_t ginnakeff :
+    1;
+uint32_t goutnakeff :
+    1;
+uint32_t reserved8 :
+    1;
+uint32_t i2cintr :
+    1;
+uint32_t erlysuspend :
+    1;
+uint32_t usbsuspend :
+    1;
+uint32_t usbreset :
+    1;
+uint32_t enumdone :
+    1;
+uint32_t isooutdrop :
+    1;
+uint32_t eopframe :
+    1;
+uint32_t reserved16 :
+    1;
+uint32_t epmismatch :
+    1;
+uint32_t inepintr :
+    1;
+uint32_t outepintr :
+    1;
+uint32_t incomplisoin :
+    1;
+uint32_t incomplisoout :
+    1;
+uint32_t reserved22_23 :
+    2;
+uint32_t portintr :
+    1;
+uint32_t hcintr :
+    1;
+uint32_t ptxfempty :
+    1;
+uint32_t reserved27 :
+    1;
+uint32_t conidstschng :
+    1;
+uint32_t disconnect :
+    1;
+uint32_t sessreqintr :
+    1;
+uint32_t wkupintr :
+    1;
+  }
+  b;
+} USB_OTG_int_msk_data;
+
+/******************************************************************************/
+
+
+typedef union _USB_OTG_int_sts_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t curmode :
+    1;
+uint32_t modemismatch :
+    1;
+uint32_t otgintr :
+    1;
+uint32_t sofintr :
+    1;
+uint32_t rxstsqlvl :
+    1;
+uint32_t nptxfempty :
+    1;
+uint32_t ginnakeff :
+    1;
+uint32_t goutnakeff :
+    1;
+uint32_t reserved8 :
+    1;
+uint32_t i2cintr :
+    1;
+uint32_t erlysuspend :
+    1;
+uint32_t usbsuspend :
+    1;
+uint32_t usbreset :
+    1;
+uint32_t enumdone :
+    1;
+uint32_t isooutdrop :
+    1;
+uint32_t eopframe :
+    1;
+uint32_t intokenrx :
+    1;
+uint32_t epmismatch :
+    1;
+uint32_t inepint:
+    1;
+uint32_t outepintr :
+    1;
+uint32_t incomplisoin :
+    1;
+uint32_t incomplisoout :
+    1;
+uint32_t reserved22_23 :
+    2;
+uint32_t portintr :
+    1;
+uint32_t hcintr :
+    1;
+uint32_t ptxfempty :
+    1;
+uint32_t reserved27 :
+    1;
+uint32_t conidstschng :
+    1;
+uint32_t disconnect :
+    1;
+uint32_t sessreqintr :
+    1;
+uint32_t wkupintr :
+    1;
+  }
+  b;
+} USB_OTG_int_sts_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_dev_rx_sts_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t epnum :
+    4;
+uint32_t bcnt :
+    11;
+uint32_t dpid :
+    2;
+uint32_t pktsts :
+    4;
+uint32_t fn :
+    4;
+uint32_t reserved :
+    7;
+  }
+  b;
+} USB_OTG_dev_rx_sts_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_host_rx_sts_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t chnum :
+    4;
+uint32_t bcnt :
+    11;
+uint32_t dpid :
+    2;
+uint32_t pktsts :
+    4;
+uint32_t reserved :
+    11;
+  }
+  b;
+} USB_OTG_host_rx_sts_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_fifo_size_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t startaddr :
+    16;
+uint32_t depth :
+    16;
+  }
+  b;
+} USB_OTG_fifo_size_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_np_tx_sts_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t nptxfspcavail :
+    16;
+uint32_t nptxqspcavail :
+    8;
+uint32_t nptxqtop_terminate :
+    1;
+uint32_t nptxqtop_token :
+    2;
+uint32_t nptxqtop_chnep :
+    4;
+uint32_t reserved :
+    1;
+  }
+  b;
+} USB_OTG_np_tx_sts_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_tx_fifo_sts_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t txfspcavail :
+    16;
+uint32_t reserved :
+    16;
+  }
+  b;
+} USB_OTG_dev_tx_fifo_sts_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_i2c_ctl_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t rwdata :
+    8;
+uint32_t regaddr :
+    8;
+uint32_t addr :
+    7;
+uint32_t i2cen :
+    1;
+uint32_t ack :
+    1;
+uint32_t i2csuspctl :
+    1;
+uint32_t i2cdevaddr :
+    2;
+uint32_t dat_se0:
+    1;
+uint32_t reserved :
+    1;
+uint32_t rw :
+    1;
+uint32_t bsydne :
+    1;
+  }
+  b;
+} USB_OTG_i2c_ctl_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_gpio_data
+{
+
+  uint32_t d32;
+  struct
+  {
+    /* input */
+uint32_t ovrcur :
+    1;
+uint32_t otgid :
+    1;
+uint32_t reserved_in :
+    14;
+    /* Output */
+uint32_t pwdn :
+    1;
+uint32_t i2cifen :
+    1;
+uint32_t vbussensingA :
+    1;
+uint32_t vbussensingB :
+    1;
+uint32_t SOFouten :
+    1;
+uint32_t reserved_out :
+    11;
+  }
+  b;
+} USB_OTG_gpio_data;
+
+
+/******************************************************************************/
+
+typedef union _USB_OTG_hw_cfg1_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t ep_dir0 :
+    2;
+uint32_t ep_dir1 :
+    2;
+uint32_t ep_dir2 :
+    2;
+uint32_t ep_dir3 :
+    2;
+uint32_t ep_dir4 :
+    2;
+uint32_t ep_dir5 :
+    2;
+uint32_t ep_dir6 :
+    2;
+uint32_t ep_dir7 :
+    2;
+uint32_t ep_dir8 :
+    2;
+uint32_t ep_dir9 :
+    2;
+uint32_t ep_dir10 :
+    2;
+uint32_t ep_dir11 :
+    2;
+uint32_t ep_dir12 :
+    2;
+uint32_t ep_dir13 :
+    2;
+uint32_t ep_dir14 :
+    2;
+uint32_t ep_dir15 :
+    2;
+  }
+  b;
+} USB_OTG_hw_cfg1_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_hw_cfg2_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t op_mode :
+    3;
+uint32_t architecture :
+    2;
+uint32_t point2point :
+    1;
+uint32_t hs_phy_type :
+    2;
+uint32_t fs_phy_type :
+    2;
+uint32_t num_dev_ep :
+    4;
+uint32_t num_host_chan :
+    4;
+uint32_t perio_ep_supported :
+    1;
+uint32_t dynamic_fifo :
+    1;
+uint32_t rx_status_q_depth :
+    2;
+uint32_t nonperio_tx_q_depth :
+    2;
+uint32_t host_perio_tx_q_depth :
+    2;
+uint32_t dev_token_q_depth :
+    5;
+uint32_t reserved31 :
+    1;
+  }
+  b;
+} USB_OTG_hw_cfg2_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_hw_cfg3_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t xfer_size_cntr_width :
+    4;
+uint32_t packet_size_cntr_width :
+    3;
+uint32_t otg_func :
+    1;
+uint32_t i2c :
+    1;
+uint32_t vendor_ctrl_if :
+    1;
+uint32_t optional_features :
+    1;
+uint32_t synch_reset_type :
+    1;
+uint32_t ahb_phy_clock_synch :
+    1;
+uint32_t reserved15_13 :
+    3;
+uint32_t dfifo_depth :
+    16;
+  }
+  b;
+} USB_OTG_hw_cfg3_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_hw_cfg4_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t num_dev_perio_in_ep :
+    4;
+uint32_t power_optimiz :
+    1;
+uint32_t min_ahb_freq :
+    9;
+uint32_t utmi_phy_data_width :
+    2;
+uint32_t num_dev_mode_ctrl_ep :
+    4;
+uint32_t iddig_filt_en :
+    1;
+uint32_t vbus_valid_filt_en :
+    1;
+uint32_t a_valid_filt_en :
+    1;
+uint32_t b_valid_filt_en :
+    1;
+uint32_t session_end_filt_en :
+    1;
+uint32_t ded_fifo_en :
+    1;
+uint32_t num_in_eps :
+    4;
+uint32_t reserved31_30 :
+    2;
+  }
+  b;
+} USB_OTG_hw_cfg4_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_dev_cfg_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t devspd :
+    2;
+uint32_t nzstsouthshk :
+    1;
+uint32_t reserved3 :
+    1;
+uint32_t devaddr :
+    7;
+uint32_t perfrint :
+    2;
+uint32_t reserved13_17 :
+    5;
+uint32_t epmscnt :
+    4;
+  }
+  b;
+} USB_OTG_dev_cfg_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_ctl_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t rmtwkupsig :
+    1;
+uint32_t sftdiscon :
+    1;
+uint32_t gnpinnaksts :
+    1;
+uint32_t goutnaksts :
+    1;
+uint32_t tstctl :
+    3;
+uint32_t sgnpinnak :
+    1;
+uint32_t cgnpinnak :
+    1;
+uint32_t sgoutnak :
+    1;
+uint32_t cgoutnak :
+    1;
+uint32_t reserved :
+    21;
+  }
+  b;
+} USB_OTG_dev_ctl_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_dev_sts_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t suspsts :
+    1;
+uint32_t enumspd :
+    2;
+uint32_t errticerr :
+    1;
+uint32_t reserved4_7:
+    4;
+uint32_t soffn :
+    14;
+uint32_t reserved22_31 :
+    10;
+  }
+  b;
+} USB_OTG_dev_sts_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_in_ep_int_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t xfercompl :
+    1;
+uint32_t epdisabled :
+    1;
+uint32_t ahberr :
+    1;
+uint32_t timeout :
+    1;
+uint32_t intktxfemp :
+    1;
+uint32_t intknepmis :
+    1;
+uint32_t inepnakeff :
+    1;
+uint32_t emptyintr :
+    1;
+uint32_t txfifoundrn :
+    1;
+uint32_t reserved08_31 :
+    23;
+  }
+  b;
+} USB_OTG_dev_in_ep_int_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_in_ep_int_data  USB_OTG_dev_in_ep_msk_data;
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_out_ep_int_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t xfercompl :
+    1;
+uint32_t epdisabled :
+    1;
+uint32_t ahberr :
+    1;
+uint32_t setup :
+    1;
+uint32_t reserved04_31 :
+    28;
+  }
+  b;
+} USB_OTG_dev_out_ep_int_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_out_ep_int_data  USB_OTG_dev_out_ep_msk_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_dev_all_int_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t in :
+    16;
+uint32_t out :
+    16;
+  }
+  ep;
+  struct
+  {
+    /** IN Endpoint bits */
+uint32_t inep0  :
+    1;
+uint32_t inep1  :
+    1;
+uint32_t inep2  :
+    1;
+uint32_t inep3  :
+    1;
+uint32_t inep4  :
+    1;
+uint32_t inep5  :
+    1;
+uint32_t inep6  :
+    1;
+uint32_t inep7  :
+    1;
+uint32_t inep8  :
+    1;
+uint32_t inep9  :
+    1;
+uint32_t inep10 :
+    1;
+uint32_t inep11 :
+    1;
+uint32_t inep12 :
+    1;
+uint32_t inep13 :
+    1;
+uint32_t inep14 :
+    1;
+uint32_t inep15 :
+    1;
+    /** OUT Endpoint bits */
+uint32_t outep0  :
+    1;
+uint32_t outep1  :
+    1;
+uint32_t outep2  :
+    1;
+uint32_t outep3  :
+    1;
+uint32_t outep4  :
+    1;
+uint32_t outep5  :
+    1;
+uint32_t outep6  :
+    1;
+uint32_t outep7  :
+    1;
+uint32_t outep8  :
+    1;
+uint32_t outep9  :
+    1;
+uint32_t outep10 :
+    1;
+uint32_t outep11 :
+    1;
+uint32_t outep12 :
+    1;
+uint32_t outep13 :
+    1;
+uint32_t outep14 :
+    1;
+uint32_t outep15 :
+    1;
+  }
+  b;
+} USB_OTG_dev_all_int_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_token_qr1_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t intknwptr :
+    5;
+uint32_t reserved05_06 :
+    2;
+uint32_t wrap_bit :
+    1;
+uint32_t epnums0_5 :
+    24;
+  }
+  b;
+} USB_OTG_token_qr1_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_thr_ctl_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t non_iso_thr_en :
+    1;
+uint32_t iso_thr_en :
+    1;
+uint32_t tx_thr_len :
+    9;
+uint32_t reserved11_15 :
+    5;
+uint32_t rx_thr_en :
+    1;
+uint32_t rx_thr_len :
+    9;
+uint32_t reserved26_31 :
+    6;
+  }
+  b;
+} USB_OTG_dev_thr_ctl_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_dev_ep_ctl_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t mps :
+    11;
+uint32_t nextep :
+    4;
+uint32_t usbactep :
+    1;
+uint32_t dpid :
+    1;
+uint32_t naksts :
+    1;
+uint32_t eptype :
+    2;
+uint32_t snp :
+    1;
+uint32_t stall :
+    1;
+uint32_t txfnum :
+    4;
+uint32_t cnak :
+    1;
+uint32_t snak :
+    1;
+uint32_t setd0pid :
+    1;
+uint32_t setd1pid :
+    1;
+uint32_t epdis :
+    1;
+uint32_t epena :
+    1;
+  }
+  b;
+} USB_OTG_dev_ep_ctl_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_ep_txfer_siz_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t xfersize :
+    19;
+uint32_t pktcnt :
+    10;
+uint32_t mc :
+    2;
+uint32_t reserved :
+    1;
+  }
+  b;
+} USB_OTG_dev_ep_txfer_siz_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_dev_ep_txfer_size0_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t xfersize :
+    7;
+uint32_t reserved7_18 :
+    12;
+uint32_t pktcnt :
+    1;
+uint32_t reserved20_28 :
+    9;
+uint32_t supcnt :
+    2;
+    uint32_t reserved31;
+  }
+  b;
+} USB_OTG_dev_ep_txfer_size0_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_host_cfg_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t fslspclksel :
+    2;
+uint32_t fslssupp :
+    1;
+  }
+  b;
+} USB_OTG_host_cfg_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_Host_frm_intrvl_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t frint :
+    16;
+uint32_t reserved :
+    16;
+  }
+  b;
+} USB_OTG_Host_frm_intrvl_data;
+
+/******************************************************************************/
+#define HFNUM_MAX_FRNUM 0x3FFF
+typedef union _USB_OTG_host_frm_nbr_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t frnum :
+    16;
+uint32_t frrem :
+    16;
+  }
+  b;
+} USB_OTG_host_frm_nbr_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_host_perio_tx_sts_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t ptxfspcavail :
+    16;
+uint32_t ptxqspcavail :
+    8;
+uint32_t ptxqtop_terminate :
+    1;
+uint32_t ptxqtop_token :
+    2;
+uint32_t ptxqtop_chnum :
+    4;
+uint32_t ptxqtop_odd :
+    1;
+  }
+  b;
+} USB_OTG_host_perio_tx_sts_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_hprt0_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t prtconnsts :
+    1;
+uint32_t prtconndet :
+    1;
+uint32_t prtena :
+    1;
+uint32_t prtenchng :
+    1;
+uint32_t prtovrcurract :
+    1;
+uint32_t prtovrcurrchng :
+    1;
+uint32_t prtres :
+    1;
+uint32_t prtsusp :
+    1;
+uint32_t prtrst :
+    1;
+uint32_t reserved9 :
+    1;
+uint32_t prtlnsts :
+    2;
+uint32_t prtpwr :
+    1;
+uint32_t prttstctl :
+    4;
+uint32_t prtspd :
+    2;
+uint32_t reserved19_31 :
+    13;
+  }
+  b;
+} USB_OTG_hprt0_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_host_all_int_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t ch0 :
+    1;
+uint32_t ch1 :
+    1;
+uint32_t ch2 :
+    1;
+uint32_t ch3 :
+    1;
+uint32_t ch4 :
+    1;
+uint32_t ch5 :
+    1;
+uint32_t ch6 :
+    1;
+uint32_t ch7 :
+    1;
+uint32_t ch8 :
+    1;
+uint32_t ch9 :
+    1;
+uint32_t ch10 :
+    1;
+uint32_t ch11 :
+    1;
+uint32_t ch12 :
+    1;
+uint32_t ch13 :
+    1;
+uint32_t ch14 :
+    1;
+uint32_t ch15 :
+    1;
+uint32_t reserved :
+    16;
+  }
+  b;
+
+  struct
+  {
+uint32_t chint :
+    16;
+uint32_t reserved :
+    16;
+  }
+  b2;
+} USB_OTG_host_all_int_data;
+
+
+/******************************************************************************/
+
+typedef union _USB_OTG_host_all_int_msk_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t ch0 :
+    1;
+uint32_t ch1 :
+    1;
+uint32_t ch2 :
+    1;
+uint32_t ch3 :
+    1;
+uint32_t ch4 :
+    1;
+uint32_t ch5 :
+    1;
+uint32_t ch6 :
+    1;
+uint32_t ch7 :
+    1;
+uint32_t ch8 :
+    1;
+uint32_t ch9 :
+    1;
+uint32_t ch10 :
+    1;
+uint32_t ch11 :
+    1;
+uint32_t ch12 :
+    1;
+uint32_t ch13 :
+    1;
+uint32_t ch14 :
+    1;
+uint32_t ch15 :
+    1;
+uint32_t reserved :
+    16;
+  }
+  b;
+
+  struct
+  {
+uint32_t chint :
+    16;
+uint32_t reserved :
+    16;
+  }
+  b2;
+} USB_OTG_host_all_int_msk_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_hc_char_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t mps :
+    11;
+uint32_t epnum :
+    4;
+uint32_t epdir :
+    1;
+uint32_t reserved :
+    1;
+uint32_t lspddev :
+    1;
+uint32_t eptype :
+    2;
+uint32_t multicnt :
+    2;
+uint32_t devaddr :
+    7;
+uint32_t oddfrm :
+    1;
+uint32_t chdis :
+    1;
+uint32_t chen :
+    1;
+  }
+  b;
+} USB_OTG_hc_char_data;
+
+/******************************************************************************/
+typedef union _USB_OTG_hc_splt_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t prtaddr :
+    7;
+uint32_t hubaddr :
+    7;
+uint32_t xactpos :
+    2;
+uint32_t compsplt :
+    1;
+uint32_t reserved :
+    14;
+uint32_t spltena :
+    1;
+  }
+  b;
+} USB_OTG_hc_splt_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_hc_int_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t xfercomp :
+    1;
+uint32_t chhltd :
+    1;
+uint32_t ahberr :
+    1;
+uint32_t stall :
+    1;
+uint32_t nak :
+    1;
+uint32_t ack :
+    1;
+uint32_t nyet :
+    1;
+uint32_t xacterr :
+    1;
+uint32_t bblerr :
+    1;
+uint32_t frmovrun :
+    1;
+uint32_t datatglerr :
+    1;
+uint32_t reserved :
+    21;
+  }
+  b;
+} USB_OTG_hc_int_data;
+
+/******************************************************************************/
+
+
+typedef union _USB_OTG_hc_txfer_siz_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t xfersize :
+    19;
+uint32_t pktcnt :
+    10;
+uint32_t pid :
+    2;
+uint32_t dopng :
+    1;
+  }
+  b;
+} USB_OTG_hc_txfer_siz_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_hc_int_msk_data
+{
+
+  uint32_t d32;
+  struct
+  {
+uint32_t xfercompl :
+    1;
+uint32_t chhltd :
+    1;
+uint32_t ahberr :
+    1;
+uint32_t stall :
+    1;
+uint32_t nak :
+    1;
+uint32_t ack :
+    1;
+uint32_t nyet :
+    1;
+uint32_t xacterr :
+    1;
+uint32_t bblerr :
+    1;
+uint32_t frmovrun :
+    1;
+uint32_t datatglerr :
+    1;
+uint32_t reserved :
+    21;
+  }
+  b;
+} USB_OTG_hc_int_msk_data;
+
+/******************************************************************************/
+
+typedef union _USB_OTG_host_pcgcctl_data
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t stoppclk :
+    1;
+uint32_t gatehclk :
+    1;
+uint32_t pwrclmp :
+    1;
+uint32_t rstpdwnmodule :
+    1;
+uint32_t physuspended :
+    1;
+uint32_t reserved :
+    27;
+  }
+  b;
+} USB_OTG_host_pcgcctl_data;
+
+#endif /* STM32F10X_CL */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+
+#endif

+ 243 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_core.h

@@ -0,0 +1,243 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_core.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Standard protocol processing functions prototypes
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CORE_H
+#define __USB_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef enum _CONTROL_STATE
+{
+  WAIT_SETUP,       /* 0 */
+  SETTING_UP,       /* 1 */
+  IN_DATA,          /* 2 */
+  OUT_DATA,         /* 3 */
+  LAST_IN_DATA,     /* 4 */
+  LAST_OUT_DATA,    /* 5 */
+  WAIT_STATUS_IN,   /* 7 */
+  WAIT_STATUS_OUT,  /* 8 */
+  STALLED,          /* 9 */
+  PAUSE             /* 10 */
+} CONTROL_STATE;    /* The state machine states of a control pipe */
+
+typedef struct OneDescriptor
+{
+  uint8_t *Descriptor;
+  uint16_t Descriptor_Size;
+}
+ONE_DESCRIPTOR, *PONE_DESCRIPTOR;
+/* All the request process routines return a value of this type
+   If the return value is not SUCCESS or NOT_READY,
+   the software will STALL the correspond endpoint */
+typedef enum _RESULT
+{
+  USB_SUCCESS = 0,    /* Process sucessfully */
+  USB_ERROR,
+  USB_UNSUPPORT,
+  USB_NOT_READY       /* The process has not been finished, endpoint will be
+                         NAK to further rquest */
+} RESULT;
+
+
+/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/
+typedef struct _ENDPOINT_INFO
+{
+  /* When send data out of the device,
+   CopyData() is used to get data buffer 'Length' bytes data
+   if Length is 0,
+    CopyData() returns the total length of the data
+    if the request is not supported, returns 0
+    (NEW Feature )
+     if CopyData() returns -1, the calling routine should not proceed
+     further and will resume the SETUP process by the class device
+   if Length is not 0,
+    CopyData() returns a pointer to indicate the data location
+   Usb_wLength is the data remain to be sent,
+   Usb_wOffset is the Offset of original data
+  When receive data from the host,
+   CopyData() is used to get user data buffer which is capable
+   of Length bytes data to copy data from the endpoint buffer.
+   if Length is 0,
+    CopyData() returns the available data length,
+   if Length is not 0,
+    CopyData() returns user buffer address
+   Usb_rLength is the data remain to be received,
+   Usb_rPointer is the Offset of data buffer
+  */
+  uint16_t  Usb_wLength;
+  uint16_t  Usb_wOffset;
+  uint16_t  PacketSize;
+  uint8_t   *(*CopyData)(uint16_t Length);
+}ENDPOINT_INFO;
+
+/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/
+
+typedef struct _DEVICE
+{
+  uint8_t Total_Endpoint;     /* Number of endpoints that are used */
+  uint8_t Total_Configuration;/* Number of configuration available */
+}
+DEVICE;
+
+typedef union
+{
+  uint16_t w;
+  struct BW
+  {
+    uint8_t bb1;
+    uint8_t bb0;
+  }
+  bw;
+} uint16_t_uint8_t;
+
+typedef struct _DEVICE_INFO
+{
+  uint8_t USBbmRequestType;       /* bmRequestType */
+  uint8_t USBbRequest;            /* bRequest */
+  uint16_t_uint8_t USBwValues;         /* wValue */
+  uint16_t_uint8_t USBwIndexs;         /* wIndex */
+  uint16_t_uint8_t USBwLengths;        /* wLength */
+
+  uint8_t ControlState;           /* of type CONTROL_STATE */
+  uint8_t Current_Feature;
+  uint8_t Current_Configuration;   /* Selected configuration */
+  uint8_t Current_Interface;       /* Selected interface of current configuration */
+  uint8_t Current_AlternateSetting;/* Selected Alternate Setting of current
+                                     interface*/
+
+  ENDPOINT_INFO Ctrl_Info;
+}DEVICE_INFO;
+
+typedef struct _DEVICE_PROP
+{
+  void (*Init)(void);        /* Initialize the device */
+  void (*Reset)(void);       /* Reset routine of this device */
+
+  /* Device dependent process after the status stage */
+  void (*Process_Status_IN)(void);
+  void (*Process_Status_OUT)(void);
+
+  /* Procedure of process on setup stage of a class specified request with data stage */
+  /* All class specified requests with data stage are processed in Class_Data_Setup
+   Class_Data_Setup()
+    responses to check all special requests and fills ENDPOINT_INFO
+    according to the request
+    If IN tokens are expected, then wLength & wOffset will be filled
+    with the total transferring bytes and the starting position
+    If OUT tokens are expected, then rLength & rOffset will be filled
+    with the total expected bytes and the starting position in the buffer
+
+    If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT
+
+   CAUTION:
+    Since GET_CONFIGURATION & GET_INTERFACE are highly related to
+    the individual classes, they will be checked and processed here.
+  */
+  RESULT (*Class_Data_Setup)(uint8_t RequestNo);
+
+  /* Procedure of process on setup stage of a class specified request without data stage */
+  /* All class specified requests without data stage are processed in Class_NoData_Setup
+   Class_NoData_Setup
+    responses to check all special requests and perform the request
+
+   CAUTION:
+    Since SET_CONFIGURATION & SET_INTERFACE are highly related to
+    the individual classes, they will be checked and processed here.
+  */
+  RESULT (*Class_NoData_Setup)(uint8_t RequestNo);
+
+  /*Class_Get_Interface_Setting
+   This function is used by the file usb_core.c to test if the selected Interface
+   and Alternate Setting (uint8_t Interface, uint8_t AlternateSetting) are supported by
+   the application.
+   This function is writing by user. It should return "SUCCESS" if the Interface
+   and Alternate Setting are supported by the application or "UNSUPPORT" if they
+   are not supported. */
+
+  RESULT  (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);
+
+  uint8_t* (*GetDeviceDescriptor)(uint16_t Length);
+  uint8_t* (*GetConfigDescriptor)(uint16_t Length);
+  uint8_t* (*GetStringDescriptor)(uint16_t Length);
+
+  uint8_t* RxEP_buffer;
+  uint8_t MaxPacketSize;
+
+}DEVICE_PROP;
+
+typedef struct _USER_STANDARD_REQUESTS
+{
+  void (*User_GetConfiguration)(void);       /* Get Configuration */
+  void (*User_SetConfiguration)(void);       /* Set Configuration */
+  void (*User_GetInterface)(void);           /* Get Interface */
+  void (*User_SetInterface)(void);           /* Set Interface */
+  void (*User_GetStatus)(void);              /* Get Status */
+  void (*User_ClearFeature)(void);           /* Clear Feature */
+  void (*User_SetEndPointFeature)(void);     /* Set Endpoint Feature */
+  void (*User_SetDeviceFeature)(void);       /* Set Device Feature */
+  void (*User_SetDeviceAddress)(void);       /* Set Device Address */
+}
+USER_STANDARD_REQUESTS;
+
+/* Exported constants --------------------------------------------------------*/
+#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT))
+
+#define Usb_rLength Usb_wLength
+#define Usb_rOffset Usb_wOffset
+
+#define USBwValue USBwValues.w
+#define USBwValue0 USBwValues.bw.bb0
+#define USBwValue1 USBwValues.bw.bb1
+#define USBwIndex USBwIndexs.w
+#define USBwIndex0 USBwIndexs.bw.bb0
+#define USBwIndex1 USBwIndexs.bw.bb1
+#define USBwLength USBwLengths.w
+#define USBwLength0 USBwLengths.bw.bb0
+#define USBwLength1 USBwLengths.bw.bb1
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+uint8_t Setup0_Process(void);
+uint8_t Post0_Process(void);
+uint8_t Out0_Process(void);
+uint8_t In0_Process(void);
+
+RESULT Standard_SetEndPointFeature(void);
+RESULT Standard_SetDeviceFeature(void);
+
+uint8_t *Standard_GetConfiguration(uint16_t Length);
+RESULT Standard_SetConfiguration(void);
+uint8_t *Standard_GetInterface(uint16_t Length);
+RESULT Standard_SetInterface(void);
+uint8_t *Standard_GetDescriptorData(uint16_t Length, PONE_DESCRIPTOR pDesc);
+
+uint8_t *Standard_GetStatus(uint16_t Length);
+RESULT Standard_ClearFeature(void);
+void SetDeviceAddress(uint8_t);
+void NOP_Process(void);
+
+extern DEVICE_PROP Device_Property;
+extern  USER_STANDARD_REQUESTS User_Standard_Requests;
+extern  DEVICE  Device_Table;
+extern DEVICE_INFO Device_Info;
+
+/* cells saving status during interrupt servicing */
+extern __IO uint16_t SaveRState;
+extern __IO uint16_t SaveTState;
+
+#endif /* __USB_CORE_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 80 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_def.h

@@ -0,0 +1,80 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_def.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Definitions related to USB Core
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DEF_H
+#define __USB_DEF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef enum _RECIPIENT_TYPE
+{
+  DEVICE_RECIPIENT,     /* Recipient device */
+  INTERFACE_RECIPIENT,  /* Recipient interface */
+  ENDPOINT_RECIPIENT,   /* Recipient endpoint */
+  OTHER_RECIPIENT
+} RECIPIENT_TYPE;
+
+
+typedef enum _STANDARD_REQUESTS
+{
+  GET_STATUS = 0,
+  CLEAR_FEATURE,
+  RESERVED1,
+  SET_FEATURE,
+  RESERVED2,
+  SET_ADDRESS,
+  GET_DESCRIPTOR,
+  SET_DESCRIPTOR,
+  GET_CONFIGURATION,
+  SET_CONFIGURATION,
+  GET_INTERFACE,
+  SET_INTERFACE,
+  TOTAL_sREQUEST,  /* Total number of Standard request */
+  SYNCH_FRAME = 12
+} STANDARD_REQUESTS;
+
+/* Definition of "USBwValue" */
+typedef enum _DESCRIPTOR_TYPE
+{
+  DEVICE_DESCRIPTOR = 1,
+  CONFIG_DESCRIPTOR,
+  STRING_DESCRIPTOR,
+  INTERFACE_DESCRIPTOR,
+  ENDPOINT_DESCRIPTOR
+} DESCRIPTOR_TYPE;
+
+/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */
+typedef enum _FEATURE_SELECTOR
+{
+  ENDPOINT_STALL,
+  DEVICE_REMOTE_WAKEUP
+} FEATURE_SELECTOR;
+
+/* Exported constants --------------------------------------------------------*/
+/* Definition of "USBbmRequestType" */
+#define REQUEST_TYPE      0x60  /* Mask to get request type */
+#define STANDARD_REQUEST  0x00  /* Standard request */
+#define CLASS_REQUEST     0x20  /* Class request */
+#define VENDOR_REQUEST    0x40  /* Vendor request */
+
+#define RECIPIENT         0x1F  /* Mask to get recipient */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __USB_DEF_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 49 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_init.h

@@ -0,0 +1,49 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_init.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Initialization routines & global variables
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_INIT_H
+#define __USB_INIT_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void USB_Init(void);
+
+/* External variables --------------------------------------------------------*/
+/*  The number of current endpoint, it will be used to specify an endpoint */
+extern uint8_t	EPindex;
+/*  The number of current device, it is an index to the Device_Table */
+/*extern uint8_t	Device_no; */
+/*  Points to the DEVICE_INFO structure of current device */
+/*  The purpose of this register is to speed up the execution */
+extern DEVICE_INFO*	pInformation;
+/*  Points to the DEVICE_PROP structure of current device */
+/*  The purpose of this register is to speed up the execution */
+extern DEVICE_PROP*	pProperty;
+/*  Temporary save the state of Rx & Tx status. */
+/*  Whenever the Rx or Tx state is changed, its value is saved */
+/*  in this variable first and will be set to the EPRB or EPRA */
+/*  at the end of interrupt process */
+extern USER_STANDARD_REQUESTS *pUser_Standard_Requests;
+
+extern uint16_t	SaveState ;
+extern uint16_t wInterrupt_Mask;
+
+#endif /* __USB_INIT_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 33 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_int.h

@@ -0,0 +1,33 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_int.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Endpoint CTR (Low and High) interrupt's service routines
+*                      prototypes
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_INT_H
+#define __USB_INT_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void CTR_LP(void);
+void CTR_HP(void);
+
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_INT_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 50 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_lib.h

@@ -0,0 +1,50 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_lib.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : USB library include files
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_LIB_H
+#define __USB_LIB_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+#include "usb_type.h"
+#include "usb_regs.h"
+#include "usb_def.h"
+#include "usb_core.h"
+#include "usb_init.h"
+#ifndef STM32F10X_CL
+ #include "usb_mem.h"
+ #include "usb_int.h"
+#endif /* STM32F10X_CL */
+
+#include "usb_sil.h"
+
+#ifdef STM32F10X_CL
+ #include "otgd_fs_cal.h"
+ #include "otgd_fs_pcd.h"
+ #include "otgd_fs_dev.h"
+ #include "otgd_fs_int.h"
+#endif /* STM32F10X_CL */
+
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_LIB_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 32 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_mem.h

@@ -0,0 +1,32 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_mem.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Utility prototypes functions for memory/PMA transfers
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_MEM_H
+#define __USB_MEM_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
+void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
+
+/* External variables --------------------------------------------------------*/
+
+#endif  /*__USB_MEM_H*/
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 671 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_regs.h

@@ -0,0 +1,671 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_regs.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Interface prototype functions to USB cell registers
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_REGS_H
+#define __USB_REGS_H
+
+#ifndef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef enum _EP_DBUF_DIR
+{
+  /* double buffered endpoint direction */
+  EP_DBUF_ERR,
+  EP_DBUF_OUT,
+  EP_DBUF_IN
+}EP_DBUF_DIR;
+
+/* endpoint buffer number */
+enum EP_BUF_NUM
+{
+  EP_NOBUF,
+  EP_BUF0,
+  EP_BUF1
+};
+
+/* Exported constants --------------------------------------------------------*/
+#define RegBase  (0x40005C00L)  /* USB_IP Peripheral Registers base address */
+#define PMAAddr  (0x40006000L)  /* USB_IP Packet Memory Area base address   */
+
+/******************************************************************************/
+/*                         General registers                                  */
+/******************************************************************************/
+
+/* Control register */
+#define CNTR    ((__IO unsigned *)(RegBase + 0x40))
+/* Interrupt status register */
+#define ISTR    ((__IO unsigned *)(RegBase + 0x44))
+/* Frame number register */
+#define FNR     ((__IO unsigned *)(RegBase + 0x48))
+/* Device address register */
+#define DADDR   ((__IO unsigned *)(RegBase + 0x4C))
+/* Buffer Table address register */
+#define BTABLE  ((__IO unsigned *)(RegBase + 0x50))
+/******************************************************************************/
+/*                         Endpoint registers                                 */
+/******************************************************************************/
+#define EP0REG  ((__IO unsigned *)(RegBase)) /* endpoint 0 register address */
+
+/* Endpoint Addresses (w/direction) */
+#define EP0_OUT     ((uint8_t)0x00)  
+#define EP0_IN      ((uint8_t)0x80) 
+#define EP1_OUT     ((uint8_t)0x01)  
+#define EP1_IN      ((uint8_t)0x81)  
+#define EP2_OUT     ((uint8_t)0x02)  
+#define EP2_IN      ((uint8_t)0x82)  
+#define EP3_OUT     ((uint8_t)0x03)  
+#define EP3_IN      ((uint8_t)0x83) 
+#define EP4_OUT     ((uint8_t)0x04)  
+#define EP4_IN      ((uint8_t)0x84)
+#define EP5_OUT     ((uint8_t)0x05)  
+#define EP5_IN      ((uint8_t)0x85)
+#define EP6_OUT     ((uint8_t)0x06)  
+#define EP6_IN      ((uint8_t)0x86)
+#define EP7_OUT     ((uint8_t)0x07)  
+#define EP7_IN      ((uint8_t)0x87)
+
+/* endpoints enumeration */
+#define ENDP0       ((uint8_t)0)
+#define ENDP1       ((uint8_t)1)
+#define ENDP2       ((uint8_t)2)
+#define ENDP3       ((uint8_t)3)
+#define ENDP4       ((uint8_t)4)
+#define ENDP5       ((uint8_t)5)
+#define ENDP6       ((uint8_t)6)
+#define ENDP7       ((uint8_t)7)
+
+/******************************************************************************/
+/*                       ISTR interrupt events                                */
+/******************************************************************************/
+#define ISTR_CTR    (0x8000) /* Correct TRansfer (clear-only bit) */
+#define ISTR_DOVR   (0x4000) /* DMA OVeR/underrun (clear-only bit) */
+#define ISTR_ERR    (0x2000) /* ERRor (clear-only bit) */
+#define ISTR_WKUP   (0x1000) /* WaKe UP (clear-only bit) */
+#define ISTR_SUSP   (0x0800) /* SUSPend (clear-only bit) */
+#define ISTR_RESET  (0x0400) /* RESET (clear-only bit) */
+#define ISTR_SOF    (0x0200) /* Start Of Frame (clear-only bit) */
+#define ISTR_ESOF   (0x0100) /* Expected Start Of Frame (clear-only bit) */
+
+
+#define ISTR_DIR    (0x0010)  /* DIRection of transaction (read-only bit)  */
+#define ISTR_EP_ID  (0x000F)  /* EndPoint IDentifier (read-only bit)  */
+
+#define CLR_CTR    (~ISTR_CTR)   /* clear Correct TRansfer bit */
+#define CLR_DOVR   (~ISTR_DOVR)  /* clear DMA OVeR/underrun bit*/
+#define CLR_ERR    (~ISTR_ERR)   /* clear ERRor bit */
+#define CLR_WKUP   (~ISTR_WKUP)  /* clear WaKe UP bit     */
+#define CLR_SUSP   (~ISTR_SUSP)  /* clear SUSPend bit     */
+#define CLR_RESET  (~ISTR_RESET) /* clear RESET bit      */
+#define CLR_SOF    (~ISTR_SOF)   /* clear Start Of Frame bit   */
+#define CLR_ESOF   (~ISTR_ESOF)  /* clear Expected Start Of Frame bit */
+
+/******************************************************************************/
+/*             CNTR control register bits definitions                         */
+/******************************************************************************/
+#define CNTR_CTRM   (0x8000) /* Correct TRansfer Mask */
+#define CNTR_DOVRM  (0x4000) /* DMA OVeR/underrun Mask */
+#define CNTR_ERRM   (0x2000) /* ERRor Mask */
+#define CNTR_WKUPM  (0x1000) /* WaKe UP Mask */
+#define CNTR_SUSPM  (0x0800) /* SUSPend Mask */
+#define CNTR_RESETM (0x0400) /* RESET Mask   */
+#define CNTR_SOFM   (0x0200) /* Start Of Frame Mask */
+#define CNTR_ESOFM  (0x0100) /* Expected Start Of Frame Mask */
+
+
+#define CNTR_RESUME (0x0010) /* RESUME request */
+#define CNTR_FSUSP  (0x0008) /* Force SUSPend */
+#define CNTR_LPMODE (0x0004) /* Low-power MODE */
+#define CNTR_PDWN   (0x0002) /* Power DoWN */
+#define CNTR_FRES   (0x0001) /* Force USB RESet */
+
+/******************************************************************************/
+/*                FNR Frame Number Register bit definitions                   */
+/******************************************************************************/
+#define FNR_RXDP (0x8000) /* status of D+ data line */
+#define FNR_RXDM (0x4000) /* status of D- data line */
+#define FNR_LCK  (0x2000) /* LoCKed */
+#define FNR_LSOF (0x1800) /* Lost SOF */
+#define FNR_FN  (0x07FF) /* Frame Number */
+/******************************************************************************/
+/*               DADDR Device ADDRess bit definitions                         */
+/******************************************************************************/
+#define DADDR_EF (0x80)
+#define DADDR_ADD (0x7F)
+/******************************************************************************/
+/*                            Endpoint register                               */
+/******************************************************************************/
+/* bit positions */
+#define EP_CTR_RX      (0x8000) /* EndPoint Correct TRansfer RX */
+#define EP_DTOG_RX     (0x4000) /* EndPoint Data TOGGLE RX */
+#define EPRX_STAT      (0x3000) /* EndPoint RX STATus bit field */
+#define EP_SETUP       (0x0800) /* EndPoint SETUP */
+#define EP_T_FIELD     (0x0600) /* EndPoint TYPE */
+#define EP_KIND        (0x0100) /* EndPoint KIND */
+#define EP_CTR_TX      (0x0080) /* EndPoint Correct TRansfer TX */
+#define EP_DTOG_TX     (0x0040) /* EndPoint Data TOGGLE TX */
+#define EPTX_STAT      (0x0030) /* EndPoint TX STATus bit field */
+#define EPADDR_FIELD   (0x000F) /* EndPoint ADDRess FIELD */
+
+/* EndPoint REGister MASK (no toggle fields) */
+#define EPREG_MASK     (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD)
+
+/* EP_TYPE[1:0] EndPoint TYPE */
+#define EP_TYPE_MASK   (0x0600) /* EndPoint TYPE Mask */
+#define EP_BULK        (0x0000) /* EndPoint BULK */
+#define EP_CONTROL     (0x0200) /* EndPoint CONTROL */
+#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
+#define EP_INTERRUPT   (0x0600) /* EndPoint INTERRUPT */
+#define EP_T_MASK      (~EP_T_FIELD & EPREG_MASK)
+
+
+/* EP_KIND EndPoint KIND */
+#define EPKIND_MASK    (~EP_KIND & EPREG_MASK)
+
+/* STAT_TX[1:0] STATus for TX transfer */
+#define EP_TX_DIS      (0x0000) /* EndPoint TX DISabled */
+#define EP_TX_STALL    (0x0010) /* EndPoint TX STALLed */
+#define EP_TX_NAK      (0x0020) /* EndPoint TX NAKed */
+#define EP_TX_VALID    (0x0030) /* EndPoint TX VALID */
+#define EPTX_DTOG1     (0x0010) /* EndPoint TX Data TOGgle bit1 */
+#define EPTX_DTOG2     (0x0020) /* EndPoint TX Data TOGgle bit2 */
+#define EPTX_DTOGMASK  (EPTX_STAT|EPREG_MASK)
+
+/* STAT_RX[1:0] STATus for RX transfer */
+#define EP_RX_DIS      (0x0000) /* EndPoint RX DISabled */
+#define EP_RX_STALL    (0x1000) /* EndPoint RX STALLed */
+#define EP_RX_NAK      (0x2000) /* EndPoint RX NAKed */
+#define EP_RX_VALID    (0x3000) /* EndPoint RX VALID */
+#define EPRX_DTOG1     (0x1000) /* EndPoint RX Data TOGgle bit1 */
+#define EPRX_DTOG2     (0x2000) /* EndPoint RX Data TOGgle bit1 */
+#define EPRX_DTOGMASK  (EPRX_STAT|EPREG_MASK)
+/* Exported macro ------------------------------------------------------------*/
+/* SetCNTR */
+#define _SetCNTR(wRegValue)  (*CNTR   = (uint16_t)wRegValue)
+
+/* SetISTR */
+#define _SetISTR(wRegValue)  (*ISTR   = (uint16_t)wRegValue)
+
+/* SetDADDR */
+#define _SetDADDR(wRegValue) (*DADDR  = (uint16_t)wRegValue)
+
+/* SetBTABLE */
+#define _SetBTABLE(wRegValue)(*BTABLE = (uint16_t)(wRegValue & 0xFFF8))
+
+/* GetCNTR */
+#define _GetCNTR()   ((uint16_t) *CNTR)
+
+/* GetISTR */
+#define _GetISTR()   ((uint16_t) *ISTR)
+
+/* GetFNR */
+#define _GetFNR()    ((uint16_t) *FNR)
+
+/* GetDADDR */
+#define _GetDADDR()  ((uint16_t) *DADDR)
+
+/* GetBTABLE */
+#define _GetBTABLE() ((uint16_t) *BTABLE)
+
+/* SetENDPOINT */
+#define _SetENDPOINT(bEpNum,wRegValue)  (*(EP0REG + bEpNum)= \
+    (uint16_t)wRegValue)
+
+/* GetENDPOINT */
+#define _GetENDPOINT(bEpNum)        ((uint16_t)(*(EP0REG + bEpNum)))
+
+/*******************************************************************************
+* Macro Name     : SetEPType
+* Description    : sets the type in the endpoint register(bits EP_TYPE[1:0])
+* Input          : bEpNum: Endpoint Number. 
+*                  wType											 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\
+                                  ((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType )))
+
+/*******************************************************************************
+* Macro Name     : GetEPType
+* Description    : gets the type in the endpoint register(bits EP_TYPE[1:0]) 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint Type
+*******************************************************************************/
+#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD)
+
+/*******************************************************************************
+* Macro Name     : SetEPTxStatus
+* Description    : sets the status for tx transfer (bits STAT_TX[1:0]).
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPTxStatus(bEpNum,wState) {\
+    register uint16_t _wRegVal;       \
+    _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\
+    /* toggle first bit ? */     \
+    if((EPTX_DTOG1 & wState)!= 0)      \
+      _wRegVal ^= EPTX_DTOG1;        \
+    /* toggle second bit ?  */         \
+    if((EPTX_DTOG2 & wState)!= 0)      \
+      _wRegVal ^= EPTX_DTOG2;        \
+    _SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX));    \
+  } /* _SetEPTxStatus */
+
+/*******************************************************************************
+* Macro Name     : SetEPRxStatus
+* Description    : sets the status for rx transfer (bits STAT_TX[1:0])
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPRxStatus(bEpNum,wState) {\
+    register uint16_t _wRegVal;   \
+    \
+    _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\
+    /* toggle first bit ? */  \
+    if((EPRX_DTOG1 & wState)!= 0) \
+      _wRegVal ^= EPRX_DTOG1;  \
+    /* toggle second bit ? */  \
+    if((EPRX_DTOG2 & wState)!= 0) \
+      _wRegVal ^= EPRX_DTOG2;  \
+    _SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX)); \
+  } /* _SetEPRxStatus */
+
+/*******************************************************************************
+* Macro Name     : SetEPRxTxStatus
+* Description    : sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
+* Input          : bEpNum: Endpoint Number. 
+*                  wStaterx: new state.
+*                  wStatetx: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPRxTxStatus(bEpNum,wStaterx,wStatetx) {\
+    register uint32_t _wRegVal;   \
+    \
+    _wRegVal = _GetENDPOINT(bEpNum) & (EPRX_DTOGMASK |EPTX_STAT) ;\
+    /* toggle first bit ? */  \
+    if((EPRX_DTOG1 & wStaterx)!= 0) \
+      _wRegVal ^= EPRX_DTOG1;  \
+    /* toggle second bit ? */  \
+    if((EPRX_DTOG2 & wStaterx)!= 0) \
+      _wRegVal ^= EPRX_DTOG2;  \
+    /* toggle first bit ? */     \
+    if((EPTX_DTOG1 & wStatetx)!= 0)      \
+      _wRegVal ^= EPTX_DTOG1;        \
+    /* toggle second bit ?  */         \
+    if((EPTX_DTOG2 & wStatetx)!= 0)      \
+      _wRegVal ^= EPTX_DTOG2;        \
+    _SetENDPOINT(bEpNum, _wRegVal | EP_CTR_RX|EP_CTR_TX);    \
+  } /* _SetEPRxTxStatus */
+/*******************************************************************************
+* Macro Name     : GetEPTxStatus / GetEPRxStatus 
+* Description    : gets the status for tx/rx transfer (bits STAT_TX[1:0]
+*                  /STAT_RX[1:0])
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : status .
+*******************************************************************************/
+#define _GetEPTxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EPTX_STAT)
+
+#define _GetEPRxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EPRX_STAT)
+
+/*******************************************************************************
+* Macro Name     : SetEPTxValid / SetEPRxValid 
+* Description    : sets directly the VALID tx/rx-status into the enpoint register
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPTxValid(bEpNum)     (_SetEPTxStatus(bEpNum, EP_TX_VALID))
+
+#define _SetEPRxValid(bEpNum)     (_SetEPRxStatus(bEpNum, EP_RX_VALID))
+
+/*******************************************************************************
+* Macro Name     : GetTxStallStatus / GetRxStallStatus.
+* Description    : checks stall condition in an endpoint.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : TRUE = endpoint in stall condition.
+*******************************************************************************/
+#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \
+                                   == EP_TX_STALL)
+#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \
+                                   == EP_RX_STALL)
+
+/*******************************************************************************
+* Macro Name     : SetEP_KIND / ClearEP_KIND.
+* Description    : set & clear EP_KIND bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEP_KIND(bEpNum)    (_SetENDPOINT(bEpNum, \
+                                (EP_CTR_RX|EP_CTR_TX|((_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK))))
+#define _ClearEP_KIND(bEpNum)  (_SetENDPOINT(bEpNum, \
+                                (EP_CTR_RX|EP_CTR_TX|(_GetENDPOINT(bEpNum) & EPKIND_MASK))))
+
+/*******************************************************************************
+* Macro Name     : Set_Status_Out / Clear_Status_Out.
+* Description    : Sets/clears directly STATUS_OUT bit in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _Set_Status_Out(bEpNum)    _SetEP_KIND(bEpNum)
+#define _Clear_Status_Out(bEpNum)  _ClearEP_KIND(bEpNum)
+
+/*******************************************************************************
+* Macro Name     : SetEPDoubleBuff / ClearEPDoubleBuff.
+* Description    : Sets/clears directly EP_KIND bit in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPDoubleBuff(bEpNum)   _SetEP_KIND(bEpNum)
+#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum)
+
+/*******************************************************************************
+* Macro Name     : ClearEP_CTR_RX / ClearEP_CTR_TX.
+* Description    : Clears bit CTR_RX / CTR_TX in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _ClearEP_CTR_RX(bEpNum)   (_SetENDPOINT(bEpNum,\
+                                   _GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK))
+#define _ClearEP_CTR_TX(bEpNum)   (_SetENDPOINT(bEpNum,\
+                                   _GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK))
+
+/*******************************************************************************
+* Macro Name     : ToggleDTOG_RX / ToggleDTOG_TX .
+* Description    : Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _ToggleDTOG_RX(bEpNum)    (_SetENDPOINT(bEpNum, \
+                                   EP_CTR_RX|EP_CTR_TX|EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
+#define _ToggleDTOG_TX(bEpNum)    (_SetENDPOINT(bEpNum, \
+                                   EP_CTR_RX|EP_CTR_TX|EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
+
+/*******************************************************************************
+* Macro Name     : ClearDTOG_RX / ClearDTOG_TX.
+* Description    : Clears DTOG_RX / DTOG_TX bit in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _ClearDTOG_RX(bEpNum)  if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\
+    _ToggleDTOG_RX(bEpNum)
+#define _ClearDTOG_TX(bEpNum)  if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\
+    _ToggleDTOG_TX(bEpNum)
+/*******************************************************************************
+* Macro Name     : SetEPAddress.
+* Description    : Sets address in an endpoint register.
+* Input          : bEpNum: Endpoint Number.
+*                  bAddr: Address. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\
+    EP_CTR_RX|EP_CTR_TX|(_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr)
+
+/*******************************************************************************
+* Macro Name     : GetEPAddress.
+* Description    : Gets address in an endpoint register.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _GetEPAddress(bEpNum) ((uint8_t)(_GetENDPOINT(bEpNum) & EPADDR_FIELD))
+
+#define _pEPTxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8  )*2 + PMAAddr))
+#define _pEPTxCount(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr))
+#define _pEPRxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr))
+#define _pEPRxCount(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr))
+
+/*******************************************************************************
+* Macro Name     : SetEPTxAddr / SetEPRxAddr.
+* Description    : sets address of the tx/rx buffer.
+* Input          : bEpNum: Endpoint Number.
+*                  wAddr: address to be set (must be word aligned).
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1))
+#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1))
+
+/*******************************************************************************
+* Macro Name     : GetEPTxAddr / GetEPRxAddr.
+* Description    : Gets address of the tx/rx buffer.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : address of the buffer.
+*******************************************************************************/
+#define _GetEPTxAddr(bEpNum) ((uint16_t)*_pEPTxAddr(bEpNum))
+#define _GetEPRxAddr(bEpNum) ((uint16_t)*_pEPRxAddr(bEpNum))
+
+/*******************************************************************************
+* Macro Name     : SetEPCountRxReg.
+* Description    : Sets counter of rx buffer with no. of blocks.
+* Input          : pdwReg: pointer to counter.
+*                  wCount: Counter.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _BlocksOf32(dwReg,wCount,wNBlocks) {\
+    wNBlocks = wCount >> 5;\
+    if((wCount & 0x1f) == 0)\
+      wNBlocks--;\
+    *pdwReg = (uint32_t)((wNBlocks << 10) | 0x8000);\
+  }/* _BlocksOf32 */
+
+#define _BlocksOf2(dwReg,wCount,wNBlocks) {\
+    wNBlocks = wCount >> 1;\
+    if((wCount & 0x1) != 0)\
+      wNBlocks++;\
+    *pdwReg = (uint32_t)(wNBlocks << 10);\
+  }/* _BlocksOf2 */
+
+#define _SetEPCountRxReg(dwReg,wCount)  {\
+    uint16_t wNBlocks;\
+    if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\
+    else {_BlocksOf2(dwReg,wCount,wNBlocks);}\
+  }/* _SetEPCountRxReg */
+
+
+
+#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\
+    uint32_t *pdwReg = _pEPTxCount(bEpNum); \
+    _SetEPCountRxReg(pdwReg, wCount);\
+  }
+/*******************************************************************************
+* Macro Name     : SetEPTxCount / SetEPRxCount.
+* Description    : sets counter for the tx/rx buffer.
+* Input          : bEpNum: endpoint number.
+*                  wCount: Counter value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount)
+#define _SetEPRxCount(bEpNum,wCount) {\
+    uint32_t *pdwReg = _pEPRxCount(bEpNum); \
+    _SetEPCountRxReg(pdwReg, wCount);\
+  }
+/*******************************************************************************
+* Macro Name     : GetEPTxCount / GetEPRxCount.
+* Description    : gets counter of the tx buffer.
+* Input          : bEpNum: endpoint number.
+* Output         : None.
+* Return         : Counter value.
+*******************************************************************************/
+#define _GetEPTxCount(bEpNum)((uint16_t)(*_pEPTxCount(bEpNum)) & 0x3ff)
+#define _GetEPRxCount(bEpNum)((uint16_t)(*_pEPRxCount(bEpNum)) & 0x3ff)
+
+/*******************************************************************************
+* Macro Name     : SetEPDblBuf0Addr / SetEPDblBuf1Addr.
+* Description    : Sets buffer 0/1 address in a double buffer endpoint.
+* Input          : bEpNum: endpoint number.
+*                : wBuf0Addr: buffer 0 address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);}
+#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);}
+
+/*******************************************************************************
+* Macro Name     : SetEPDblBuffAddr.
+* Description    : Sets addresses in a double buffer endpoint.
+* Input          : bEpNum: endpoint number.
+*                : wBuf0Addr: buffer 0 address.
+*                : wBuf1Addr = buffer 1 address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \
+    _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\
+    _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\
+  } /* _SetEPDblBuffAddr */
+
+/*******************************************************************************
+* Macro Name     : GetEPDblBuf0Addr / GetEPDblBuf1Addr.
+* Description    : Gets buffer 0/1 address of a double buffer endpoint.
+* Input          : bEpNum: endpoint number.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum))
+#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum))
+
+/*******************************************************************************
+* Macro Name     : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count.
+* Description    : Gets buffer 0/1 address of a double buffer endpoint.
+* Input          : bEpNum: endpoint number.
+*                : bDir: endpoint dir  EP_DBUF_OUT = OUT 
+*                                      EP_DBUF_IN  = IN 
+*                : wCount: Counter value    
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _SetEPDblBuf0Count(bEpNum, bDir, wCount)  { \
+    if(bDir == EP_DBUF_OUT)\
+      /* OUT endpoint */ \
+    {_SetEPRxDblBuf0Count(bEpNum,wCount);} \
+    else if(bDir == EP_DBUF_IN)\
+      /* IN endpoint */ \
+      *_pEPTxCount(bEpNum) = (uint32_t)wCount;  \
+  } /* SetEPDblBuf0Count*/
+
+#define _SetEPDblBuf1Count(bEpNum, bDir, wCount)  { \
+    if(bDir == EP_DBUF_OUT)\
+      /* OUT endpoint */ \
+    {_SetEPRxCount(bEpNum,wCount);}\
+    else if(bDir == EP_DBUF_IN)\
+      /* IN endpoint */\
+      *_pEPRxCount(bEpNum) = (uint32_t)wCount; \
+  } /* SetEPDblBuf1Count */
+
+#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\
+    _SetEPDblBuf0Count(bEpNum, bDir, wCount); \
+    _SetEPDblBuf1Count(bEpNum, bDir, wCount); \
+  } /* _SetEPDblBuffCount  */
+
+/*******************************************************************************
+* Macro Name     : GetEPDblBuf0Count / GetEPDblBuf1Count.
+* Description    : Gets buffer 0/1 rx/tx counter for double buffering.
+* Input          : bEpNum: endpoint number.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum))
+#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum))
+
+
+/* External variables --------------------------------------------------------*/
+extern __IO uint16_t wIstr;  /* ISTR register last read value */
+
+/* Exported functions ------------------------------------------------------- */
+void SetCNTR(uint16_t /*wRegValue*/);
+void SetISTR(uint16_t /*wRegValue*/);
+void SetDADDR(uint16_t /*wRegValue*/);
+void SetBTABLE(uint16_t /*wRegValue*/);
+void SetBTABLE(uint16_t /*wRegValue*/);
+uint16_t GetCNTR(void);
+uint16_t GetISTR(void);
+uint16_t GetFNR(void);
+uint16_t GetDADDR(void);
+uint16_t GetBTABLE(void);
+void SetENDPOINT(uint8_t /*bEpNum*/, uint16_t /*wRegValue*/);
+uint16_t GetENDPOINT(uint8_t /*bEpNum*/);
+void SetEPType(uint8_t /*bEpNum*/, uint16_t /*wType*/);
+uint16_t GetEPType(uint8_t /*bEpNum*/);
+void SetEPTxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
+void SetEPRxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
+void SetDouBleBuffEPStall(uint8_t /*bEpNum*/, uint8_t bDir);
+uint16_t GetEPTxStatus(uint8_t /*bEpNum*/);
+uint16_t GetEPRxStatus(uint8_t /*bEpNum*/);
+void SetEPTxValid(uint8_t /*bEpNum*/);
+void SetEPRxValid(uint8_t /*bEpNum*/);
+uint16_t GetTxStallStatus(uint8_t /*bEpNum*/);
+uint16_t GetRxStallStatus(uint8_t /*bEpNum*/);
+void SetEP_KIND(uint8_t /*bEpNum*/);
+void ClearEP_KIND(uint8_t /*bEpNum*/);
+void Set_Status_Out(uint8_t /*bEpNum*/);
+void Clear_Status_Out(uint8_t /*bEpNum*/);
+void SetEPDoubleBuff(uint8_t /*bEpNum*/);
+void ClearEPDoubleBuff(uint8_t /*bEpNum*/);
+void ClearEP_CTR_RX(uint8_t /*bEpNum*/);
+void ClearEP_CTR_TX(uint8_t /*bEpNum*/);
+void ToggleDTOG_RX(uint8_t /*bEpNum*/);
+void ToggleDTOG_TX(uint8_t /*bEpNum*/);
+void ClearDTOG_RX(uint8_t /*bEpNum*/);
+void ClearDTOG_TX(uint8_t /*bEpNum*/);
+void SetEPAddress(uint8_t /*bEpNum*/, uint8_t /*bAddr*/);
+uint8_t GetEPAddress(uint8_t /*bEpNum*/);
+void SetEPTxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
+void SetEPRxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
+uint16_t GetEPTxAddr(uint8_t /*bEpNum*/);
+uint16_t GetEPRxAddr(uint8_t /*bEpNum*/);
+void SetEPCountRxReg(uint32_t * /*pdwReg*/, uint16_t /*wCount*/);
+void SetEPTxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
+void SetEPRxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
+uint16_t GetEPTxCount(uint8_t /*bEpNum*/);
+uint16_t GetEPRxCount(uint8_t /*bEpNum*/);
+void SetEPDblBuf0Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/);
+void SetEPDblBuf1Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf1Addr*/);
+void SetEPDblBuffAddr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/, uint16_t /*wBuf1Addr*/);
+uint16_t GetEPDblBuf0Addr(uint8_t /*bEpNum*/);
+uint16_t GetEPDblBuf1Addr(uint8_t /*bEpNum*/);
+void SetEPDblBuffCount(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
+void SetEPDblBuf0Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
+void SetEPDblBuf1Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
+uint16_t GetEPDblBuf0Count(uint8_t /*bEpNum*/);
+uint16_t GetEPDblBuf1Count(uint8_t /*bEpNum*/);
+EP_DBUF_DIR GetEPDblBufDir(uint8_t /*bEpNum*/);
+void FreeUserBuffer(uint8_t bEpNum/*bEpNum*/, uint8_t bDir);
+uint16_t ToWord(uint8_t, uint8_t);
+uint16_t ByteSwap(uint16_t);
+
+#endif /* STM32F10X_CL */
+
+#endif /* __USB_REGS_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 34 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_sil.h

@@ -0,0 +1,34 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_sil.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Simplified Interface Layer function prototypes.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_SIL_H
+#define __USB_SIL_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+uint32_t USB_SIL_Init(void);
+uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize);
+uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer);
+
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_SIL_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 74 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/inc/usb_type.h

@@ -0,0 +1,74 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_type.h
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Type definitions used by the USB Library
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_TYPE_H
+#define __USB_TYPE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#ifndef __STM32F10x_H
+
+typedef signed long      s32;
+typedef signed short     s16;
+typedef signed char      s8;
+
+typedef volatile signed long      vs32;
+typedef volatile signed short     vs16;
+typedef volatile signed char      vs8;
+
+typedef unsigned long       u32;
+typedef unsigned short      u16;
+typedef unsigned char       u8;
+
+typedef unsigned long  const    uc32;  /* Read Only */
+typedef unsigned short const    uc16;  /* Read Only */
+typedef unsigned char  const    uc8;   /* Read Only */
+
+typedef volatile unsigned long      vu32;
+typedef volatile unsigned short     vu16;
+typedef volatile unsigned char      vu8;
+
+typedef volatile unsigned long  const    vuc32;  /* Read Only */
+typedef volatile unsigned short const    vuc16;  /* Read Only */
+typedef volatile unsigned char  const    vuc8;   /* Read Only */
+
+
+typedef enum
+{
+  FALSE = 0, TRUE  = !FALSE
+}
+bool;
+
+typedef enum { RESET = 0, SET   = !RESET } FlagStatus, ITStatus;
+
+typedef enum { DISABLE = 0, ENABLE  = !DISABLE} FunctionalState;
+
+typedef enum { ERROR = 0, SUCCESS  = !ERROR} ErrorStatus;
+#endif
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* External variables --------------------------------------------------------*/
+
+#endif /* __USB_TYPE_H */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 1273 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/otgd_fs_cal.c

@@ -0,0 +1,1273 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otgd_fs_cal.c
+* Author             : STMicroelectronics
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : OTG FS Device Core Access Layer interface.
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifdef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "otgd_fs_cal.h"
+#include "usb_conf.h"
+#include "otgd_fs_regs.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+USB_OTG_CORE_REGS     core_regs;
+
+/* Private function prototypes -----------------------------------------------*/
+static uint32_t GetMode(void);
+static void EnableCommonInt(void);
+static USB_OTG_Status SetID(void);
+static USB_OTG_Status OTGD_FS_CoreReset(void);
+
+extern uint32_t STM32_USBH_OTG_ISR_Handler  (void);
+extern uint32_t STM32_PCD_OTG_ISR_Handler (void);
+extern uint32_t STM32_USBO_OTG_ISR_Handler (void);
+
+#ifdef HOST_MODE_ENABLED
+static void InitFSLSPClkSel(void);
+#endif
+
+
+/******************************************************************************/
+/*                           Common Core Layer                                */
+/******************************************************************************/
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PhyInit
+* Description    : Initialize the phy
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_PhyInit(void)
+{
+  USB_OTG_gpio_data    gpioctl;
+  USB_OTG_usb_cfg_data usbcfg;
+  USB_OTG_Status status = USB_OTG_OK;
+
+  /* Enable the I2C interface and deactivate the power down*/
+  gpioctl.d32 = 0;
+  gpioctl.b.vbussensingB = 1;
+  gpioctl.b.pwdn = 1;
+  gpioctl.b.i2cifen = 0;
+  WRITE_REG32 (&core_regs.common_regs->gpio, gpioctl.d32);
+  mDELAY(200);
+
+  /* Program GUSBCFG.OtgUtmifsSel to I2C*/
+  usbcfg.d32 = READ_REG32(&core_regs.common_regs->usb_cfg);
+  usbcfg.b.otgutmifssel = 0;
+  WRITE_REG32 (&core_regs.common_regs->usb_cfg, usbcfg.d32);
+
+  return status;
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_WritePacket
+* Description    : Writes a packet into the Tx FIFO associated with the EP
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_WritePacket(uint8_t *src, uint8_t ch_ep_num, uint16_t bytes)
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  uint32_t dword_count , i;
+  __IO uint32_t *fifo;
+
+  /* Find the DWORD length, padded by extra bytes as neccessary if MPS
+   * is not a multiple of DWORD */
+  dword_count =  (bytes + 3) / 4;
+
+  fifo = core_regs.data_fifo[ch_ep_num];
+
+  for (i = 0; i < dword_count; i++, src += 4)
+  {
+    WRITE_REG32( fifo, *((__packed uint32_t *)src) );
+  }
+
+  return status;
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_ReadPacket
+* Description    : Reads a packet from the Rx FIFO
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+void* OTGD_FS_ReadPacket(uint8_t *dest, uint16_t bytes)
+{
+  uint32_t i;
+  uint32_t word_count = (bytes + 3) / 4;
+
+  __IO uint32_t *fifo = core_regs.data_fifo[0];
+  uint32_t *data_buff = (uint32_t *)dest;
+
+  for (i = 0; i < word_count; i++, data_buff++)
+  {
+    *data_buff = READ_REG32(fifo);
+  }
+
+  /* Return the buffer pointer because if the transfer is composed of several packets,
+     the data of the next packet must be stored following the previous packet's data         */
+  return ((void *)data_buff);
+}
+/*******************************************************************************
+* Function Name  : EnableCommonInt
+* Description    : initializes the commmon interrupts, used in both device and
+                   host modes
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+static void EnableCommonInt(void)
+{
+
+  USB_OTG_int_msk_data int_mask;
+  int_mask.d32 = 0;
+
+  /* Clear any pending USB_OTG Interrupts */
+  WRITE_REG32( &core_regs.common_regs->otg_int, 0xFFFFFFFF);
+
+  /* Clear any pending common interrupts */
+  WRITE_REG32( &core_regs.common_regs->int_sts, 0xFFFFFFFF);
+
+  WRITE_REG32( &core_regs.common_regs->int_msk, int_mask.d32);
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_SetAddress
+* Description    : Initialize core registers addresses.
+* Input          : BaseAddress
+* Output         : None
+* Return         : status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_SetAddress(uint32_t BaseAddress)
+{
+  uint32_t i = 0;
+  USB_OTG_Status status = USB_OTG_OK;
+  core_regs.common_regs = (USB_OTG_common_regs *)(BaseAddress + USB_OTG_CORE_GLOBAL_REGS_OFFSET);
+  core_regs.dev_regs =  (USB_OTG_dev_regs  *)  (BaseAddress + USB_OTG_DEV_GLOBAL_REG_OFFSET);
+
+  for (i = 0; i < MAX_EPS_CHANNELS; i++)
+  {
+    core_regs.inep_regs[i]  = (USB_OTG_dev_in_ep_regs *)  (BaseAddress + USB_OTG_DEV_IN_EP_REG_OFFSET + (i * USB_OTG_EP_REG_OFFSET));
+    core_regs.outep_regs[i] = (USB_OTG_dev_out_ep_regs *) (BaseAddress + USB_OTG_DEV_OUT_EP_REG_OFFSET + (i * USB_OTG_EP_REG_OFFSET));
+  }
+
+  core_regs.host_regs = (USB_OTG_host_regs *)(BaseAddress + USB_OTG_HOST_GLOBAL_REG_OFFSET);
+  core_regs.hprt0 = (uint32_t *)(BaseAddress + USB_OTG_HOST_PORT_REGS_OFFSET);
+
+  for (i = 0; i < MAX_EPS_CHANNELS; i++)
+  {
+    core_regs.hc_regs[i] = (USB_OTG_hc_regs *)(BaseAddress + USB_OTG_HOST_CHAN_REGS_OFFSET + (i * USB_OTG_CHAN_REGS_OFFSET));
+  }
+
+
+  for (i = 0; i < MAX_EPS_CHANNELS; i++)
+  {
+    core_regs.data_fifo[i] = (uint32_t *)(BaseAddress + USB_OTG_DATA_FIFO_OFFSET + (i * USB_OTG_DATA_FIFO_SIZE));
+  }
+
+  core_regs.pcgcctl = (uint32_t *)(BaseAddress + USB_OTG_PCGCCTL_OFFSET);
+
+  return status;
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_CoreInit
+* Description    : Initialize the USB_OTG controller registers and prepares the core
+                   for device mode or host mode operation.
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_CoreInit(void)
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_usb_cfg_data usbcfg;
+
+  usbcfg.d32 = 0;
+
+  /* Reset the Controller */
+  OTGD_FS_CoreReset();
+
+  usbcfg.d32 = READ_REG32(&core_regs.common_regs->usb_cfg);
+  usbcfg.b.physel = 1;
+  WRITE_REG32 (&core_regs.common_regs->usb_cfg, usbcfg.d32);
+
+  /* init and configure the phy */
+  OTGD_FS_PhyInit();
+
+  /* Reset after a PHY select and set Host mode */
+  OTGD_FS_CoreReset();
+
+  /* Set Host or Device Mode */
+  SetID();
+
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_CoreReset
+* Description    : Soft reset of the core
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static USB_OTG_Status OTGD_FS_CoreReset(void)
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  __IO USB_OTG_rst_ctl_data greset;
+  uint32_t count = 0;
+  greset.d32 = 0;
+
+  /* Wait for AHB master IDLE state. */
+  do
+  {
+    uDELAY(3);
+    greset.d32 = READ_REG32(&core_regs.common_regs->rst_ctl);
+    if (++count > 200000)
+    {
+      return USB_OTG_OK;
+    }
+  }
+  while (greset.b.ahbidle == 0);
+
+  /* Core Soft Reset */
+  count = 0;
+  greset.b.csftrst = 1;
+  WRITE_REG32(&core_regs.common_regs->rst_ctl, greset.d32 );
+  do
+  {
+    greset.d32 = READ_REG32(&core_regs.common_regs->rst_ctl);
+    if (++count > 200000)
+    {
+      break;
+    }
+  }
+  while (greset.b.csftrst == 1);
+
+  /* Wait for 3 PHY Clocks*/
+  uDELAY(10);
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_EnableGlobalInt
+* Description    : Enables the controller's Global Int in the AHB Config reg
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_EnableGlobalInt(void)
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_ahb_cfg_data ahb_cfg;
+
+  ahb_cfg.d32 = 0;
+  ahb_cfg.b.glblintrmsk = 1; /* Enable interrupts */
+  MODIFY_REG32(&core_regs.common_regs->ahb_cfg, 0, ahb_cfg.d32);
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_DisableGlobalInt
+* Description    : Disables the controller's Global Int in the AHB Config reg
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_DisableGlobalInt(void)
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_ahb_cfg_data ahbcfg;
+
+  ahbcfg.d32 = 0;
+  ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+  MODIFY_REG32(&core_regs.common_regs->ahb_cfg, ahbcfg.d32, 0);
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_FlushTxFifo
+* Description    : Flush a Tx FIFO
+* Input          : FIFO num
+* Output         : None
+* Return         : status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_FlushTxFifo (uint32_t num )
+{
+
+  USB_OTG_Status status = USB_OTG_OK;
+  __IO USB_OTG_rst_ctl_data greset;
+  int count = 0;
+
+  greset.d32 = 0;
+  greset.b.txfflsh = 1;
+  greset.b.txfnum  = num;
+  WRITE_REG32( &core_regs.common_regs->rst_ctl, greset.d32 );
+
+  do
+  {
+    greset.d32 = READ_REG32( &core_regs.common_regs->rst_ctl);
+    if (++count > 200000)
+    {
+      break;
+    }
+  }
+  while (greset.b.txfflsh == 1);
+
+  /* Wait for 3 PHY Clocks*/
+  uDELAY(3);
+
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_FlushRxFifo
+* Description    : Flush a Rx FIFO
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_FlushRxFifo( void )
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  __IO USB_OTG_rst_ctl_data greset;
+  int count = 0;
+
+  greset.d32 = 0;
+  greset.b.rxfflsh = 1;
+  WRITE_REG32( &core_regs.common_regs->rst_ctl, greset.d32 );
+
+  do
+  {
+    greset.d32 = READ_REG32( &core_regs.common_regs->rst_ctl);
+    if (++count > 200000)
+    {
+      break;
+    }
+  }
+  while (greset.b.rxfflsh == 1);
+
+  /* Wait for 3 PHY Clocks*/
+  uDELAY(3);
+
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : SetID
+* Description    : Set ID line
+* Input          : None
+* Output         : None
+* Return         : num_in_ep
+*******************************************************************************/
+USB_OTG_Status SetID(void)
+{
+
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_usb_cfg_data usbcfg;
+
+  usbcfg.d32 = READ_REG32(&core_regs.common_regs->usb_cfg);
+
+  usbcfg.b.force_dev = 1;
+
+  WRITE_REG32(&core_regs.common_regs->usb_cfg, usbcfg.d32);
+
+  mDELAY(50);
+
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : GetMode
+* Description    : Get current mode
+* Input          : None
+* Output         : None
+* Return         : current mode
+*******************************************************************************/
+static uint32_t GetMode(void)
+{
+  return (READ_REG32(&core_regs.common_regs->int_sts ) & 0x1);
+}
+
+/*******************************************************************************
+* Function Name  : IsDeviceMode
+* Description    : Check if it is device mode
+* Input          : None
+* Output         : None
+* Return         : num_in_ep
+*******************************************************************************/
+uint8_t IsDeviceMode(void)
+{
+  return (GetMode() != HOST_MODE);
+}
+
+/*******************************************************************************
+* Function Name  : IsHostMode
+* Description    : Check if it is host mode
+* Input          : None
+* Output         : None
+* Return         : num_in_ep
+*******************************************************************************/
+uint8_t IsHostMode(void)
+{
+  return (GetMode() == HOST_MODE);
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_ReadCoreItr
+* Description    : returns the Core Interrupt register
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+uint32_t OTGD_FS_ReadCoreItr(void)
+{
+  uint32_t v;
+
+  v = READ_REG32(&core_regs.common_regs->int_sts);
+  v &= READ_REG32(&core_regs.common_regs->int_msk);
+
+  return v;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_ReadOtgItr
+* Description    : returns the USB_OTG Interrupt register
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+uint32_t OTGD_FS_ReadOtgItr (void)
+{
+  return (READ_REG32 (&core_regs.common_regs->otg_int));
+}
+
+/******************************************************************************/
+/*                           PCD Core Layer                                   */
+/******************************************************************************/
+
+/*******************************************************************************
+* Function Name  : InitDevSpeed
+* Description    : Initializes the DevSpd field of the DCFG register depending
+                   on the PHY type and the enumeration speed of the device.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+static void InitDevSpeed(void)
+{
+  USB_OTG_dev_cfg_data  dcfg;
+
+  dcfg.d32 = READ_REG32(&core_regs.dev_regs->dev_cfg);
+  dcfg.b.devspd = 0x3;  /* Full speed PHY */
+  WRITE_REG32(&core_regs.dev_regs->dev_cfg, dcfg.d32);
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_CoreInitDev
+* Description    : Initialize the USB_OTG controller registers for device mode
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_CoreInitDev (void)
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_dev_ep_ctl_data   depctl;
+  uint32_t i;
+
+  USB_OTG_dev_cfg_data   dcfg;
+  USB_OTG_fifo_size_data nptxfifosize;
+  USB_OTG_fifo_size_data txfifosize;
+  USB_OTG_dev_in_ep_msk_data msk;
+
+  dcfg.d32 = 0;
+
+  /* Set device speed */
+  InitDevSpeed ();
+
+  /* Restart the Phy Clock */
+  WRITE_REG32(core_regs.pcgcctl, 0);
+
+  /* Device configuration register */
+  dcfg.d32 = READ_REG32( &core_regs.dev_regs->dev_cfg);
+  dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80;
+  WRITE_REG32( &core_regs.dev_regs->dev_cfg, dcfg.d32 );
+
+  /* set Rx FIFO size */
+  WRITE_REG32( &core_regs.common_regs->rx_fifo_siz, RX_FIFO_SIZE);
+
+  /* Non-periodic Tx FIFO */
+  nptxfifosize.b.depth     = DEV_NP_TX_FIFO_SIZE;
+  nptxfifosize.b.startaddr = RX_FIFO_SIZE;
+
+  WRITE_REG32( &core_regs.common_regs->np_tx_fifo_siz, nptxfifosize.d32 );
+
+  txfifosize.b.depth = DEV_NP_TX_FIFO_SIZE;
+  WRITE_REG32( &core_regs.common_regs->dev_p_tx_fsiz_dieptxf[0], txfifosize.d32 );
+  txfifosize.b.startaddr += txfifosize.b.depth;
+  txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
+  
+  /* Flush the FIFOs */
+  OTGD_FS_FlushTxFifo(0x10); /* all Tx FIFOs */
+  OTGD_FS_FlushRxFifo();
+
+  /* Clear all pending Device Interrupts */
+  WRITE_REG32( &core_regs.dev_regs->dev_in_ep_msk, 0 );
+  WRITE_REG32( &core_regs.dev_regs->dev_out_ep_msk, 0 );
+  WRITE_REG32( &core_regs.dev_regs->dev_all_int, 0xFFFFFFFF );
+  WRITE_REG32( &core_regs.dev_regs->dev_all_int_msk, 0 );
+
+  for (i = 0; i <= MAX_TX_FIFOS; i++)
+  {
+    depctl.d32 = READ_REG32(&core_regs.inep_regs[i]->dev_in_ep_ctl);
+    if (depctl.b.epena)
+    {
+      depctl.d32 = 0;
+      depctl.b.epdis = 1;
+      depctl.b.snak = 1;
+    }
+    else
+    {
+      depctl.d32 = 0;
+    }
+
+    WRITE_REG32( &core_regs.inep_regs[i]->dev_in_ep_ctl, depctl.d32);
+
+
+    WRITE_REG32( &core_regs.inep_regs[i]->dev_in_ep_txfer_siz, 0);
+    WRITE_REG32( &core_regs.inep_regs[i]->dev_in_ep_int, 0xFF);
+  }
+
+  for (i = 0; i < 1/* NUM_OUT_EPS*/; i++)
+  {
+    depctl.d32 = READ_REG32(&core_regs.outep_regs[i]->dev_out_ep_ctl);
+    if (depctl.b.epena)
+    {
+      depctl.d32 = 0;
+      depctl.b.epdis = 1;
+      depctl.b.snak = 1;
+    }
+    else
+    {
+      depctl.d32 = 0;
+    }
+
+    WRITE_REG32( &core_regs.outep_regs[i]->dev_out_ep_ctl, depctl.d32);
+
+    WRITE_REG32( &core_regs.outep_regs[i]->dev_out_ep_txfer_siz, 0);
+    WRITE_REG32( &core_regs.outep_regs[i]->dev_out_ep_int, 0xFF);
+  }
+
+  msk.d32 = 0;
+  msk.b.txfifoundrn = 1;
+  MODIFY_REG32(&core_regs.dev_regs->dev_in_ep_msk, msk.d32, msk.d32);
+
+  OTGD_FS_EnableDevInt();
+
+  return status;
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_EnableDevInt
+* Description    : Enables the Device mode interrupts
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_EnableDevInt(void)
+{
+
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_int_msk_data intr_mask;
+
+  intr_mask.d32 = 0;
+
+  /* Disable all interrupts. */
+  WRITE_REG32( &core_regs.common_regs->int_msk, 0);
+
+  /* Clear any pending interrupts */
+  WRITE_REG32( &core_regs.common_regs->int_sts, 0xFFFFFFFF);
+
+  /* Enable the common interrupts */
+  EnableCommonInt();
+  
+  /* Enable the defined interrupts*/
+#ifdef INTR_MODEMISMATCH
+  intr_mask.b.modemismatch = 1;
+#endif /* INTR_MODEMISMATCH */
+#ifdef INTR_SOFINTR
+  intr_mask.b.sofintr = 1;
+#endif /* INTR_SOFINTR */
+#ifdef INTR_RXSTSQLVL
+  intr_mask.b.rxstsqlvl = 1;
+#endif /* INTR_RXSTSQLVL */
+#ifdef INTR_NPTXFEMPTY
+  intr_mask.b.nptxfempty = 1;
+#endif /* INTR_NPTXFEMPTY */
+#ifdef INTR_GINNAKEFF
+  intr_mask.b.ginnakeff = 1;
+#endif /* INTR_GINNAKEFF */
+#ifdef INTR_GOUTNAKEFF
+  intr_mask.b.goutnakeff = 1;
+#endif /* INTR_GOUTNAKEFF */
+#ifdef INTR_ERLYSUSPEND
+  intr_mask.b.erlysuspend = 1;
+#endif /* INTR_ERLYSUSPEND */
+#ifdef INTR_USBSUSPEND
+  intr_mask.b.usbsuspend = 1;
+#endif /* INTR_USBSUSPEND */
+#ifdef INTR_USBRESET
+  intr_mask.b.usbreset = 1;
+#endif /* INTR_USBRESET */
+#ifdef INTR_ENUMDONE
+  intr_mask.b.enumdone = 1;
+#endif /* INTR_ENUMDONE */
+#ifdef INTR_ISOOUTDROP
+  intr_mask.b.isooutdrop = 1;
+#endif /* INTR_ISOOUTDROP */
+#ifdef INTR_EOPFRAME
+  intr_mask.b.eopframe = 1;
+#endif /* INTR_EOPFRAME */
+#ifdef INTR_EPMISMATCH
+  intr_mask.b.epmismatch = 1;
+#endif /* INTR_EPMISMATCH */
+#ifdef INTR_INEPINTR
+  intr_mask.b.inepintr = 1;
+#endif /* INTR_INEPINTR */
+#ifdef INTR_OUTEPINTR
+  intr_mask.b.outepintr = 1;
+#endif /* INTR_OUTEPINTR */
+#ifdef INTR_INCOMPLISOIN
+  intr_mask.b.incomplisoin = 1;
+#endif /* INTR_INCOMPLISOIN */
+#ifdef INTR_INCOMPLISOOUT
+  intr_mask.b.incomplisoout = 1;
+#endif /* INTR_INCOMPLISOOUT */
+#ifdef INTR_DISCONNECT
+  intr_mask.b.disconnect = 1;
+#endif /* INTR_DISCONNECT */
+#ifdef INTR_WKUPINTR
+  intr_mask.b.wkupintr = 1;
+#endif /* INTR_WKUPINTR */
+
+  MODIFY_REG32( &core_regs.common_regs->int_msk, intr_mask.d32, intr_mask.d32);
+  return status;
+  
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_EP0Activate
+* Description    : enables EP0 OUT to receive SETUP packets and configures EP0
+                   IN for transmitting packets
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+USB_OTG_Status  OTGD_FS_EP0Activate(void)
+{
+  USB_OTG_Status          status = USB_OTG_OK;
+  USB_OTG_dev_sts_data    dsts;
+  USB_OTG_dev_ep_ctl_data diepctl;
+  USB_OTG_dev_ctl_data    dctl;
+
+  dctl.d32 = 0;
+  /* Read the Device Status and Endpoint 0 Control registers */
+  dsts.d32 = READ_REG32(&core_regs.dev_regs->dev_sts);
+  diepctl.d32 = READ_REG32(&core_regs.inep_regs[0]->dev_in_ep_ctl);
+
+  /* Set the MPS of the IN EP based on the enumeration speed */
+  switch (dsts.b.enumspd)
+  {
+    case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+    case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+    case DSTS_ENUMSPD_FS_PHY_48MHZ:
+      diepctl.b.mps = DEP0CTL_MPS_64;
+      break;
+    case DSTS_ENUMSPD_LS_PHY_6MHZ:
+      diepctl.b.mps = DEP0CTL_MPS_8;
+      break;
+  }
+
+  WRITE_REG32(&core_regs.inep_regs[0]->dev_in_ep_ctl, diepctl.d32);
+  dctl.b.cgnpinnak = 1;
+  MODIFY_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32, dctl.d32);
+  return status;
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_EPActivate
+* Description    : Activates an EP
+* Input          : ep
+* Output         : None
+* Return         : num_in_ep
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_EPActivate(USB_OTG_EP *ep)
+{
+
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_dev_ep_ctl_data depctl;
+  __IO uint32_t *addr;
+  USB_OTG_dev_all_int_data daintmsk;
+  daintmsk.d32 = 0;
+
+  /* Read DEPCTLn register */
+  if (ep->is_in == 1)
+  {
+    addr = &core_regs.inep_regs[ep->num]->dev_in_ep_ctl;
+    daintmsk.ep.in = 1 << ep->num;
+  }
+  else
+  {
+    addr = &core_regs.outep_regs[ep->num]->dev_out_ep_ctl;
+    daintmsk.ep.out = 1 << ep->num;
+  }
+
+  /* If the EP is already active don't change the EP Control
+   * register. */
+  depctl.d32 = READ_REG32(addr);
+  if (!depctl.b.usbactep)
+  {
+    depctl.b.mps    = ep->maxpacket;
+    depctl.b.eptype = ep->type;
+    depctl.b.txfnum = ep->tx_fifo_num;
+    depctl.b.setd0pid = 1;
+    depctl.b.usbactep = 1;
+    WRITE_REG32(addr, depctl.d32);
+  }
+
+  /* Enable the Interrupt for this EP */
+  MODIFY_REG32(&core_regs.dev_regs->dev_all_int_msk, 0, daintmsk.d32);
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_EPDeactivate
+* Description    : Deactivates an EP
+* Input          : ep
+* Output         : None
+* Return         : num_in_ep
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_EPDeactivate(USB_OTG_EP *ep)
+{
+
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_dev_ep_ctl_data depctl;
+  __IO uint32_t *addr;
+  USB_OTG_dev_all_int_data daintmsk;
+  depctl.d32 = 0;
+  daintmsk.d32 = 0;
+
+  /* Read DEPCTLn register */
+  if (ep->is_in == 1)
+  {
+    addr = &core_regs.inep_regs[ep->num]->dev_in_ep_ctl;
+    daintmsk.ep.in = 1 << ep->num;
+  }
+  else
+  {
+    addr = &core_regs.outep_regs[ep->num]->dev_out_ep_ctl;
+    daintmsk.ep.out = 1 << ep->num;
+  }
+
+  depctl.b.usbactep = 0;
+  WRITE_REG32(addr, depctl.d32);
+
+  /* Disable the Interrupt for this EP */
+  MODIFY_REG32(&core_regs.dev_regs->dev_all_int_msk, daintmsk.d32, 0);
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_EPStartXfer
+* Description    : Handle the setup for data xfer for an EP and starts the xfer
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_EPStartXfer(USB_OTG_EP *ep)
+{
+
+  USB_OTG_Status status = USB_OTG_OK;
+  __IO USB_OTG_dev_ep_ctl_data depctl;
+  USB_OTG_dev_ep_txfer_siz_data deptsiz;
+
+  /* IN endpoint */
+  if (ep->is_in == 1)
+  {
+
+    depctl.d32  = READ_REG32(&(core_regs.inep_regs[ep->num]->dev_in_ep_ctl));
+    deptsiz.d32 = READ_REG32(&(core_regs.inep_regs[ep->num]->dev_in_ep_txfer_siz));
+
+    /* Zero Length Packet? */
+    if (ep->xfer_len == 0)
+    {
+      deptsiz.b.xfersize = 0;
+      deptsiz.b.pktcnt = 1;
+
+    }
+    else
+    {
+      /* Program the transfer size and packet count
+       * as follows: xfersize = N * maxpacket +
+       * short_packet pktcnt = N + (short_packet
+       * exist ? 1 : 0)
+       */
+      deptsiz.b.xfersize = ep->xfer_len;
+      deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
+    }
+    WRITE_REG32(&core_regs.inep_regs[ep->num]->dev_in_ep_txfer_siz, deptsiz.d32);
+
+    if (ep->type != EP_TYPE_ISOC)
+    {
+      /* Enable the Tx FIFO Empty Interrupt for this EP */
+      uint32_t fifoemptymsk = 0;
+      fifoemptymsk = 1 << ep->num;
+      MODIFY_REG32(&core_regs.dev_regs->dev_fifo_empty_msk, 0, fifoemptymsk);
+    }
+   
+    /* EP enable, IN data in FIFO */
+    depctl.b.cnak = 1;
+    depctl.b.epena = 1;
+    WRITE_REG32(&core_regs.inep_regs[ep->num]->dev_in_ep_ctl, depctl.d32);
+    
+    depctl.d32 = READ_REG32 (&core_regs.inep_regs[0]->dev_in_ep_ctl);
+    depctl.b.nextep = ep->num;
+    WRITE_REG32 (&core_regs.inep_regs[0]->dev_in_ep_ctl, depctl.d32);    
+  }
+  else
+  {
+    /* OUT endpoint */
+    depctl.d32  = READ_REG32(&(core_regs.outep_regs[ep->num]->dev_out_ep_ctl));
+    deptsiz.d32 = READ_REG32(&(core_regs.outep_regs[ep->num]->dev_out_ep_txfer_siz));
+
+    /* Program the transfer size and packet count as follows:
+     * pktcnt = N
+     * xfersize = N * maxpacket
+     */
+    if (ep->xfer_len == 0)
+    {
+      deptsiz.b.xfersize = ep->maxpacket;
+      deptsiz.b.pktcnt = 1;
+    }
+    else
+    {
+      deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
+      deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
+    }
+    WRITE_REG32(&core_regs.outep_regs[ep->num]->dev_out_ep_txfer_siz, deptsiz.d32);
+
+    if (ep->type == EP_TYPE_ISOC)
+    {
+
+      if (ep->even_odd_frame)
+      {
+        depctl.b.setd1pid = 1;
+      }
+      else
+      {
+        depctl.b.setd0pid = 1;
+      }
+    }
+
+    /* EP enable */
+    depctl.b.cnak = 1;
+    depctl.b.epena = 1;
+
+    WRITE_REG32(&core_regs.outep_regs[ep->num]->dev_out_ep_ctl, depctl.d32);
+
+  }
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_EP0StartXfer
+* Description    : Handle the setup for a data xfer for EP0 and starts the xfer
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_EP0StartXfer(USB_OTG_EP *ep)
+{
+
+  USB_OTG_Status                    status = USB_OTG_OK;
+  uint32_t                               fifoemptymsk = 0;
+  USB_OTG_dev_ep_ctl_data           depctl;
+  USB_OTG_dev_ep_txfer_size0_data   deptsiz;
+  USB_OTG_dev_in_ep_regs            *in_regs ;
+
+  /* IN endpoint */
+  if (ep->is_in == 1)
+  {
+    in_regs = core_regs.inep_regs[0];
+    depctl.d32  = READ_REG32(&in_regs->dev_in_ep_ctl);
+    deptsiz.d32 = READ_REG32(&in_regs->dev_in_ep_txfer_siz);
+
+    /* Zero Length Packet? */
+    if (ep->xfer_len == 0)
+    {
+      deptsiz.b.xfersize = 0;
+      deptsiz.b.pktcnt = 1;
+    }
+    else
+    {
+      if (ep->xfer_len > ep->maxpacket)
+      {
+        ep->xfer_len = ep->maxpacket;
+        deptsiz.b.xfersize = ep->maxpacket;
+      }
+      else
+      {
+        deptsiz.b.xfersize = ep->xfer_len;
+      }
+      deptsiz.b.pktcnt = 1;
+
+    }
+    WRITE_REG32(&in_regs->dev_in_ep_txfer_siz, deptsiz.d32);
+
+    /* EP enable, IN data in FIFO */
+    depctl.b.cnak = 1;
+    depctl.b.epena = 1;
+    WRITE_REG32(&in_regs->dev_in_ep_ctl, depctl.d32);
+
+    /* Enable the Tx FIFO Empty Interrupt for this EP */
+    if (ep->xfer_len > 0)
+    {
+      fifoemptymsk |= 1 << ep->num;
+      MODIFY_REG32(&core_regs.dev_regs->dev_fifo_empty_msk, 0, fifoemptymsk);
+    }
+  }
+  else
+  {
+    /* OUT endpoint */
+    depctl.d32  = READ_REG32(&core_regs.outep_regs[ep->num]->dev_out_ep_ctl);
+    deptsiz.d32 = READ_REG32(&core_regs.outep_regs[ep->num]->dev_out_ep_txfer_siz);
+
+    /* Program the transfer size and packet count as follows:
+     * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
+     * pktcnt = N           */
+    if (ep->xfer_len == 0)
+    {
+      deptsiz.b.xfersize = ep->maxpacket;
+      deptsiz.b.pktcnt = 1;
+    }
+    else
+    {
+      deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
+      deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
+    }
+
+    WRITE_REG32(&core_regs.outep_regs[ep->num]->dev_out_ep_txfer_siz, deptsiz.d32);
+
+    /* EP enable */
+    depctl.b.cnak = 1;
+    depctl.b.epena = 1;
+    WRITE_REG32 (&(core_regs.outep_regs[ep->num]->dev_out_ep_ctl), depctl.d32);
+  }
+  return status;
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_EPSetStall
+* Description    : Set the EP STALL
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_EPSetStall(USB_OTG_EP *ep)
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_dev_ep_ctl_data depctl; 
+  __IO uint32_t *depctl_addr;
+
+  if (ep->is_in == 1)
+  {
+    depctl_addr = &(core_regs.inep_regs[ep->num]->dev_in_ep_ctl);
+    depctl.d32 = READ_REG32(depctl_addr);
+
+    /* set the disable and stall bits */
+    if (depctl.b.epena)
+    {
+      depctl.b.epdis = 1;
+    }
+    depctl.b.stall = 1;
+    WRITE_REG32(depctl_addr, depctl.d32);
+  }
+  else
+  {
+    depctl_addr = &(core_regs.outep_regs[ep->num]->dev_out_ep_ctl);
+    depctl.d32 = READ_REG32(depctl_addr);
+
+    /* set the stall bit */
+    depctl.b.stall = 1;
+    WRITE_REG32(depctl_addr, depctl.d32);
+  }
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_EPClearStall
+* Description    : Clear the EP STALL
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+USB_OTG_Status OTGD_FS_EPClearStall(USB_OTG_EP *ep)
+{
+  USB_OTG_Status status = USB_OTG_OK;
+  USB_OTG_dev_ep_ctl_data depctl;
+  __IO uint32_t *depctl_addr;
+
+  if (ep->is_in == 1)
+  {
+    depctl_addr = &(core_regs.inep_regs[ep->num]->dev_in_ep_ctl);
+  }
+  else
+  {
+    depctl_addr = &(core_regs.outep_regs[ep->num]->dev_out_ep_ctl);
+  }
+
+  
+  depctl.d32 = READ_REG32(depctl_addr);
+   
+  /* clear the stall bits */
+  depctl.b.stall = 0;
+
+  if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+  {
+    depctl.b.setd0pid = 1; /* DATA0 */
+  }
+
+  WRITE_REG32(depctl_addr, depctl.d32);
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_ReadDevAllOutEp_itr
+* Description    : returns the OUT endpoint interrupt bits
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+uint32_t OTGD_FS_ReadDevAllOutEp_itr(void)
+{
+  uint32_t v;
+  v  = READ_REG32(&core_regs.dev_regs->dev_all_int);
+  v &= READ_REG32(&core_regs.dev_regs->dev_all_int_msk);
+  return ((v & 0xffff0000) >> 16);
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_ReadDevOutEP_itr
+* Description    : returns the Device OUT EP Interrupt register
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+uint32_t OTGD_FS_ReadDevOutEP_itr(USB_OTG_EP *ep)
+{
+  uint32_t v;
+  v  = READ_REG32(&core_regs.outep_regs[ep->num]->dev_out_ep_int);
+  v &= READ_REG32(&core_regs.dev_regs->dev_out_ep_msk);
+  return v;
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_ReadDevAllInEPItr
+* Description    : Get int status register
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+uint32_t OTGD_FS_ReadDevAllInEPItr(void)
+{
+  uint32_t v;
+  v = READ_REG32(&core_regs.dev_regs->dev_all_int);
+  v &= READ_REG32(&core_regs.dev_regs->dev_all_int_msk);
+  return (v & 0xffff);
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Dev_GetEPStatus
+* Description    : returns the EP Status 
+* Input          : - ep: pointer to the EP structure
+* Output         : None
+* Return         : status: DEV_EP_TX_STALL, DEV_EP_TX_VALID, DEV_EP_TX_NAK, 
+*                  DEV_EP_RX_STALL, DEV_EP_RX_VALID or DEV_EP_RX_NAK,
+*******************************************************************************/
+uint32_t OTGD_FS_Dev_GetEPStatus(USB_OTG_EP *ep)
+{
+  USB_OTG_dev_ep_ctl_data depctl;
+  __IO uint32_t *depctl_addr;
+  uint32_t Status = 0;
+
+  if (ep->is_in == 1)
+  {
+    depctl_addr = &(core_regs.inep_regs[ep->num]->dev_in_ep_ctl);
+  }
+  else
+  {
+    depctl_addr = &(core_regs.outep_regs[ep->num]->dev_out_ep_ctl);
+  }
+
+  depctl.d32 = READ_REG32(depctl_addr);
+
+  /* Process for IN endpoint */
+  if (ep->is_in == 1)
+  {
+    if (depctl.b.stall == 1)  
+      Status = DEV_EP_TX_STALL;
+    else if (depctl.b.naksts == 1)
+      Status = DEV_EP_TX_NAK;
+    else 
+      Status = DEV_EP_TX_VALID; 
+  } 
+  /* Process for OUT endpoint */
+  else 
+  {
+    if (depctl.b.stall == 1)  
+      Status = DEV_EP_RX_STALL;
+    else if (depctl.b.naksts == 1)
+      Status = DEV_EP_RX_NAK;
+    else 
+      Status = DEV_EP_RX_VALID; 
+  }
+  
+  /* Return the current status */
+  return Status;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Dev_SetEPStatus
+* Description    : Sets the EP Status 
+* Input          : - ep: pointer to the EP structure
+*                  - Status: new status to be set
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void OTGD_FS_Dev_SetEPStatus(USB_OTG_EP *ep, uint32_t Status)
+{
+  USB_OTG_dev_ep_ctl_data depctl;
+  __IO uint32_t *depctl_addr;
+
+  if (ep->is_in == 1)
+  {
+    depctl_addr = &(core_regs.inep_regs[ep->num]->dev_in_ep_ctl);
+  }
+  else
+  {
+    depctl_addr = &(core_regs.outep_regs[ep->num]->dev_out_ep_ctl);
+  }
+
+  depctl.d32 = READ_REG32(depctl_addr);
+
+  /* Process for IN endpoint */
+  if (ep->is_in == 1)
+  {
+    if (Status == DEV_EP_TX_STALL)  
+    {
+      OTGD_FS_EPSetStall(ep); return;
+    }
+    else if (Status == DEV_EP_TX_NAK)
+      depctl.b.snak = 1;
+    else if (Status == DEV_EP_TX_VALID)
+    {
+      if (depctl.b.stall == 1)
+      {  
+        ep->even_odd_frame = 0;
+        OTGD_FS_EPClearStall(ep);
+        return;
+      }      
+      depctl.b.cnak = 1;
+      depctl.b.usbactep = 1; 
+      depctl.b.epena = 1;
+    }
+    else if (Status == DEV_EP_TX_DIS)
+      depctl.b.usbactep = 0;
+  } 
+  else /* Process for OUT endpoint */
+  {
+    if (Status == DEV_EP_RX_STALL)  
+      depctl.b.stall = 1;
+    else if (Status == DEV_EP_RX_NAK)
+      depctl.b.snak = 1;
+    else if (Status == DEV_EP_RX_VALID)
+    {
+      if (depctl.b.stall == 1)
+      {  
+        ep->even_odd_frame = 0;
+        OTGD_FS_EPClearStall(ep);
+        return;
+      }  
+      depctl.b.cnak = 1;
+      depctl.b.usbactep = 1;    
+      depctl.b.epena = 1;
+    }
+    else if (Status == DEV_EP_RX_DIS)
+    {
+      depctl.b.usbactep = 0;    
+    }
+  }
+
+  if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+  {
+    depctl.b.setd0pid = 1; /* DATA0 */
+  }
+
+  WRITE_REG32(depctl_addr, depctl.d32); 
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Dev_SetRemoteWakeup
+* Description    : Enable Remote wakeup signaling
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+void OTGD_FS_Dev_SetRemoteWakeup()
+{
+ USB_OTG_dev_ctl_data devctl;
+ __IO uint32_t *dctl_addr;
+ 
+ dctl_addr = &(core_regs.dev_regs->dev_ctl);
+ 
+ devctl.d32 = READ_REG32( dctl_addr);
+ 
+ /* Enable the Remote Wakeup signal */
+ devctl.b.rmtwkupsig = 1;
+ 
+ WRITE_REG32(dctl_addr, devctl.d32);
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Dev_ResetRemoteWakeup
+* Description    : Disable Remote wakeup signaling
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+void OTGD_FS_Dev_ResetRemoteWakeup()
+{
+ USB_OTG_dev_ctl_data devctl;
+ __IO uint32_t *dctl_addr;
+ 
+ dctl_addr = &(core_regs.dev_regs->dev_ctl);
+ 
+ devctl.d32 = READ_REG32( dctl_addr);
+ 
+ /* Disable the Remote Wakeup signal */
+ devctl.b.rmtwkupsig = 0;
+ 
+ 
+ WRITE_REG32(dctl_addr, devctl.d32);
+}
+#endif /* STM32F10X_CL */
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 385 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/otgd_fs_dev.c

@@ -0,0 +1,385 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otgd_fs_dev.c
+* Author             : STMicroelectronics
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : High Layer device mode interface and wrapping layer.
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifdef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "otgd_fs_dev.h"
+#include "usb_regs.h"
+#include "otgd_fs_cal.h"
+#include "otgd_fs_pcd.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : OTG_DEV_Init
+* Description    : Initialize the OTG Device IP and EP0.
+* Input          : None.
+* Output         : None.
+* Return         : None. 
+*******************************************************************************/
+void OTG_DEV_Init(void)
+{
+  EP_DESCRIPTOR ep_descriptor;
+  USB_OTG_EP *ep;
+  
+  /* Set the OTG_USB base registers address */
+  OTGD_FS_SetAddress(USB_OTG_FS1_BASE_ADDR);
+  
+  /* Disable all global interrupts */
+  OTGD_FS_DisableGlobalInt();
+
+  /*Init the Core (common init.) */
+  OTGD_FS_CoreInit();
+
+  /* Init Device */
+  OTGD_FS_CoreInitDev();
+
+  /* Init internal driver structure */
+  OTGD_FS_PCD_Init();
+  
+  /* Configure and open the IN control EP0 */ 
+  ep_descriptor.bEndpointAddress = 0x80;
+  ep_descriptor.wMaxPacketSize = 64;  
+  ep_descriptor.bmAttributes = USB_ENDPOINT_XFER_CONTROL; 
+  OTGD_FS_PCD_EP_Open(&ep_descriptor);
+  
+  /* Configure and open the OUT control EP0 */ 
+  ep_descriptor.bEndpointAddress = 0x00;
+  OTGD_FS_PCD_EP_Open(&ep_descriptor);    
+
+
+  ep = OTGD_FS_PCD_GetOutEP(0);
+  OTGD_FS_EPStartXfer(ep);
+  
+  /* Enable EP0 to start receiving setup packets */  
+  OTGD_FS_PCD_EP0_OutStart();  
+  
+  /* Enable USB Global interrupt */
+  OTGD_FS_EnableGlobalInt();     
+}
+
+
+/*******************************************************************************
+* Function Name  : OTG_DEV_EP_Init
+* Description    : Initialize the selected endpoint parameters
+* Input          : - bEpAdd: address of the endpoint (epnum|epdir) 
+*                     expample: EP1 OUT -> 0x01 and EP1 IN 0x81.
+*                  - bEpType: OTG_DEV_EP_TYPE_CONTROL, OTG_DEV_EP_TYPE_ISOC, 
+*                     OTG_DEV_EP_TYPE_BULK, OTG_DEV_EP_TYPE_INT
+*                  - wEpMaxPackSize: The EP max packet size.
+* Output         : None.
+* Return         : Status: New status to be set for the endpoint: 
+*******************************************************************************/
+void OTG_DEV_EP_Init(uint8_t bEpAdd, uint8_t bEpType, uint16_t wEpMaxPackSize)
+{
+  EP_DESCRIPTOR ep_descriptor;
+  USB_OTG_EP *ep;
+  
+  /* Set the EP parameters in a structure */
+  ep_descriptor.bEndpointAddress = bEpAdd;
+  ep_descriptor.bmAttributes = bEpType; 
+  ep_descriptor.wMaxPacketSize = wEpMaxPackSize;
+
+  OTGD_FS_PCD_EP_Flush(bEpAdd);
+  
+  /* Open the EP with entered parameters */   
+  OTGD_FS_PCD_EP_Open(&ep_descriptor); 
+  
+  /* Activate the EP if it is an OUT EP */
+  if ((bEpAdd & 0x80) == 0)
+  {
+    ep = OTGD_FS_PCD_GetOutEP(bEpAdd & 0x7F);
+    OTGD_FS_EPStartXfer(ep);
+  } 
+  else
+  {
+    ep = OTGD_FS_PCD_GetInEP(bEpAdd & 0x7F);
+    ep->even_odd_frame = 0;    
+    OTG_DEV_SetEPTxStatus(bEpAdd, DEV_EP_TX_NAK);
+  }
+  
+}
+
+/*******************************************************************************
+* Function Name  : OTG_DEV_GetEPTxStatus
+* Description    : Set the related endpoint status.
+* Input          : Number of the endpoint.
+* Output         : None.
+* Return         : Status: New status to be set for the endpoint: 
+*******************************************************************************/
+uint32_t OTG_DEV_GetEPTxStatus(uint8_t bEpnum) 
+{
+  USB_OTG_EP *ep;
+  uint32_t status = 0;
+  
+  ep = OTGD_FS_PCD_GetInEP(bEpnum & 0x7F); 
+  
+  status = OTGD_FS_Dev_GetEPStatus(ep); 
+  
+  return status; 
+}
+
+/*******************************************************************************
+* Function Name  : OTG_DEV_GetEPRxStatus
+* Description    : returns the related endpoint status.
+* Input          : Number of the endpoint.
+* Output         : None.
+* Return         : Status: New status to be set for the endpoint: 
+*******************************************************************************/
+uint32_t OTG_DEV_GetEPRxStatus(uint8_t bEpnum)
+{
+  USB_OTG_EP *ep;
+  uint32_t status = 0;
+  
+  ep = OTGD_FS_PCD_GetOutEP(bEpnum & 0x7F); 
+  
+  status = OTGD_FS_Dev_GetEPStatus(ep); 
+  
+  return status;
+}
+
+/*******************************************************************************
+* Function Name  : OTG_DEV_SetEPTxStatus
+* Description    : Sets the related endpoint status.
+* Input          : - bEpnum: Number of the endpoint.
+*                  - Status: New status to be set for the endpoint. It can be
+*                    DEV_EP_TX_VALID, DEV_EP_TX_STALL, DEV_EP_TX_NAK or 
+*                    DEV_EP_TX_DISABLE.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void OTG_DEV_SetEPTxStatus(uint8_t bEpnum, uint32_t Status) 
+{
+  USB_OTG_EP *ep;
+   
+  ep = OTGD_FS_PCD_GetInEP(bEpnum & 0x7F); 
+  
+  if ((bEpnum == 0x80) && (Status == DEV_EP_TX_STALL))
+  {
+    ep->is_in = 1;
+  }
+  
+  OTGD_FS_Dev_SetEPStatus(ep, Status); 
+}
+
+/*******************************************************************************
+* Function Name  : OTG_DEV_SetEPRxStatus
+* Description    : Sets the related endpoint status.
+* Input          : - bEpnum: Number of the endpoint.
+*                  - Status: New status to be set for the endpoint. It can be
+*                    DEV_EP_RX_VALID, DEV_EP_RX_STALL, DEV_EP_RX_NAK or 
+*                    DEV_EP_RX_DISABLE.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void OTG_DEV_SetEPRxStatus(uint8_t bEpnum, uint32_t Status)                           
+{
+  USB_OTG_EP *ep;
+ 
+  ep = OTGD_FS_PCD_GetOutEP(bEpnum & 0x7F); 
+  
+  OTGD_FS_Dev_SetEPStatus(ep, Status); 
+}
+
+/*******************************************************************************
+* Function Name  : USB_DevDisconnect
+* Description    : Disconnect the Pullup resist.
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void USB_DevDisconnect(void)
+{
+  OTGD_FS_PCD_DevDisconnect();
+}
+
+/*******************************************************************************
+* Function Name  : USB_DevConnect
+* Description    : Disconnect the .
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void USB_DevConnect(void)
+{
+  OTGD_FS_PCD_DevConnect();
+}
+
+/*-*-*-*-*-*-*-*-*-* Replace the usb_regs.h defines -*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+/*******************************************************************************
+* Function Name  : SetEPTxStatus
+* Description    : Set the status of Tx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxStatus(uint8_t bEpNum, uint16_t wState)
+{
+  _SetEPTxStatus(bEpNum, wState);
+}
+
+/*******************************************************************************
+* Function Name  : SetEPRxStatus
+* Description    : Set the status of Rx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxStatus(uint8_t bEpNum, uint16_t wState)
+{
+  _SetEPRxStatus(bEpNum, wState);
+}
+
+/*******************************************************************************
+* Function Name  : GetEPTxStatus
+* Description    : Returns the endpoint Tx status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint TX Status
+*******************************************************************************/
+uint16_t GetEPTxStatus(uint8_t bEpNum) 
+{
+  return(_GetEPTxStatus(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : GetEPRxStatus
+* Description    : Returns the endpoint Rx status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint RX Status
+*******************************************************************************/
+uint16_t GetEPRxStatus(uint8_t bEpNum) 
+{
+  return(_GetEPRxStatus(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : SetEPTxValid
+* Description    : Valid the endpoint Tx Status.
+* Input          : bEpNum: Endpoint Number.  
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxValid(uint8_t bEpNum)
+{
+  _SetEPTxStatus(bEpNum, EP_TX_VALID);
+}
+
+/*******************************************************************************
+* Function Name  : SetEPRxValid
+* Description    : Valid the endpoint Rx Status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxValid(uint8_t bEpNum)
+{
+  _SetEPRxStatus(bEpNum, EP_RX_VALID);
+}
+
+/*******************************************************************************
+* Function Name  : GetTxStallStatus
+* Description    : Returns the Stall status of the Tx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Tx Stall status.
+*******************************************************************************/
+uint16_t GetTxStallStatus(uint8_t bEpNum)
+{
+  return(_GetTxStallStatus(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : GetRxStallStatus
+* Description    : Returns the Stall status of the Rx endpoint. 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx Stall status.
+*******************************************************************************/
+uint16_t GetRxStallStatus(uint8_t bEpNum)
+{
+  return(_GetRxStallStatus(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : SetEPTxCount.
+* Description    : Set the Tx count.
+* Input          : bEpNum: Endpoint Number.
+*                  wCount: new count value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxCount(uint8_t bEpNum, uint16_t wCount)
+{
+}
+
+/*******************************************************************************
+* Function Name  : SetEPRxCount
+* Description    : Set the Rx count.
+* Input          : bEpNum: Endpoint Number. 
+*                  wCount: the new count value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxCount(uint8_t bEpNum, uint16_t wCount)
+{ 
+}
+
+/*******************************************************************************
+* Function Name  : ToWord
+* Description    : merge two byte in a word.
+* Input          : bh: byte high, bl: bytes low.
+* Output         : None.
+* Return         : resulted word.
+*******************************************************************************/
+uint16_t ToWord(uint8_t bh, uint8_t bl)
+{
+  uint16_t wRet;
+  wRet = (uint16_t)bl | ((uint16_t)bh << 8);
+  return(wRet);
+}
+
+/*******************************************************************************
+* Function Name  : ByteSwap
+* Description    : Swap two byte in a word.
+* Input          : wSwW: word to Swap.
+* Output         : None.
+* Return         : resulted word.
+*******************************************************************************/
+uint16_t ByteSwap(uint16_t wSwW)
+{
+  uint8_t bTemp;
+  uint16_t wRet;
+  bTemp = (uint8_t)(wSwW & 0xff);
+  wRet =  (wSwW >> 8) | ((uint16_t)bTemp << 8);
+  return(wRet);
+}
+
+#endif /* STM32F10X_CL */
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 876 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/otgd_fs_int.c

@@ -0,0 +1,876 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otgd_fs_int.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Endpoint interrupt's service routines.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifdef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x.h"
+#include "usb_type.h"
+#include "otgd_fs_int.h"
+#include "usb_lib.h"
+#include "usb_istr.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Max size of the received OUT Non periodic packet */
+#define MAX_OUT_PKT_SIZE    160
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+uint8_t USBD_Data_Buffer  [MAX_OUT_PKT_SIZE];
+__IO uint8_t IsocBuff [(ISOC_BUFFER_SZE * NUM_SUB_BUFFERS)];
+__IO uint32_t IsocBufferIdx = 0;
+
+extern USB_OTG_CORE_REGS  core_regs;
+
+__IO uint16_t SaveRState;
+__IO uint16_t SaveTState;
+
+/* Extern variables ----------------------------------------------------------*/
+extern void (*pEpInt_IN[7])(void);    /*  Handles IN  interrupts   */
+extern void (*pEpInt_OUT[7])(void);   /*  Handles OUT interrupts   */
+
+/* Private function prototypes -----------------------------------------------*/
+static uint32_t OTGD_FS_PCD_ReadDevInEP( USB_OTG_EP *ep);
+static enum usb_device_speed OTGD_FS_PCD_GetDeviceSpeed(void);
+static uint32_t OTGD_FS_PCD_WriteEmptyTxFifo(uint32_t epnum);
+
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_ModeMismatch_ISR
+* Description    : Handles the Mode Mismatch error interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_ModeMismatch_ISR(void)
+{
+  USB_OTG_int_sts_data gintsts;  
+  
+  INTR_MODEMISMATCH_Callback();
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.modemismatch = 1;
+  WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_Sof_ISR
+* Description    : Handles the Start Of Frame detected interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_Sof_ISR(void)
+{
+  USB_OTG_int_sts_data int_sts;
+  
+  /* Call user function */
+  INTR_SOFINTR_Callback();
+    
+  /* Clear interrupt */
+  int_sts.d32 = 0;
+  int_sts.b.sofintr = 1;
+  WRITE_REG32 (&core_regs.common_regs->int_sts, int_sts.d32);
+
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_RxStatusQueueLevel_ISR
+* Description    : Handles the Rx Status Queue Level Interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_RxStatusQueueLevel_ISR(void)
+{
+  USB_OTG_int_msk_data int_mask;
+  USB_OTG_dev_rx_sts_data status;
+  /* USB_OTG_int_sts_data int_sts; */
+  USB_OTG_EP *ep;
+
+  /* Disable the Rx Status Queue Level interrupt */
+  int_mask.b.rxstsqlvl = 1;
+  MODIFY_REG32( &core_regs.common_regs->int_msk, int_mask.d32, 0);
+
+  /* Get the Status from the top of the FIFO */
+  status.d32 = READ_REG32( &core_regs.common_regs->rx_stsp );
+
+  /* Get the related endpoint structure */
+  ep = OTGD_FS_PCD_GetOutEP(status.b.epnum);
+
+  switch (status.b.pktsts)
+  {
+    case STS_GOUT_NAK:
+      break;
+    case STS_DATA_UPDT:
+      if (status.b.bcnt)
+      {
+        if (ep->type == EP_TYPE_ISOC)
+        {
+          /* Call user function */
+          INTR_RXSTSQLVL_ISODU_Callback();         
+          
+          /* Copy the received buffer to the RAM */
+          OTGD_FS_ReadPacket((uint8_t*)(IsocBuff + (ISOC_BUFFER_SZE * IsocBufferIdx)), status.b.bcnt);
+          ep->xfer_buff = (uint8_t*)(IsocBuff + (ISOC_BUFFER_SZE * IsocBufferIdx));  
+          
+          /* Check if the end of the global buffer has been reached */
+          if (IsocBufferIdx == (NUM_SUB_BUFFERS - 1))
+          {
+            /* Reset the buffer index */
+            IsocBufferIdx = 0;                         
+          }
+          else
+          {
+            /* Increment the buffer index */
+            IsocBufferIdx ++;
+          }          
+        }
+        else
+        {
+          /* Copy the received buffer to the RAM */
+          OTGD_FS_ReadPacket(USBD_Data_Buffer, status.b.bcnt);
+          ep->xfer_buff = USBD_Data_Buffer;
+        }
+        
+        /* Update the endpoint structure */
+        ep->xfer_len  = status.b.bcnt;
+        ep->xfer_count += status.b.bcnt;        
+      }
+      break;
+    case STS_XFER_COMP:
+      break;
+    case STS_SETUP_COMP:
+      break;
+    case STS_SETUP_UPDT:
+      /* Copy the setup packet received in Fifo into the setup buffer in RAM */
+      OTGD_FS_ReadPacket(USBD_Data_Buffer, 8); 
+      ep->xfer_buff = USBD_Data_Buffer;
+      ep->xfer_count += status.b.bcnt;
+      ep->xfer_len  = status.b.bcnt;
+      break;
+    default:
+      break;
+  }
+
+  /* Call the user function */
+  INTR_RXSTSQLVL_Callback();
+  
+  /* Enable the Rx Status Queue Level interrupt */
+  MODIFY_REG32( &core_regs.common_regs->int_msk, 0, int_mask.d32);
+  
+  /* Clear interrupt: this is a read only bit, it cannot be cleared by register 
+     access */
+  /* int_sts.d32 = 0;
+     int_sts.b.rxstsqlvl = 1;
+     WRITE_REG32 (&core_regs.common_regs->int_sts, int_sts.d32);
+  */
+
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_NPTxFE_ISR
+* Description    : Handles the Non Periodic Tx FIFO Empty interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_NPTxFE_ISR(void )
+{
+  /* USB_OTG_int_sts_data gintsts; */
+  USB_OTG_int_msk_data gintmsk;
+  gintmsk.d32 = 0;
+
+  /* Call the user function */
+  INTR_NPTXFEMPTY_Callback();
+  
+  gintmsk.b.nptxfempty = 1;
+  MODIFY_REG32(&core_regs.common_regs->int_msk, gintmsk.d32, 0 );
+
+  /* Clear interrupt: This bit is a read only bit, cannot be cleared 
+     by register access */
+  /* gintsts.d32 = 0;
+     gintsts.b.nptxfempty = 1;
+     WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+   */
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_GInNakEff_ISR
+* Description    : Handles the Global IN Endpoints NAK Effective interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_GInNakEff_ISR(void)
+{
+  /* USB_OTG_int_sts_data gintsts; */
+  
+  /* Call user function */
+  INTR_GINNAKEFF_Callback();
+  
+  /* Clear interrupt: This is a read only bit, it cannot be cleared by register 
+     access */
+  /* gintsts.d32 = 0;
+     gintsts.b.ginnakeff = 1;
+     WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  */  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_GOutNakEff_ISR
+* Description    : Handles the Global OUT Endpoints NAK Effective interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_GOutNakEff_ISR(void)
+{
+  /* USB_OTG_int_sts_data gintsts; */
+  
+  /* Call user function */
+  INTR_GOUTNAKEFF_Callback();  
+  
+  /* Clear interrupt: This is a read only bit, it cannot be cleared by register 
+     access */
+  /* gintsts.d32 = 0;
+     gintsts.b.goutnakeff = 1;
+     WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  */  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_EarlySuspend_ISR
+* Description    : Handles the Early Suspend detected interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_EarlySuspend_ISR(void )
+{
+  USB_OTG_int_sts_data gintsts;
+  USB_OTG_int_msk_data gintmsk;
+  gintmsk.d32 = 0;
+
+  /* Call user function */
+  INTR_ERLYSUSPEND_Callback();  
+  
+  gintmsk.b.erlysuspend = 1;
+  MODIFY_REG32(&core_regs.common_regs->int_msk, gintmsk.d32, 0 );
+
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.erlysuspend = 1;
+  WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_USBSuspend_ISR
+* Description    : Handles the Suspend condition detected interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_USBSuspend_ISR(void)
+{
+  USB_OTG_int_sts_data gintsts;  
+  
+  /* Call user function */
+  INTR_USBSUSPEND_Callback();
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.usbsuspend = 1;
+  WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_UsbReset_ISR
+* Description    : This interrupt occurs when a USB Reset is detected.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_UsbReset_ISR(void)
+{
+  USB_OTG_dev_all_int_data daintmsk;
+  USB_OTG_dev_out_ep_msk_data doepmsk;
+  USB_OTG_dev_in_ep_msk_data diepmsk;
+  USB_OTG_dev_cfg_data dcfg;
+  USB_OTG_dev_ctl_data dctl;
+  USB_OTG_int_sts_data gintsts;
+
+  daintmsk.d32 = 0;
+  doepmsk.d32 = 0;
+  diepmsk.d32 = 0;
+  dcfg.d32 = 0;
+  dctl.d32 = 0;
+
+  /* Clear the Remote Wakeup Signalling */
+  dctl.b.rmtwkupsig = 1;
+  MODIFY_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32, 0 );
+
+  /* Flush the NP Tx FIFO */
+  OTGD_FS_FlushTxFifo( 0 );
+
+  daintmsk.b.inep0 = 1;
+  daintmsk.b.outep0 = 1;
+  WRITE_REG32( &core_regs.dev_regs->dev_all_int_msk, daintmsk.d32 );
+
+  doepmsk.b.setup = 1;
+  doepmsk.b.xfercompl = 1;
+  doepmsk.b.ahberr = 1;
+  doepmsk.b.epdisabled = 1;
+  WRITE_REG32( &core_regs.dev_regs->dev_out_ep_msk, doepmsk.d32 );
+
+  diepmsk.b.xfercompl = 1;
+  diepmsk.b.timeout = 1;
+  diepmsk.b.epdisabled = 1;
+  diepmsk.b.ahberr = 1;
+  diepmsk.b.intknepmis = 1;
+  WRITE_REG32( &core_regs.dev_regs->dev_in_ep_msk, diepmsk.d32 );
+
+  /* Reset Device Address */
+  dcfg.d32 = READ_REG32( &core_regs.dev_regs->dev_cfg);
+  dcfg.b.devaddr = 0;
+  WRITE_REG32( &core_regs.dev_regs->dev_cfg, dcfg.d32);
+
+
+  /* setup EP0 to receive SETUP packets */
+  OTGD_FS_PCD_EP0_OutStart();
+
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.usbreset = 1;
+  WRITE_REG32 (&core_regs.common_regs->int_sts, gintsts.d32);
+
+  /* Call the user reset function */
+  OTGD_FS_DEVICE_RESET; 
+  
+  /* Call user function */
+  INTR_USBRESET_Callback();  
+  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_EnumDone_ISR
+* Description    : Reads the device status register and set the device speed
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_EnumDone_ISR(void)
+{
+  USB_OTG_int_sts_data gintsts;
+  USB_OTG_usb_cfg_data gusbcfg;
+
+  OTGD_FS_EP0Activate();
+
+  /* Set USB turnaround time based on device speed and PHY interface. */
+  gusbcfg.d32 = READ_REG32(&core_regs.common_regs->usb_cfg);
+
+  /* Full or low speed */
+  if ( OTGD_FS_PCD_GetDeviceSpeed() == USB_SPEED_FULL)
+  {
+    gusbcfg.b.usbtrdtim = 9;
+  }
+  WRITE_REG32(&core_regs.common_regs->usb_cfg, gusbcfg.d32);
+
+  /* Call user function */
+  INTR_ENUMDONE_Callback();
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.enumdone = 1;
+  WRITE_REG32( &core_regs.common_regs->int_sts, gintsts.d32 );
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_IsoOutDrop_ISR
+* Description    : Handles the Isochrounous Out packet Dropped interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_IsoOutDrop_ISR(void)
+{
+  USB_OTG_int_sts_data gintsts;  
+  
+  /* Call user function */
+  INTR_ISOOUTDROP_Callback();
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.isooutdrop = 1;
+  WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_EOPF_ISR
+* Description    : Handles the Expexted End Of Periodic Frame interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_EOPF_ISR(void )
+{
+  USB_OTG_int_sts_data gintsts;
+  USB_OTG_int_msk_data gintmsk;
+  gintmsk.d32 = 0;
+
+  gintmsk.b.eopframe = 1;
+  MODIFY_REG32(&core_regs.common_regs->int_msk, gintmsk.d32, 0 );
+
+  /* Call user function */
+  INTR_EOPFRAME_Callback();
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.eopframe = 1;
+  WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_EPMismatch_ISR
+* Description    : Handles the Endpoint Mismatch error interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_EPMismatch_ISR(void)
+{
+  USB_OTG_int_sts_data gintsts;  
+  
+  /* Call user function */
+  INTR_EPMISMATCH_Callback();
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.epmismatch = 1;
+  WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_InEP_ISR
+* Description    : Handles all IN endpoints interrupts.
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_InEP_ISR(void)
+{
+  USB_OTG_dev_in_ep_int_data diepint;
+
+  uint32_t ep_intr;
+  uint32_t epnum = 0;
+  USB_OTG_EP *ep;
+  uint32_t fifoemptymsk;
+  
+  diepint.d32 = 0;
+  ep_intr = OTGD_FS_ReadDevAllInEPItr();
+  while ( ep_intr )
+  {
+    if (ep_intr&0x1) /* In ITR */
+    {
+      ep = OTGD_FS_PCD_GetInEP(epnum);
+      diepint.d32 = OTGD_FS_PCD_ReadDevInEP(ep); /* Get In ITR status */
+      if ( diepint.b.xfercompl )
+      {
+        fifoemptymsk = 0x1 << ep->num;
+        MODIFY_REG32(&core_regs.dev_regs->dev_fifo_empty_msk, fifoemptymsk, 0);
+
+        /* Clear the Interrupt flag */ 
+        CLEAR_IN_EP_INTR(epnum, xfercompl);
+        
+        if (epnum == 0)  
+        {        
+          /* Call the core IN process for EP0 */ 
+          In0_Process();
+          
+          /* before terminate set Tx & Rx status */
+          OTG_DEV_SetEPRxStatus(epnum, SaveRState);
+          OTG_DEV_SetEPTxStatus(epnum, SaveTState);
+        }
+        else
+        {
+          OTG_DEV_SetEPTxStatus(EP1_IN, DEV_EP_TX_NAK);
+
+          (*pEpInt_IN[epnum -1])();
+          
+          /* Toggle Endpoint frame ID */
+          if (ep->even_odd_frame == 0)
+            ep->even_odd_frame = 1;
+          else
+            ep->even_odd_frame = 0;
+        } 
+      }
+      if ( diepint.b.ahberr )
+      {
+        CLEAR_IN_EP_INTR(epnum, ahberr);
+      }
+      if ( diepint.b.timeout )
+      {
+        CLEAR_IN_EP_INTR(epnum, timeout);
+      }
+      if (diepint.b.intktxfemp)
+      {
+        CLEAR_IN_EP_INTR(epnum, intktxfemp);
+      }
+      if (diepint.b.intknepmis)
+      {
+        CLEAR_IN_EP_INTR(epnum, intknepmis);
+      }
+      if (diepint.b.inepnakeff)
+      {
+        CLEAR_IN_EP_INTR(epnum, inepnakeff);
+      }
+      if (diepint.b.emptyintr)
+      {      
+         if ((epnum == 0) || (OTG_DEV_GetEPTxStatus(epnum) == DEV_EP_TX_VALID))
+        {
+          OTGD_FS_PCD_WriteEmptyTxFifo(epnum);          
+        }
+
+        CLEAR_IN_EP_INTR(epnum, emptyintr);          
+      }
+      if ( diepint.b.epdisabled )
+      { 
+        /* Reset Endpoint Frame ID to 0 */
+        ep->even_odd_frame = 0;
+
+        CLEAR_IN_EP_INTR(epnum, epdisabled);
+      }      
+    }
+    epnum++;
+    ep_intr >>= 1;
+  }
+
+  /* Call user function */
+  INTR_INEPINTR_Callback();
+  
+  return 1;
+}
+
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_OutEP_ISR
+* Description    : Handles all OUT endpoints interrupts.
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_OutEP_ISR(void)
+{
+  uint32_t ep_intr;
+  USB_OTG_dev_out_ep_int_data doepint;
+  uint32_t epnum = 0;
+  USB_OTG_EP *ep;
+
+  doepint.d32 = 0;
+
+  /* Read in the device interrupt bits */
+  ep_intr = OTGD_FS_ReadDevAllOutEp_itr();
+  
+  while ( ep_intr )
+  {
+    if (ep_intr&0x1)
+    {
+      /* Get EP pointer */
+      ep = OTGD_FS_PCD_GetOutEP(epnum);
+      doepint.d32 = OTGD_FS_ReadDevOutEP_itr(ep);
+
+      /* Transfer complete */
+      if ( doepint.b.xfercompl )
+      {
+        /* Clear the bit in DOEPINTn for this interrupt */
+        CLEAR_OUT_EP_INTR(epnum, xfercompl);
+        
+        if (epnum == 0)  
+        { 
+          /* Call the OUT process for the EP0 */
+          Out0_Process();
+        }
+        else
+        {
+          (*pEpInt_OUT[epnum-1])();
+        }
+      }
+      /* Endpoint disable  */
+      if ( doepint.b.epdisabled )
+      {
+        /* Clear the bit in DOEPINTn for this interrupt */
+        CLEAR_OUT_EP_INTR(epnum, epdisabled);
+      }
+      /* AHB Error */
+      if ( doepint.b.ahberr )
+      {
+        CLEAR_OUT_EP_INTR(epnum, ahberr);
+      }
+      /* Setup Phase Done (control EPs) */
+      if ( doepint.b.setup )
+      {
+        if (epnum == 0)  
+        {        
+          /* Call the SETUP process for the EP0 */
+          Setup0_Process();  
+
+          /* Before exit, update the Tx status */
+          OTG_DEV_SetEPTxStatus(0x80, SaveTState);  
+        }
+        else
+        {
+          /* Other control endpoints */
+        }  
+        
+        /* Clear the EP Interrupt */
+        CLEAR_OUT_EP_INTR(epnum, setup);
+      }
+    }
+    epnum++;
+    ep_intr >>= 1;
+  }
+
+  /* Call user function */
+  INTR_OUTEPINTR_Callback();  
+  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_IncomplIsoIn_ISR
+* Description    : Handles the Incomplete Isochrous IN tranfer error interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_IncomplIsoIn_ISR(void)
+{
+  USB_OTG_int_sts_data gintsts;  
+
+  /* Call user function */
+  INTR_INCOMPLISOIN_Callback(); 
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.incomplisoin = 1;
+  WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_IncomplIsoOut_ISR
+* Description    : Handles the Incomplete Isochrous OUT tranfer error interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_IncomplIsoOut_ISR(void)
+{
+  USB_OTG_int_sts_data gintsts;  
+
+  /* Call user function */
+  INTR_INCOMPLISOOUT_Callback();
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.outepintr = 1;
+  WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
+  
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_Handle_Wakeup_ISR
+* Description    : Handles the Wakeup or Remote Wakeup detected interrupt.
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_Handle_Wakeup_ISR(void)
+{
+  USB_OTG_int_sts_data gintsts;
+
+  /* Call user function */
+  INTR_WKUPINTR_Callback();
+  
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.wkupintr = 1;
+  WRITE_REG32 (&core_regs.common_regs->int_sts, gintsts.d32);
+
+  return 1;
+}
+
+
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_GetDeviceSpeed
+* Description    : Get the device speed from the device status register
+* Input          : None
+* Output         : None
+* Return         : The Device speed value.
+*******************************************************************************/
+static enum usb_device_speed OTGD_FS_PCD_GetDeviceSpeed(void)
+{
+  USB_OTG_dev_sts_data dsts;
+  enum usb_device_speed speed = USB_SPEED_UNKNOWN;
+  dsts.d32 = READ_REG32(&core_regs.dev_regs->dev_sts);
+
+  switch (dsts.b.enumspd)
+  {
+    case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+      speed = USB_SPEED_HIGH;
+      break;
+    case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+    case DSTS_ENUMSPD_FS_PHY_48MHZ:
+      speed = USB_SPEED_FULL;
+      break;
+
+    case DSTS_ENUMSPD_LS_PHY_6MHZ:
+      speed = USB_SPEED_LOW;
+      break;
+  }
+
+  return speed;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_ReadDevInEP
+* Description    : Reads all the Endpoints flags.
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static uint32_t OTGD_FS_PCD_ReadDevInEP( USB_OTG_EP *ep)
+{
+  uint32_t v, msk, emp;
+  msk = READ_REG32(&core_regs.dev_regs->dev_in_ep_msk);
+  emp = READ_REG32(&core_regs.dev_regs->dev_fifo_empty_msk);
+  msk |= ((emp >> ep->num) & 0x1) << 7;
+  v = READ_REG32(&core_regs.inep_regs[ep->num]->dev_in_ep_int) & msk;
+  return v;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_WriteEmptyTxFifo
+* Description    : Checks Fifo for the next packet to be loaded.
+* Input          : None
+* Output         : None
+* Return         : Status
+*******************************************************************************/
+static uint32_t OTGD_FS_PCD_WriteEmptyTxFifo(uint32_t epnum)
+{
+  USB_OTG_dev_tx_fifo_sts_data txstatus;
+  USB_OTG_EP *ep;
+  uint32_t len = 0;
+  uint32_t dwords;
+  USB_OTG_dev_ep_ctl_data  depctl;
+  
+  txstatus.d32 = 0;
+
+  ep = OTGD_FS_PCD_GetInEP(epnum); 
+  
+  len = ep->xfer_len - ep->xfer_count;
+
+  if (len > ep->maxpacket)
+  {
+    len = ep->maxpacket;
+  }
+  
+  dwords = (len + 3) / 4;
+  txstatus.d32 = READ_REG32( &core_regs.inep_regs[epnum]->dev_tx_fifo_sts);
+
+  /* Manage the case of 0-length data packets toggling data PID */
+  if ((ep->xfer_len == 0) && (ep->xfer_count == 0))
+  {
+    if (ep->num > 0)
+    {
+      depctl.d32 = READ_REG32( &core_regs.inep_regs[epnum]->dev_in_ep_ctl);      
+      if (ep->even_odd_frame == 1)
+      {
+        depctl.b.setd0pid = 0;
+        depctl.b.setd1pid = 1;
+      }
+      else
+      {
+        depctl.b.setd0pid = 1;
+        depctl.b.setd1pid = 0;
+      }      
+      WRITE_REG32( &core_regs.inep_regs[epnum]->dev_in_ep_ctl, depctl.d32);           
+    }
+  }
+
+  
+  while  (txstatus.b.txfspcavail > dwords &&
+          ep->xfer_count < ep->xfer_len &&
+          ep->xfer_len != 0)
+  {
+    if (ep->num > 0)
+    {
+      depctl.d32 = READ_REG32( &core_regs.inep_regs[epnum]->dev_in_ep_ctl);      
+      if (ep->even_odd_frame == 0)
+      {
+        depctl.b.setd0pid = 1;
+        depctl.b.setd1pid = 0;
+      }
+      else
+      {
+        depctl.b.setd0pid = 0;
+        depctl.b.setd1pid = 1;
+      }      
+      WRITE_REG32( &core_regs.inep_regs[epnum]->dev_in_ep_ctl, depctl.d32);           
+    }
+    
+    /* Write the FIFO */
+    len = ep->xfer_len - ep->xfer_count;
+
+    if (len > ep->maxpacket)
+    {
+      len = ep->maxpacket;
+    }
+    dwords = (len + 3) / 4;
+
+    OTGD_FS_WritePacket(ep->xfer_buff, epnum, len);    
+    
+    ep->xfer_count += len;
+
+    txstatus.d32 = READ_REG32(&core_regs.inep_regs[epnum]->dev_tx_fifo_sts);   
+  }
+  
+  return 1;
+}
+#endif  /* STM32F10X_CL */
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 445 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/otgd_fs_pcd.c

@@ -0,0 +1,445 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : otgd_fs_pcd.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Peripheral Device Interface low layer.
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifdef STM32F10X_CL
+
+#include "usb_lib.h"
+#include "otgd_fs_cal.h"
+#include "otgd_fs_pcd.h"
+
+USB_OTG_PCD_DEV USB_OTG_PCD_dev;
+
+extern USB_OTG_CORE_REGS     core_regs;
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_Init
+* Description    : Initialize the USB Device portion of the driver.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void OTGD_FS_PCD_Init(void)
+{
+  uint32_t i;
+  USB_OTG_EP *ep;
+
+  ep = &USB_OTG_PCD_dev.ep0;
+  USB_OTG_PCD_dev.ep0state = 0;
+
+  /* Init ep structure */
+  ep->num = 0;
+  ep->tx_fifo_num = 0;
+
+  /* Control until ep is actvated */
+  ep->type = EP_TYPE_CTRL;
+  ep->maxpacket = MAX_PACKET_SIZE;
+
+  ep->xfer_buff = 0;
+  ep->xfer_len = 0;
+
+  for (i = 1; i < MAX_TX_FIFOS ; i++)
+  {
+    ep = &USB_OTG_PCD_dev.in_ep[i-1];
+
+    /* Init ep structure */
+    ep->is_in = 1;
+    ep->num = i;
+    ep->tx_fifo_num = i;
+
+    /* Control until ep is actvated */
+    ep->type = EP_TYPE_CTRL;
+    ep->maxpacket = MAX_PACKET_SIZE;
+    ep->xfer_buff = 0;
+    ep->xfer_len = 0;
+  }
+
+  for (i = 1; i < MAX_TX_FIFOS; i++)
+  {
+    ep = &USB_OTG_PCD_dev.out_ep[i-1];
+
+    /* Init ep structure */
+    ep->is_in = 0;
+    ep->num = i;
+    ep->tx_fifo_num = i;
+
+    /* Control until ep is activated */
+    ep->type = EP_TYPE_CTRL;
+    ep->maxpacket = MAX_PACKET_SIZE;
+    ep->xfer_buff = 0;
+    ep->xfer_len = 0;
+  }
+
+  USB_OTG_PCD_dev.ep0.maxpacket = MAX_EP0_SIZE;
+  USB_OTG_PCD_dev.ep0.type = EP_TYPE_CTRL;
+
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_EP_Open
+* Description    : Configure an Endpoint
+* Input          : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_PCD_EP_Open(EP_DESCRIPTOR *epdesc)
+{
+  USB_OTG_EP *ep;
+
+
+  if ((0x80 & epdesc->bEndpointAddress) != 0)
+  {
+    ep = OTGD_FS_PCD_GetInEP(epdesc->bEndpointAddress & 0x7F);
+  }
+  else
+  {
+    ep = OTGD_FS_PCD_GetOutEP(epdesc->bEndpointAddress & 0x7F);
+  }
+
+  ep->num   = epdesc->bEndpointAddress & 0x7F;
+  ep->is_in = (0x80 & epdesc->bEndpointAddress) != 0;
+  ep->maxpacket = epdesc->wMaxPacketSize;
+  ep->type = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+
+  if (ep->is_in)
+  {
+    /* Assign a Tx FIFO */
+    ep->tx_fifo_num = ep->num;
+  }
+  
+  /* Set initial data PID. */
+  if ((epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK )
+  {
+    ep->data_pid_start = 0;
+  }
+
+  OTGD_FS_EPActivate(ep );
+
+  return 0;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_EP_Close
+* Description    : Called when an EP is disabled
+* Input          : Endpoint address.
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_PCD_EP_Close(uint8_t  ep_addr)
+{
+
+  USB_OTG_EP *ep;
+
+  if ((0x80 & ep_addr) != 0)
+  {
+    ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
+  }
+  else
+  {
+    ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
+  }
+
+  ep->num   = ep_addr & 0x7F;
+  ep->is_in = (0x80 & ep_addr) != 0;
+
+  OTGD_FS_EPDeactivate(ep );
+  return 0;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_EP_Read
+* Description    : Read data from Fifo
+* Input          : Endpoint address.
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t OTGD_FS_PCD_EP_Read (uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
+{
+  USB_OTG_EP *ep;
+  uint32_t i;
+
+  ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
+
+  /* copy received data into application buffer */
+  for (i = 0 ; i < buf_len ; i++)
+  {
+    pbuf[i] = ep->xfer_buff[i];
+  }
+
+  /*setup and start the Xfer */
+  ep->xfer_buff = pbuf;
+  ep->xfer_len = buf_len;
+  ep->xfer_count = 0;
+  ep->is_in = 0;
+  ep->num = ep_addr & 0x7F;
+
+  if ( ep->num == 0 )
+  {
+    OTGD_FS_EP0StartXfer(ep);
+  }
+  else if (USB_OTG_PCD_dev.ep0state == 0)
+  {
+    OTGD_FS_EPStartXfer( ep );
+  }
+
+  return 0;
+}
+
+/*******************************************************************************
+* Function Name  : USBF_EP_Write
+* Description    : Read data from Fifo
+* Input          : ep
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t  OTGD_FS_PCD_EP_Write (uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
+{
+  USB_OTG_EP *ep;
+
+  ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7f);
+
+  /* assign data to EP structure buffer */
+  ep->xfer_buff = pbuf;
+
+  /* Setup and start the Transfer */
+  ep->xfer_count = 0;
+  ep->xfer_len = buf_len;
+  ep->is_in = 1;
+  ep->num = ep_addr & 0x7F;
+  
+  if ( ep->num == 0 )
+  {
+    OTGD_FS_EP0StartXfer(ep);
+  }
+  else if (USB_OTG_PCD_dev.ep0state == 0)
+  {
+    OTGD_FS_EPStartXfer( ep );
+  }
+
+  return 0;
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_EP_Stall
+* Description    : Stall an endpoint.
+* Input          : Endpoint Address.
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t  OTGD_FS_PCD_EP_Stall (uint8_t ep_addr)
+{
+  USB_OTG_EP *ep;
+
+  if ((0x80 & ep_addr) != 0)
+  {
+    ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
+  }
+  else
+  {
+    ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
+  }
+
+  ep->num   = ep_addr & 0x7F;
+  ep->is_in = ((ep_addr & 0x80) == 0x80) ? 1 : 0;
+
+  OTGD_FS_EPSetStall(ep);
+  return (0);
+}
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_EP_ClrStall
+* Description    : Clear stall condition on endpoints.
+* Input          : Endpoint Address.
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t  OTGD_FS_PCD_EP_ClrStall (uint8_t ep_addr)
+{
+
+  USB_OTG_EP *ep;
+
+  if ((0x80 & ep_addr) != 0)
+  {
+    ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
+  }
+  else
+  {
+    ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
+  }
+
+  ep->num   = ep_addr & 0x7F;
+  ep->is_in = ((ep_addr & 0x80) == 0x80) ? 1 : 0;
+
+  OTGD_FS_EPClearStall(ep);
+
+  return (0);
+}
+
+/*******************************************************************************
+* Function Name  : USBF_FCD_EP_Flush()
+* Description    : This Function flushes the buffer.
+* Input          : Endpoint Address.
+* Output         : None
+* Return         : status
+*******************************************************************************/
+uint32_t  OTGD_FS_PCD_EP_Flush (uint8_t ep_addr)
+{
+
+  uint8_t  is_out;
+  uint8_t  ep_nbr;
+
+  ep_nbr   = ep_addr & 0x7F;
+  is_out = ((ep_addr & 0x80) == 0x80) ? 0 : 1;
+
+  if (is_out == 0)
+  {
+    OTGD_FS_FlushTxFifo(ep_nbr);
+  }
+  else
+  {
+    OTGD_FS_FlushRxFifo();
+  }
+  OTGD_FS_PCD_EP_ClrStall(ep_addr);
+  return (0);
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_EP_SetAddress
+* Description    : This Function set USB device address
+* Input          : The new device Address to be set.
+* Output         : None
+* Return         : status
+*******************************************************************************/
+void  OTGD_FS_PCD_EP_SetAddress (uint8_t address)
+{
+
+  USB_OTG_dev_cfg_data dcfg;
+  dcfg.d32 = 0;
+
+  dcfg.b.devaddr = address;
+  MODIFY_REG32( &core_regs.dev_regs->dev_cfg, 0, dcfg.d32);
+}
+
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_GetInEP
+* Description    : This function returns pointer to IN EP struct with number ep_num
+* Input          : Endpoint Number.
+* Output         : None
+* Return         : status
+*******************************************************************************/
+USB_OTG_EP* OTGD_FS_PCD_GetInEP(uint32_t ep_num)
+{
+  uint32_t i;
+  if (ep_num == 0)
+  {
+    return &USB_OTG_PCD_dev.ep0;
+  }
+  else
+  {
+    for (i = 0; i < MAX_TX_FIFOS; ++i)
+    {
+      if (USB_OTG_PCD_dev.in_ep[i].num == ep_num)
+        return &USB_OTG_PCD_dev.in_ep[i];
+    }
+    return 0;
+  }
+}
+/*******************************************************************************
+* Function Name  : USBF_GetOutEP
+* Description    : returns pointer to OUT EP struct with number ep_num
+* Input          : Endpoint Number.
+* Output         : None
+* Return         : USBF_EP
+*******************************************************************************/
+USB_OTG_EP* OTGD_FS_PCD_GetOutEP(uint32_t ep_num)
+{
+  uint32_t i;
+  if (ep_num == 0)
+  {
+    return &USB_OTG_PCD_dev.ep0;
+  }
+  else
+  {
+    for (i = 0; i < MAX_TX_FIFOS; ++i)
+    {
+      if (USB_OTG_PCD_dev.out_ep[i].num == ep_num)
+        return &USB_OTG_PCD_dev.out_ep[i];
+    }
+    return 0;
+  }
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_DevConnect
+* Description    : Connect device
+* Input         : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+void  OTGD_FS_PCD_DevConnect(void)
+{
+
+  USB_OTG_dev_ctl_data dctl;
+
+  dctl.d32 = READ_REG32(&core_regs.dev_regs->dev_ctl);
+
+  /* Connect device */
+  dctl.b.sftdiscon  = 0;
+  WRITE_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32);
+  mDELAY(25);
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_DevDisconnect
+* Description    : Disconnect device
+* Input         : None
+* Output         : None
+* Return         : status
+*******************************************************************************/
+void  OTGD_FS_PCD_DevDisconnect (void)
+{
+
+  USB_OTG_dev_ctl_data dctl;
+
+  dctl.d32 = READ_REG32(&core_regs.dev_regs->dev_ctl);
+
+  /* Disconnect device for 20ms */
+  dctl.b.sftdiscon  = 1;
+  WRITE_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32);
+  mDELAY(25);
+}
+
+/*******************************************************************************
+* Function Name  : OTGD_FS_PCD_EP0_OutStart
+* Description    : Configures EPO to receive SETUP packets.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void OTGD_FS_PCD_EP0_OutStart(void)
+{
+
+  USB_OTG_dev_ep_txfer_size0_data doeptsize0;
+
+  doeptsize0.d32 = 0;
+  doeptsize0.b.supcnt = 3;
+  doeptsize0.b.pktcnt = 1;
+  doeptsize0.b.xfersize = 8 * 3;
+
+  WRITE_REG32( &core_regs.outep_regs[0]->dev_out_ep_txfer_siz, doeptsize0.d32 );
+
+}
+
+#endif /* STM32F10X_CL */
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
+

+ 1088 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_core.c

@@ -0,0 +1,1088 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_core.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Standard protocol processing (USB v2.0)
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define ValBit(VAR,Place)    (VAR & (1 << Place))
+#define SetBit(VAR,Place)    (VAR |= (1 << Place))
+#define ClrBit(VAR,Place)    (VAR &= ((1 << Place) ^ 255))
+
+#ifdef STM32F10X_CL
+ #define Send0LengthData()  {OTGD_FS_PCD_EP_Write (0, 0, 0) ; vSetEPTxStatus(EP_TX_VALID);}
+#else
+#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \
+    vSetEPTxStatus(EP_TX_VALID); \
+  }
+#endif /* STM32F10X_CL */
+
+#define vSetEPRxStatus(st) (SaveRState = st)
+#define vSetEPTxStatus(st) (SaveTState = st)
+
+#define USB_StatusIn() Send0LengthData()
+#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID)
+
+#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */
+#define StatusInfo1 StatusInfo.bw.bb0
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+uint16_t_uint8_t StatusInfo;
+
+bool Data_Mul_MaxPacketSize = FALSE;
+/* Private function prototypes -----------------------------------------------*/
+static void DataStageOut(void);
+static void DataStageIn(void);
+static void NoData_Setup0(void);
+static void Data_Setup0(void);
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : Standard_GetConfiguration.
+* Description    : Return the current configuration variable address.
+* Input          : Length - How many bytes are needed.
+* Output         : None.
+* Return         : Return 1 , if the request is invalid when "Length" is 0.
+*                  Return "Buffer" if the "Length" is not 0.
+*******************************************************************************/
+uint8_t *Standard_GetConfiguration(uint16_t Length)
+{
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength =
+      sizeof(pInformation->Current_Configuration);
+    return 0;
+  }
+  pUser_Standard_Requests->User_GetConfiguration();
+  return (uint8_t *)&pInformation->Current_Configuration;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_SetConfiguration.
+* Description    : This routine is called to set the configuration value
+*                  Then each class should configure device themself.
+* Input          : None.
+* Output         : None.
+* Return         : Return USB_SUCCESS, if the request is performed.
+*                  Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_SetConfiguration(void)
+{
+
+  if ((pInformation->USBwValue0 <=
+      Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0)
+      && (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/
+  {
+    pInformation->Current_Configuration = pInformation->USBwValue0;
+    pUser_Standard_Requests->User_SetConfiguration();
+    return USB_SUCCESS;
+  }
+  else
+  {
+    return USB_UNSUPPORT;
+  }
+}
+
+/*******************************************************************************
+* Function Name  : Standard_GetInterface.
+* Description    : Return the Alternate Setting of the current interface.
+* Input          : Length - How many bytes are needed.
+* Output         : None.
+* Return         : Return 0, if the request is invalid when "Length" is 0.
+*                  Return "Buffer" if the "Length" is not 0.
+*******************************************************************************/
+uint8_t *Standard_GetInterface(uint16_t Length)
+{
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength =
+      sizeof(pInformation->Current_AlternateSetting);
+    return 0;
+  }
+  pUser_Standard_Requests->User_GetInterface();
+  return (uint8_t *)&pInformation->Current_AlternateSetting;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_SetInterface.
+* Description    : This routine is called to set the interface.
+*                  Then each class should configure the interface them self.
+* Input          : None.
+* Output         : None.
+* Return         : - Return USB_SUCCESS, if the request is performed.
+*                  - Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_SetInterface(void)
+{
+  RESULT Re;
+  /*Test if the specified Interface and Alternate Setting are supported by
+    the application Firmware*/
+  Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0);
+
+  if (pInformation->Current_Configuration != 0)
+  {
+    if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0)
+        || (pInformation->USBwValue1 != 0))
+    {
+      return  USB_UNSUPPORT;
+    }
+    else if (Re == USB_SUCCESS)
+    {
+      pUser_Standard_Requests->User_SetInterface();
+      pInformation->Current_Interface = pInformation->USBwIndex0;
+      pInformation->Current_AlternateSetting = pInformation->USBwValue0;
+      return USB_SUCCESS;
+    }
+
+  }
+
+  return USB_UNSUPPORT;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_GetStatus.
+* Description    : Copy the device request data to "StatusInfo buffer".
+* Input          : - Length - How many bytes are needed.
+* Output         : None.
+* Return         : Return 0, if the request is at end of data block,
+*                  or is invalid when "Length" is 0.
+*******************************************************************************/
+uint8_t *Standard_GetStatus(uint16_t Length)
+{
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength = 2;
+    return 0;
+  }
+
+  /* Reset Status Information */
+  StatusInfo.w = 0;
+
+  if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+  {
+    /*Get Device Status */
+    uint8_t Feature = pInformation->Current_Feature;
+
+    /* Remote Wakeup enabled */
+    if (ValBit(Feature, 5))
+    {
+      SetBit(StatusInfo0, 1);
+    }
+    else
+    {
+      ClrBit(StatusInfo0, 1);
+    }      
+
+    /* Bus-powered */
+    if (ValBit(Feature, 6))
+    {
+      SetBit(StatusInfo0, 0);
+    }
+    else /* Self-powered */
+    {
+      ClrBit(StatusInfo0, 0);
+    }
+  }
+  /*Interface Status*/
+  else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+  {
+    return (uint8_t *)&StatusInfo;
+  }
+  /*Get EndPoint Status*/
+  else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
+  {
+    uint8_t Related_Endpoint;
+    uint8_t wIndex0 = pInformation->USBwIndex0;
+
+    Related_Endpoint = (wIndex0 & 0x0f);
+    if (ValBit(wIndex0, 7))
+    {
+      /* IN endpoint */
+      if (_GetTxStallStatus(Related_Endpoint))
+      {
+        SetBit(StatusInfo0, 0); /* IN Endpoint stalled */
+      }
+    }
+    else
+    {
+      /* OUT endpoint */
+      if (_GetRxStallStatus(Related_Endpoint))
+      {
+        SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */
+      }
+    }
+
+  }
+  else
+  {
+    return NULL;
+  }
+  pUser_Standard_Requests->User_GetStatus();
+  return (uint8_t *)&StatusInfo;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_ClearFeature.
+* Description    : Clear or disable a specific feature.
+* Input          : None.
+* Output         : None.
+* Return         : - Return USB_SUCCESS, if the request is performed.
+*                  - Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_ClearFeature(void)
+{
+  uint32_t     Type_Rec = Type_Recipient;
+  uint32_t     Status;
+
+
+  if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+  {/*Device Clear Feature*/
+    ClrBit(pInformation->Current_Feature, 5);
+    return USB_SUCCESS;
+  }
+  else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
+  {/*EndPoint Clear Feature*/
+    DEVICE* pDev;
+    uint32_t Related_Endpoint;
+    uint32_t wIndex0;
+    uint32_t rEP;
+
+    if ((pInformation->USBwValue != ENDPOINT_STALL)
+        || (pInformation->USBwIndex1 != 0))
+    {
+      return USB_UNSUPPORT;
+    }
+
+    pDev = &Device_Table;
+    wIndex0 = pInformation->USBwIndex0;
+    rEP = wIndex0 & ~0x80;
+    Related_Endpoint = ENDP0 + rEP;
+
+    if (ValBit(pInformation->USBwIndex0, 7))
+    {
+      /*Get Status of endpoint & stall the request if the related_ENdpoint
+      is Disabled*/
+      Status = _GetEPTxStatus(Related_Endpoint);
+    }
+    else
+    {
+      Status = _GetEPRxStatus(Related_Endpoint);
+    }
+
+    if ((rEP >= pDev->Total_Endpoint) || (Status == 0)
+        || (pInformation->Current_Configuration == 0))
+    {
+      return USB_UNSUPPORT;
+    }
+
+
+    if (wIndex0 & 0x80)
+    {
+      /* IN endpoint */
+      if (_GetTxStallStatus(Related_Endpoint ))
+      {
+      #ifndef STM32F10X_CL
+        ClearDTOG_TX(Related_Endpoint);
+      #endif /* STM32F10X_CL */
+        SetEPTxStatus(Related_Endpoint, EP_TX_VALID);
+      }
+    }
+    else
+    {
+      /* OUT endpoint */
+      if (_GetRxStallStatus(Related_Endpoint))
+      {
+        if (Related_Endpoint == ENDP0)
+        {
+          /* After clear the STALL, enable the default endpoint receiver */
+          SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize);
+          _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
+        }
+        else
+        {
+        #ifndef STM32F10X_CL
+          ClearDTOG_RX(Related_Endpoint);
+        #endif /* STM32F10X_CL */
+          _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
+        }
+      }
+    }
+    pUser_Standard_Requests->User_ClearFeature();
+    return USB_SUCCESS;
+  }
+
+  return USB_UNSUPPORT;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_SetEndPointFeature
+* Description    : Set or enable a specific feature of EndPoint
+* Input          : None.
+* Output         : None.
+* Return         : - Return USB_SUCCESS, if the request is performed.
+*                  - Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_SetEndPointFeature(void)
+{
+  uint32_t    wIndex0;
+  uint32_t    Related_Endpoint;
+  uint32_t    rEP;
+  uint32_t    Status;
+
+  wIndex0 = pInformation->USBwIndex0;
+  rEP = wIndex0 & ~0x80;
+  Related_Endpoint = ENDP0 + rEP;
+
+  if (ValBit(pInformation->USBwIndex0, 7))
+  {
+    /* get Status of endpoint & stall the request if the related_ENdpoint
+    is Disabled*/
+    Status = _GetEPTxStatus(Related_Endpoint);
+  }
+  else
+  {
+    Status = _GetEPRxStatus(Related_Endpoint);
+  }
+
+  if (Related_Endpoint >= Device_Table.Total_Endpoint
+      || pInformation->USBwValue != 0 || Status == 0
+      || pInformation->Current_Configuration == 0)
+  {
+    return USB_UNSUPPORT;
+  }
+  else
+  {
+    if (wIndex0 & 0x80)
+    {
+      /* IN endpoint */
+      _SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
+    }
+
+    else
+    {
+      /* OUT endpoint */
+      _SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
+    }
+  }
+  pUser_Standard_Requests->User_SetEndPointFeature();
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_SetDeviceFeature.
+* Description    : Set or enable a specific feature of Device.
+* Input          : None.
+* Output         : None.
+* Return         : - Return USB_SUCCESS, if the request is performed.
+*                  - Return USB_UNSUPPORT, if the request is invalid.
+*******************************************************************************/
+RESULT Standard_SetDeviceFeature(void)
+{
+  SetBit(pInformation->Current_Feature, 5);
+  pUser_Standard_Requests->User_SetDeviceFeature();
+  return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : Standard_GetDescriptorData.
+* Description    : Standard_GetDescriptorData is used for descriptors transfer.
+*                : This routine is used for the descriptors resident in Flash
+*                  or RAM
+*                  pDesc can be in either Flash or RAM
+*                  The purpose of this routine is to have a versatile way to
+*                  response descriptors request. It allows user to generate
+*                  certain descriptors with software or read descriptors from
+*                  external storage part by part.
+* Input          : - Length - Length of the data in this transfer.
+*                  - pDesc - A pointer points to descriptor struct.
+*                  The structure gives the initial address of the descriptor and
+*                  its original size.
+* Output         : None.
+* Return         : Address of a part of the descriptor pointed by the Usb_
+*                  wOffset The buffer pointed by this address contains at least
+*                  Length bytes.
+*******************************************************************************/
+uint8_t *Standard_GetDescriptorData(uint16_t Length, ONE_DESCRIPTOR *pDesc)
+{
+  uint32_t  wOffset;
+
+  wOffset = pInformation->Ctrl_Info.Usb_wOffset;
+  if (Length == 0)
+  {
+    pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset;
+    return 0;
+  }
+
+  return pDesc->Descriptor + wOffset;
+}
+
+/*******************************************************************************
+* Function Name  : DataStageOut.
+* Description    : Data stage of a Control Write Transfer.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void DataStageOut(void)
+{
+  ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
+  uint32_t save_rLength;
+
+  save_rLength = pEPinfo->Usb_rLength;
+
+  if (pEPinfo->CopyData && save_rLength)
+  {
+    uint8_t *Buffer;
+    uint32_t Length;
+
+    Length = pEPinfo->PacketSize;
+    if (Length > save_rLength)
+    {
+      Length = save_rLength;
+    }
+
+    Buffer = (*pEPinfo->CopyData)(Length);
+    pEPinfo->Usb_rLength -= Length;
+    pEPinfo->Usb_rOffset += Length;
+
+  #ifdef STM32F10X_CL  
+    OTGD_FS_PCD_EP_Read(ENDP0, Buffer, Length); 
+  #else  
+    PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length);
+  #endif  /* STM32F10X_CL */
+  }
+
+  if (pEPinfo->Usb_rLength != 0)
+  {
+    vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */
+    SetEPTxCount(ENDP0, 0);
+    vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */
+  }
+  /* Set the next State*/
+  if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize)
+  {
+    pInformation->ControlState = OUT_DATA;
+  }
+  else
+  {
+    if (pEPinfo->Usb_rLength > 0)
+    {
+      pInformation->ControlState = LAST_OUT_DATA;
+    }
+    else if (pEPinfo->Usb_rLength == 0)
+    {
+      pInformation->ControlState = WAIT_STATUS_IN;
+      USB_StatusIn();
+    }
+  }
+}
+
+/*******************************************************************************
+* Function Name  : DataStageIn.
+* Description    : Data stage of a Control Read Transfer.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void DataStageIn(void)
+{
+  ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
+  uint32_t save_wLength = pEPinfo->Usb_wLength;
+  uint32_t ControlState = pInformation->ControlState;
+
+  uint8_t *DataBuffer;
+  uint32_t Length;
+
+  if ((save_wLength == 0) && (ControlState == LAST_IN_DATA))
+  {
+    if(Data_Mul_MaxPacketSize == TRUE)
+    {
+      /* No more data to send and empty packet */
+      Send0LengthData();
+      ControlState = LAST_IN_DATA;
+      Data_Mul_MaxPacketSize = FALSE;
+    }
+    else 
+    {
+      /* No more data to send so STALL the TX Status*/
+      ControlState = WAIT_STATUS_OUT;
+
+    #ifdef STM32F10X_CL      
+      OTGD_FS_PCD_EP_Read (ENDP0, 0, 0);
+    #endif  /* STM32F10X_CL */ 
+    
+    #ifndef STM32F10X_CL 
+      vSetEPTxStatus(EP_TX_STALL);
+    #endif  /* STM32F10X_CL */ 
+    }
+    
+    goto Expect_Status_Out;
+  }
+
+  Length = pEPinfo->PacketSize;
+  ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA;
+
+  if (Length > save_wLength)
+  {
+    Length = save_wLength;
+  }
+
+  DataBuffer = (*pEPinfo->CopyData)(Length);
+
+#ifdef STM32F10X_CL
+  OTGD_FS_PCD_EP_Write (ENDP0, DataBuffer, Length);
+#else   
+  UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
+#endif /* STM32F10X_CL */ 
+
+  SetEPTxCount(ENDP0, Length);
+
+  pEPinfo->Usb_wLength -= Length;
+  pEPinfo->Usb_wOffset += Length;
+  vSetEPTxStatus(EP_TX_VALID);
+
+  USB_StatusOut();/* Expect the host to abort the data IN stage */
+
+Expect_Status_Out:
+  pInformation->ControlState = ControlState;
+}
+
+/*******************************************************************************
+* Function Name  : NoData_Setup0.
+* Description    : Proceed the processing of setup request without data stage.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void NoData_Setup0(void)
+{
+  RESULT Result = USB_UNSUPPORT;
+  uint32_t RequestNo = pInformation->USBbRequest;
+  uint32_t ControlState;
+
+  if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+  {
+    /* Device Request*/
+    /* SET_CONFIGURATION*/
+    if (RequestNo == SET_CONFIGURATION)
+    {
+      Result = Standard_SetConfiguration();
+    }
+
+    /*SET ADDRESS*/
+    else if (RequestNo == SET_ADDRESS)
+    {
+      if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0)
+          || (pInformation->USBwIndex != 0)
+          || (pInformation->Current_Configuration != 0))
+        /* Device Address should be 127 or less*/
+      {
+        ControlState = STALLED;
+        goto exit_NoData_Setup0;
+      }
+      else
+      {
+        Result = USB_SUCCESS;
+
+      #ifdef STM32F10X_CL
+         SetDeviceAddress(pInformation->USBwValue0);
+      #endif  /* STM32F10X_CL */
+      }
+    }
+    /*SET FEATURE for Device*/
+    else if (RequestNo == SET_FEATURE)
+    {
+      if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP)
+          && (pInformation->USBwIndex == 0)
+          && (ValBit(pInformation->Current_Feature, 5)))
+      {
+        Result = Standard_SetDeviceFeature();
+      }
+      else
+      {
+        Result = USB_UNSUPPORT;
+      }
+    }
+    /*Clear FEATURE for Device */
+    else if (RequestNo == CLEAR_FEATURE)
+    {
+      if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP
+          && pInformation->USBwIndex == 0
+          && ValBit(pInformation->Current_Feature, 5))
+      {
+        Result = Standard_ClearFeature();
+      }
+      else
+      {
+        Result = USB_UNSUPPORT;
+      }
+    }
+
+  }
+
+  /* Interface Request*/
+  else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+  {
+    /*SET INTERFACE*/
+    if (RequestNo == SET_INTERFACE)
+    {
+      Result = Standard_SetInterface();
+    }
+  }
+
+  /* EndPoint Request*/
+  else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
+  {
+    /*CLEAR FEATURE for EndPoint*/
+    if (RequestNo == CLEAR_FEATURE)
+    {
+      Result = Standard_ClearFeature();
+    }
+    /* SET FEATURE for EndPoint*/
+    else if (RequestNo == SET_FEATURE)
+    {
+      Result = Standard_SetEndPointFeature();
+    }
+  }
+  else
+  {
+    Result = USB_UNSUPPORT;
+  }
+
+
+  if (Result != USB_SUCCESS)
+  {
+    Result = (*pProperty->Class_NoData_Setup)(RequestNo);
+    if (Result == USB_NOT_READY)
+    {
+      ControlState = PAUSE;
+      goto exit_NoData_Setup0;
+    }
+  }
+
+  if (Result != USB_SUCCESS)
+  {
+    ControlState = STALLED;
+    goto exit_NoData_Setup0;
+  }
+
+  ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */
+
+  USB_StatusIn();
+
+exit_NoData_Setup0:
+  pInformation->ControlState = ControlState;
+  return;
+}
+
+/*******************************************************************************
+* Function Name  : Data_Setup0.
+* Description    : Proceed the processing of setup request with data stage.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Data_Setup0(void)
+{
+  uint8_t *(*CopyRoutine)(uint16_t);
+  RESULT Result;
+  uint32_t Request_No = pInformation->USBbRequest;
+
+  uint32_t Related_Endpoint, Reserved;
+  uint32_t wOffset, Status;
+
+
+
+  CopyRoutine = NULL;
+  wOffset = 0;
+
+  /*GET DESCRIPTOR*/
+  if (Request_No == GET_DESCRIPTOR)
+  {
+    if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+    {
+      uint8_t wValue1 = pInformation->USBwValue1;
+      if (wValue1 == DEVICE_DESCRIPTOR)
+      {
+        CopyRoutine = pProperty->GetDeviceDescriptor;
+      }
+      else if (wValue1 == CONFIG_DESCRIPTOR)
+      {
+        CopyRoutine = pProperty->GetConfigDescriptor;
+      }
+      else if (wValue1 == STRING_DESCRIPTOR)
+      {
+        CopyRoutine = pProperty->GetStringDescriptor;
+      }  /* End of GET_DESCRIPTOR */
+    }
+  }
+
+  /*GET STATUS*/
+  else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0)
+           && (pInformation->USBwLength == 0x0002)
+           && (pInformation->USBwIndex1 == 0))
+  {
+    /* GET STATUS for Device*/
+    if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+        && (pInformation->USBwIndex == 0))
+    {
+      CopyRoutine = Standard_GetStatus;
+    }
+
+    /* GET STATUS for Interface*/
+    else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+    {
+      if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)
+          && (pInformation->Current_Configuration != 0))
+      {
+        CopyRoutine = Standard_GetStatus;
+      }
+    }
+
+    /* GET STATUS for EndPoint*/
+    else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
+    {
+      Related_Endpoint = (pInformation->USBwIndex0 & 0x0f);
+      Reserved = pInformation->USBwIndex0 & 0x70;
+
+      if (ValBit(pInformation->USBwIndex0, 7))
+      {
+        /*Get Status of endpoint & stall the request if the related_ENdpoint
+        is Disabled*/
+        Status = _GetEPTxStatus(Related_Endpoint);
+      }
+      else
+      {
+        Status = _GetEPRxStatus(Related_Endpoint);
+      }
+
+      if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0)
+          && (Status != 0))
+      {
+        CopyRoutine = Standard_GetStatus;
+      }
+    }
+
+  }
+
+  /*GET CONFIGURATION*/
+  else if (Request_No == GET_CONFIGURATION)
+  {
+    if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
+    {
+      CopyRoutine = Standard_GetConfiguration;
+    }
+  }
+  /*GET INTERFACE*/
+  else if (Request_No == GET_INTERFACE)
+  {
+    if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+        && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0)
+        && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001)
+        && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS))
+    {
+      CopyRoutine = Standard_GetInterface;
+    }
+
+  }
+  
+  if (CopyRoutine)
+  {
+    pInformation->Ctrl_Info.Usb_wOffset = wOffset;
+    pInformation->Ctrl_Info.CopyData = CopyRoutine;
+    /* sb in the original the cast to word was directly */
+    /* now the cast is made step by step */
+    (*CopyRoutine)(0);
+    Result = USB_SUCCESS;
+  }
+  else
+  {
+    Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);
+    if (Result == USB_NOT_READY)
+    {
+      pInformation->ControlState = PAUSE;
+      return;
+    }
+  }
+
+  if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF)
+  {
+    /* Data is not ready, wait it */
+    pInformation->ControlState = PAUSE;
+    return;
+  }
+  if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0))
+  {
+    /* Unsupported request */
+    pInformation->ControlState = STALLED;
+    return;
+  }
+
+
+  if (ValBit(pInformation->USBbmRequestType, 7))
+  {
+    /* Device ==> Host */
+    __IO uint32_t wLength = pInformation->USBwLength;
+     
+    /* Restrict the data length to be the one host asks for */
+    if (pInformation->Ctrl_Info.Usb_wLength > wLength)
+    {
+      pInformation->Ctrl_Info.Usb_wLength = wLength;
+    }
+    
+    else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength)
+    {
+      if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize)
+      {
+        Data_Mul_MaxPacketSize = FALSE;
+      }
+      else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0)
+      {
+        Data_Mul_MaxPacketSize = TRUE;
+      }
+    }   
+
+    pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize;
+    DataStageIn();
+  }
+  else
+  {
+    pInformation->ControlState = OUT_DATA;
+    vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */
+  }
+
+  return;
+}
+
+/*******************************************************************************
+* Function Name  : Setup0_Process
+* Description    : Get the device request data and dispatch to individual process.
+* Input          : None.
+* Output         : None.
+* Return         : Post0_Process.
+*******************************************************************************/
+uint8_t Setup0_Process(void)
+{
+
+  union
+  {
+    uint8_t* b;
+    uint16_t* w;
+  } pBuf;
+
+#ifdef STM32F10X_CL
+  USB_OTG_EP *ep;
+  uint16_t offset = 0;
+ 
+  ep = OTGD_FS_PCD_GetOutEP(ENDP0);
+  pBuf.b = ep->xfer_buff;
+  
+  OTGD_FS_EP0StartXfer(ep);
+#else  
+  uint16_t offset = 1;
+  
+  pBuf.b = PMAAddr + (uint8_t *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */
+#endif /* STM32F10X_CL */
+
+  if (pInformation->ControlState != PAUSE)
+  {
+    pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
+    pInformation->USBbRequest = *pBuf.b++; /* bRequest */
+    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
+    pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
+    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
+    pInformation->USBwIndex  = ByteSwap(*pBuf.w++); /* wIndex */
+    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
+    pInformation->USBwLength = *pBuf.w; /* wLength */
+  }
+
+  pInformation->ControlState = SETTING_UP;
+  if (pInformation->USBwLength == 0)
+  {
+    /* Setup with no data stage */
+    NoData_Setup0();
+  }
+  else
+  {
+    /* Setup with data stage */
+    Data_Setup0();
+  }
+  return Post0_Process();
+}
+
+/*******************************************************************************
+* Function Name  : In0_Process
+* Description    : Process the IN token on all default endpoint.
+* Input          : None.
+* Output         : None.
+* Return         : Post0_Process.
+*******************************************************************************/
+uint8_t In0_Process(void)
+{
+  uint32_t ControlState = pInformation->ControlState;
+
+  if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
+  {
+    DataStageIn();
+    /* ControlState may be changed outside the function */
+    ControlState = pInformation->ControlState;
+  }
+
+  else if (ControlState == WAIT_STATUS_IN)
+  {
+    if ((pInformation->USBbRequest == SET_ADDRESS) &&
+        (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)))
+    {
+      SetDeviceAddress(pInformation->USBwValue0);
+      pUser_Standard_Requests->User_SetDeviceAddress();
+    }
+    (*pProperty->Process_Status_IN)();
+    ControlState = STALLED;
+  }
+
+  else
+  {
+    ControlState = STALLED;
+  }
+
+  pInformation->ControlState = ControlState;
+
+  return Post0_Process();
+}
+
+/*******************************************************************************
+* Function Name  : Out0_Process
+* Description    : Process the OUT token on all default endpoint.
+* Input          : None.
+* Output         : None.
+* Return         : Post0_Process.
+*******************************************************************************/
+uint8_t Out0_Process(void)
+{
+  uint32_t ControlState = pInformation->ControlState;
+
+  if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
+  {
+    /* host aborts the transfer before finish */
+    ControlState = STALLED;
+  }
+  else if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA))
+  {
+    DataStageOut();
+    ControlState = pInformation->ControlState; /* may be changed outside the function */
+  }
+
+  else if (ControlState == WAIT_STATUS_OUT)
+  {
+    (*pProperty->Process_Status_OUT)();
+  #ifndef STM32F10X_CL
+    ControlState = STALLED;
+  #endif /* STM32F10X_CL */
+  }
+
+
+  /* Unexpect state, STALL the endpoint */
+  else
+  {
+    ControlState = STALLED;
+  }
+
+  pInformation->ControlState = ControlState;
+
+  return Post0_Process();
+}
+
+/*******************************************************************************
+* Function Name  : Post0_Process
+* Description    : Stall the Endpoint 0 in case of error.
+* Input          : None.
+* Output         : None.
+* Return         : - 0 if the control State is in PAUSE
+*                  - 1 if not.
+*******************************************************************************/
+uint8_t Post0_Process(void)
+{
+#ifdef STM32F10X_CL  
+  USB_OTG_EP *ep;
+#endif /* STM32F10X_CL */
+      
+  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
+
+  if (pInformation->ControlState == STALLED)
+  {
+    vSetEPRxStatus(EP_RX_STALL);
+    vSetEPTxStatus(EP_TX_STALL);
+  }
+
+#ifdef STM32F10X_CL
+  else if ((pInformation->ControlState == OUT_DATA) ||
+      (pInformation->ControlState == WAIT_STATUS_OUT))
+  {
+    ep = OTGD_FS_PCD_GetInEP(0);
+    ep->is_in = 0;
+    OTGD_FS_EP0StartXfer(ep);
+    
+    vSetEPTxStatus(EP_TX_VALID);
+  }
+  
+  else if ((pInformation->ControlState == IN_DATA) || 
+      (pInformation->ControlState == WAIT_STATUS_IN))
+  {
+    ep = OTGD_FS_PCD_GetInEP(0);
+    ep->is_in = 1;
+    OTGD_FS_EP0StartXfer(ep);    
+  }  
+#endif /* STM32F10X_CL */
+
+  return (pInformation->ControlState == PAUSE);
+}
+
+/*******************************************************************************
+* Function Name  : SetDeviceAddress.
+* Description    : Set the device and all the used Endpoints addresses.
+* Input          : - Val: device adress.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetDeviceAddress(uint8_t Val)
+{
+#ifdef STM32F10X_CL 
+  OTGD_FS_PCD_EP_SetAddress ((uint8_t)Val);
+#else 
+  uint32_t i;
+  uint32_t nEP = Device_Table.Total_Endpoint;
+
+  /* set address in every used endpoint */
+  for (i = 0; i < nEP; i++)
+  {
+    _SetEPAddress((uint8_t)i, (uint8_t)i);
+  } /* for */
+  _SetDADDR(Val | DADDR_EF); /* set device address and enable function */
+#endif  /* STM32F10X_CL */  
+}
+
+/*******************************************************************************
+* Function Name  : NOP_Process
+* Description    : No operation function.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void NOP_Process(void)
+{
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 63 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_init.c

@@ -0,0 +1,63 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_init.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Initialization routines & global variables
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/*  The number of current endpoint, it will be used to specify an endpoint */
+ uint8_t	EPindex;
+/*  The number of current device, it is an index to the Device_Table */
+/* uint8_t	Device_no; */
+/*  Points to the DEVICE_INFO structure of current device */
+/*  The purpose of this register is to speed up the execution */
+DEVICE_INFO *pInformation;
+/*  Points to the DEVICE_PROP structure of current device */
+/*  The purpose of this register is to speed up the execution */
+DEVICE_PROP *pProperty;
+/*  Temporary save the state of Rx & Tx status. */
+/*  Whenever the Rx or Tx state is changed, its value is saved */
+/*  in this variable first and will be set to the EPRB or EPRA */
+/*  at the end of interrupt process */
+uint16_t	SaveState ;
+uint16_t  wInterrupt_Mask;
+DEVICE_INFO	Device_Info;
+USER_STANDARD_REQUESTS  *pUser_Standard_Requests;
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : USB_Init
+* Description    : USB system initialization
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void USB_Init(void)
+{
+  pInformation = &Device_Info;
+  pInformation->ControlState = 2;
+  pProperty = &Device_Property;
+  pUser_Standard_Requests = &User_Standard_Requests;
+  /* Initialize devices one by one */
+  pProperty->Init();
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 188 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_int.c

@@ -0,0 +1,188 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_int.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Endpoint CTR (Low and High) interrupt's service routines
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint16_t SaveRState;
+__IO uint16_t SaveTState;
+
+/* Extern variables ----------------------------------------------------------*/
+extern void (*pEpInt_IN[7])(void);    /*  Handles IN  interrupts   */
+extern void (*pEpInt_OUT[7])(void);   /*  Handles OUT interrupts   */
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : CTR_LP.
+* Description    : Low priority Endpoint Correct Transfer interrupt's service
+*                  routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void CTR_LP(void)
+{
+  __IO uint16_t wEPVal = 0;
+  /* stay in loop while pending ints */
+  while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
+  {
+    /* extract highest priority endpoint number */
+    EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
+    if (EPindex == 0)
+    {
+      /* Decode and service control endpoint interrupt */
+      /* calling related service routine */
+      /* (Setup0_Process, In0_Process, Out0_Process) */
+
+      /* save RX & TX status */
+      /* and set both to NAK */
+
+
+	    SaveRState = _GetENDPOINT(ENDP0);
+	    SaveTState = SaveRState & EPTX_STAT;
+	    SaveRState &=  EPRX_STAT;	
+
+	    _SetEPRxTxStatus(ENDP0,EP_RX_NAK,EP_TX_NAK);
+
+      /* DIR bit = origin of the interrupt */
+
+      if ((wIstr & ISTR_DIR) == 0)
+      {
+        /* DIR = 0 */
+
+        /* DIR = 0      => IN  int */
+        /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
+
+
+        _ClearEP_CTR_TX(ENDP0);
+        In0_Process();
+
+           /* before terminate set Tx & Rx status */
+
+            _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
+		  return;
+      }
+      else
+      {
+        /* DIR = 1 */
+
+        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
+        /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
+
+        wEPVal = _GetENDPOINT(ENDP0);
+        
+        if ((wEPVal &EP_SETUP) != 0)
+        {
+          _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
+          Setup0_Process();
+          /* before terminate set Tx & Rx status */
+
+		      _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
+          return;
+        }
+
+        else if ((wEPVal & EP_CTR_RX) != 0)
+        {
+          _ClearEP_CTR_RX(ENDP0);
+          Out0_Process();
+          /* before terminate set Tx & Rx status */
+     
+		     _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
+          return;
+        }
+      }
+    }/* if(EPindex == 0) */
+    else
+    {
+      /* Decode and service non control endpoints interrupt  */
+
+      /* process related endpoint register */
+      wEPVal = _GetENDPOINT(EPindex);
+      if ((wEPVal & EP_CTR_RX) != 0)
+      {
+        /* clear int flag */
+        _ClearEP_CTR_RX(EPindex);
+
+        /* call OUT service function */
+        (*pEpInt_OUT[EPindex-1])();
+
+      } /* if((wEPVal & EP_CTR_RX) */
+
+      if ((wEPVal & EP_CTR_TX) != 0)
+      {
+        /* clear int flag */
+        _ClearEP_CTR_TX(EPindex);
+
+        /* call IN service function */
+        (*pEpInt_IN[EPindex-1])();
+      } /* if((wEPVal & EP_CTR_TX) != 0) */
+
+    }/* if(EPindex == 0) else */
+
+  }/* while(...) */
+}
+
+/*******************************************************************************
+* Function Name  : CTR_HP.
+* Description    : High Priority Endpoint Correct Transfer interrupt's service 
+*                  routine.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void CTR_HP(void)
+{
+  uint32_t wEPVal = 0;
+
+  while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
+  {
+    _SetISTR((uint16_t)CLR_CTR); /* clear CTR flag */
+    /* extract highest priority endpoint number */
+    EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
+    /* process related endpoint register */
+    wEPVal = _GetENDPOINT(EPindex);
+    if ((wEPVal & EP_CTR_RX) != 0)
+    {
+      /* clear int flag */
+      _ClearEP_CTR_RX(EPindex);
+
+      /* call OUT service function */
+      (*pEpInt_OUT[EPindex-1])();
+
+    } /* if((wEPVal & EP_CTR_RX) */
+    else if ((wEPVal & EP_CTR_TX) != 0)
+    {
+      /* clear int flag */
+      _ClearEP_CTR_TX(EPindex);
+
+      /* call IN service function */
+      (*pEpInt_IN[EPindex-1])();
+
+
+    } /* if((wEPVal & EP_CTR_TX) != 0) */
+
+  }/* while(...) */
+}
+
+#endif  /* STM32F10X_CL */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 75 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_mem.c

@@ -0,0 +1,75 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_mem.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Utility functions for memory transfers to/from PMA
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+* Function Name  : UserToPMABufferCopy
+* Description    : Copy a buffer from user memory area to packet memory area (PMA)
+* Input          : - pbUsrBuf: pointer to user memory area.
+*                  - wPMABufAddr: address into PMA.
+*                  - wNBytes: no. of bytes to be copied.
+* Output         : None.
+* Return         : None	.
+*******************************************************************************/
+void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
+{
+  uint32_t n = (wNBytes + 1) >> 1;   /* n = (wNBytes + 1) / 2 */
+  uint32_t i, temp1, temp2;
+  uint16_t *pdwVal;
+  pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr);
+  for (i = n; i != 0; i--)
+  {
+    temp1 = (uint16_t) * pbUsrBuf;
+    pbUsrBuf++;
+    temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
+    *pdwVal++ = temp2;
+    pdwVal++;
+    pbUsrBuf++;
+  }
+}
+/*******************************************************************************
+* Function Name  : PMAToUserBufferCopy
+* Description    : Copy a buffer from user memory area to packet memory area (PMA)
+* Input          : - pbUsrBuf    = pointer to user memory area.
+*                  - wPMABufAddr = address into PMA.
+*                  - wNBytes     = no. of bytes to be copied.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
+{
+  uint32_t n = (wNBytes + 1) >> 1;/* /2*/
+  uint32_t i;
+  uint32_t *pdwVal;
+  pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
+  for (i = n; i != 0; i--)
+  {
+    *(uint16_t*)pbUsrBuf++ = *pdwVal++;
+    pbUsrBuf++;
+  }
+}
+
+#endif /* STM32F10X_CL */
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 750 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_regs.c

@@ -0,0 +1,750 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_regs.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Interface functions to USB cell registers
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef STM32F10X_CL
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : SetCNTR.
+* Description    : Set the CNTR register value.
+* Input          : wRegValue: new register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetCNTR(uint16_t wRegValue)
+{
+  _SetCNTR(wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetCNTR.
+* Description    : returns the CNTR register value.
+* Input          : None.
+* Output         : None.
+* Return         : CNTR register Value.
+*******************************************************************************/
+uint16_t GetCNTR(void)
+{
+  return(_GetCNTR());
+}
+
+/*******************************************************************************
+* Function Name  : SetISTR.
+* Description    : Set the ISTR register value.
+* Input          : wRegValue: new register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetISTR(uint16_t wRegValue)
+{
+  _SetISTR(wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetISTR
+* Description    : Returns the ISTR register value.
+* Input          : None.
+* Output         : None.
+* Return         : ISTR register Value
+*******************************************************************************/
+uint16_t GetISTR(void)
+{
+  return(_GetISTR());
+}
+
+/*******************************************************************************
+* Function Name  : GetFNR
+* Description    : Returns the FNR register value.
+* Input          : None.
+* Output         : None.
+* Return         : FNR register Value
+*******************************************************************************/
+uint16_t GetFNR(void)
+{
+  return(_GetFNR());
+}
+
+/*******************************************************************************
+* Function Name  : SetDADDR
+* Description    : Set the DADDR register value.
+* Input          : wRegValue: new register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetDADDR(uint16_t wRegValue)
+{
+  _SetDADDR(wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetDADDR
+* Description    : Returns the DADDR register value.
+* Input          : None.
+* Output         : None.
+* Return         : DADDR register Value
+*******************************************************************************/
+uint16_t GetDADDR(void)
+{
+  return(_GetDADDR());
+}
+
+/*******************************************************************************
+* Function Name  : SetBTABLE
+* Description    : Set the BTABLE.
+* Input          : wRegValue: New register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetBTABLE(uint16_t wRegValue)
+{
+  _SetBTABLE(wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetBTABLE.
+* Description    : Returns the BTABLE register value.
+* Input          : None. 
+* Output         : None.
+* Return         : BTABLE address.
+*******************************************************************************/
+uint16_t GetBTABLE(void)
+{
+  return(_GetBTABLE());
+}
+
+/*******************************************************************************
+* Function Name  : SetENDPOINT
+* Description    : Setthe Endpoint register value.
+* Input          : bEpNum: Endpoint Number. 
+*                  wRegValue.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetENDPOINT(uint8_t bEpNum, uint16_t wRegValue)
+{
+  _SetENDPOINT(bEpNum, wRegValue);
+}
+
+/*******************************************************************************
+* Function Name  : GetENDPOINT
+* Description    : Return the Endpoint register value.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint register value.
+*******************************************************************************/
+uint16_t GetENDPOINT(uint8_t bEpNum)
+{
+  return(_GetENDPOINT(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : SetEPType
+* Description    : sets the type in the endpoint register.
+* Input          : bEpNum: Endpoint Number. 
+*                  wType: type definition.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPType(uint8_t bEpNum, uint16_t wType)
+{
+  _SetEPType(bEpNum, wType);
+}
+
+/*******************************************************************************
+* Function Name  : GetEPType
+* Description    : Returns the endpoint type.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint Type
+*******************************************************************************/
+uint16_t GetEPType(uint8_t bEpNum)
+{
+  return(_GetEPType(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : SetEPTxStatus
+* Description    : Set the status of Tx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxStatus(uint8_t bEpNum, uint16_t wState)
+{
+  _SetEPTxStatus(bEpNum, wState);
+}
+
+/*******************************************************************************
+* Function Name  : SetEPRxStatus
+* Description    : Set the status of Rx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+*                  wState: new state.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxStatus(uint8_t bEpNum, uint16_t wState)
+{
+  _SetEPRxStatus(bEpNum, wState);
+}
+
+/*******************************************************************************
+* Function Name  : SetDouBleBuffEPStall
+* Description    : sets the status for Double Buffer Endpoint to STALL
+* Input          : bEpNum: Endpoint Number. 
+*                  bDir: Endpoint direction.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetDouBleBuffEPStall(uint8_t bEpNum, uint8_t bDir)
+{
+  uint16_t Endpoint_DTOG_Status;
+  Endpoint_DTOG_Status = GetENDPOINT(bEpNum);
+  if (bDir == EP_DBUF_OUT)
+  { /* OUT double buffered endpoint */
+    _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1);
+  }
+  else if (bDir == EP_DBUF_IN)
+  { /* IN double buffered endpoint */
+    _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1);
+  }
+}
+
+/*******************************************************************************
+* Function Name  : GetEPTxStatus
+* Description    : Returns the endpoint Tx status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint TX Status
+*******************************************************************************/
+uint16_t GetEPTxStatus(uint8_t bEpNum)
+{
+  return(_GetEPTxStatus(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : GetEPRxStatus
+* Description    : Returns the endpoint Rx status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint RX Status
+*******************************************************************************/
+uint16_t GetEPRxStatus(uint8_t bEpNum)
+{
+  return(_GetEPRxStatus(bEpNum));
+}
+
+/*******************************************************************************
+* Function Name  : SetEPTxValid
+* Description    : Valid the endpoint Tx Status.
+* Input          : bEpNum: Endpoint Number.  
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxValid(uint8_t bEpNum)
+{
+  _SetEPTxStatus(bEpNum, EP_TX_VALID);
+}
+
+/*******************************************************************************
+* Function Name  : SetEPRxValid
+* Description    : Valid the endpoint Rx Status.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxValid(uint8_t bEpNum)
+{
+  _SetEPRxStatus(bEpNum, EP_RX_VALID);
+}
+
+/*******************************************************************************
+* Function Name  : SetEP_KIND
+* Description    : Clear the EP_KIND bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEP_KIND(uint8_t bEpNum)
+{
+  _SetEP_KIND(bEpNum);
+}
+
+/*******************************************************************************
+* Function Name  : ClearEP_KIND
+* Description    : set the  EP_KIND bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearEP_KIND(uint8_t bEpNum)
+{
+  _ClearEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : Clear_Status_Out
+* Description    : Clear the Status Out of the related Endpoint
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Clear_Status_Out(uint8_t bEpNum)
+{
+  _ClearEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : Set_Status_Out
+* Description    : Set the Status Out of the related Endpoint
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void Set_Status_Out(uint8_t bEpNum)
+{
+  _SetEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : SetEPDoubleBuff
+* Description    : Enable the double buffer feature for the endpoint. 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDoubleBuff(uint8_t bEpNum)
+{
+  _SetEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ClearEPDoubleBuff
+* Description    : Disable the double buffer feature for the endpoint. 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearEPDoubleBuff(uint8_t bEpNum)
+{
+  _ClearEP_KIND(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : GetTxStallStatus
+* Description    : Returns the Stall status of the Tx endpoint.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Tx Stall status.
+*******************************************************************************/
+uint16_t GetTxStallStatus(uint8_t bEpNum)
+{
+  return(_GetTxStallStatus(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetRxStallStatus
+* Description    : Returns the Stall status of the Rx endpoint. 
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx Stall status.
+*******************************************************************************/
+uint16_t GetRxStallStatus(uint8_t bEpNum)
+{
+  return(_GetRxStallStatus(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : ClearEP_CTR_RX
+* Description    : Clear the CTR_RX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearEP_CTR_RX(uint8_t bEpNum)
+{
+  _ClearEP_CTR_RX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ClearEP_CTR_TX
+* Description    : Clear the CTR_TX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearEP_CTR_TX(uint8_t bEpNum)
+{
+  _ClearEP_CTR_TX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ToggleDTOG_RX
+* Description    : Toggle the DTOG_RX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ToggleDTOG_RX(uint8_t bEpNum)
+{
+  _ToggleDTOG_RX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ToggleDTOG_TX
+* Description    : Toggle the DTOG_TX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ToggleDTOG_TX(uint8_t bEpNum)
+{
+  _ToggleDTOG_TX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ClearDTOG_RX.
+* Description    : Clear the DTOG_RX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearDTOG_RX(uint8_t bEpNum)
+{
+  _ClearDTOG_RX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : ClearDTOG_TX.
+* Description    : Clear the DTOG_TX bit.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void ClearDTOG_TX(uint8_t bEpNum)
+{
+  _ClearDTOG_TX(bEpNum);
+}
+/*******************************************************************************
+* Function Name  : SetEPAddress
+* Description    : Set the endpoint address.
+* Input          : bEpNum: Endpoint Number.
+*                  bAddr: New endpoint address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPAddress(uint8_t bEpNum, uint8_t bAddr)
+{
+  _SetEPAddress(bEpNum, bAddr);
+}
+/*******************************************************************************
+* Function Name  : GetEPAddress
+* Description    : Get the endpoint address.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Endpoint address.
+*******************************************************************************/
+uint8_t GetEPAddress(uint8_t bEpNum)
+{
+  return(_GetEPAddress(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : SetEPTxAddr
+* Description    : Set the endpoint Tx buffer address.
+* Input          : bEpNum: Endpoint Number.
+*                  wAddr: new address. 
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxAddr(uint8_t bEpNum, uint16_t wAddr)
+{
+  _SetEPTxAddr(bEpNum, wAddr);
+}
+/*******************************************************************************
+* Function Name  : SetEPRxAddr
+* Description    : Set the endpoint Rx buffer address.
+* Input          : bEpNum: Endpoint Number.
+*                  wAddr: new address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxAddr(uint8_t bEpNum, uint16_t wAddr)
+{
+  _SetEPRxAddr(bEpNum, wAddr);
+}
+/*******************************************************************************
+* Function Name  : GetEPTxAddr
+* Description    : Returns the endpoint Tx buffer address.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx buffer address. 
+*******************************************************************************/
+uint16_t GetEPTxAddr(uint8_t bEpNum)
+{
+  return(_GetEPTxAddr(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPRxAddr.
+* Description    : Returns the endpoint Rx buffer address.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx buffer address.
+*******************************************************************************/
+uint16_t GetEPRxAddr(uint8_t bEpNum)
+{
+  return(_GetEPRxAddr(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : SetEPTxCount.
+* Description    : Set the Tx count.
+* Input          : bEpNum: Endpoint Number.
+*                  wCount: new count value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPTxCount(uint8_t bEpNum, uint16_t wCount)
+{
+  _SetEPTxCount(bEpNum, wCount);
+}
+/*******************************************************************************
+* Function Name  : SetEPCountRxReg.
+* Description    : Set the Count Rx Register value.
+* Input          : *pdwReg: point to the register.
+*                  wCount: the new register value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPCountRxReg(uint32_t *pdwReg, uint16_t wCount)
+{
+  _SetEPCountRxReg(dwReg, wCount);
+}
+/*******************************************************************************
+* Function Name  : SetEPRxCount
+* Description    : Set the Rx count.
+* Input          : bEpNum: Endpoint Number. 
+*                  wCount: the new count value.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPRxCount(uint8_t bEpNum, uint16_t wCount)
+{
+  _SetEPRxCount(bEpNum, wCount);
+}
+/*******************************************************************************
+* Function Name  : GetEPTxCount
+* Description    : Get the Tx count.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None
+* Return         : Tx count value.
+*******************************************************************************/
+uint16_t GetEPTxCount(uint8_t bEpNum)
+{
+  return(_GetEPTxCount(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPRxCount
+* Description    : Get the Rx count.
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : Rx count value.
+*******************************************************************************/
+uint16_t GetEPRxCount(uint8_t bEpNum)
+{
+  return(_GetEPRxCount(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuffAddr
+* Description    : Set the addresses of the buffer 0 and 1.
+* Input          : bEpNum: Endpoint Number.  
+*                  wBuf0Addr: new address of buffer 0. 
+*                  wBuf1Addr: new address of buffer 1.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuffAddr(uint8_t bEpNum, uint16_t wBuf0Addr, uint16_t wBuf1Addr)
+{
+  _SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr);
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuf0Addr
+* Description    : Set the Buffer 1 address.
+* Input          : bEpNum: Endpoint Number
+*                  wBuf0Addr: new address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuf0Addr(uint8_t bEpNum, uint16_t wBuf0Addr)
+{
+  _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuf1Addr
+* Description    : Set the Buffer 1 address.
+* Input          : bEpNum: Endpoint Number
+*                  wBuf1Addr: new address.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuf1Addr(uint8_t bEpNum, uint16_t wBuf1Addr)
+{
+  _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBuf0Addr
+* Description    : Returns the address of the Buffer 0.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+uint16_t GetEPDblBuf0Addr(uint8_t bEpNum)
+{
+  return(_GetEPDblBuf0Addr(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBuf1Addr
+* Description    : Returns the address of the Buffer 1.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : Address of the Buffer 1.
+*******************************************************************************/
+uint16_t GetEPDblBuf1Addr(uint8_t bEpNum)
+{
+  return(_GetEPDblBuf1Addr(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuffCount
+* Description    : Set the number of bytes for a double Buffer 
+*                  endpoint.
+* Input          : bEpNum,bDir, wCount
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuffCount(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
+{
+  _SetEPDblBuffCount(bEpNum, bDir, wCount);
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuf0Count
+* Description    : Set the number of bytes in the buffer 0 of a double Buffer 
+*                  endpoint.
+* Input          : bEpNum, bDir,  wCount
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuf0Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
+{
+  _SetEPDblBuf0Count(bEpNum, bDir, wCount);
+}
+/*******************************************************************************
+* Function Name  : SetEPDblBuf1Count
+* Description    : Set the number of bytes in the buffer 0 of a double Buffer 
+*                  endpoint.
+* Input          : bEpNum,  bDir,  wCount
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void SetEPDblBuf1Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
+{
+  _SetEPDblBuf1Count(bEpNum, bDir, wCount);
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBuf0Count
+* Description    : Returns the number of byte received in the buffer 0 of a double
+*                  Buffer endpoint.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : Endpoint Buffer 0 count
+*******************************************************************************/
+uint16_t GetEPDblBuf0Count(uint8_t bEpNum)
+{
+  return(_GetEPDblBuf0Count(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBuf1Count
+* Description    : Returns the number of data received in the buffer 1 of a double
+*                  Buffer endpoint.
+* Input          : bEpNum: Endpoint Number.
+* Output         : None.
+* Return         : Endpoint Buffer 1 count.
+*******************************************************************************/
+uint16_t GetEPDblBuf1Count(uint8_t bEpNum)
+{
+  return(_GetEPDblBuf1Count(bEpNum));
+}
+/*******************************************************************************
+* Function Name  : GetEPDblBufDir
+* Description    : gets direction of the double buffered endpoint
+* Input          : bEpNum: Endpoint Number. 
+* Output         : None.
+* Return         : EP_DBUF_OUT, EP_DBUF_IN,
+*                  EP_DBUF_ERR if the endpoint counter not yet programmed.
+*******************************************************************************/
+EP_DBUF_DIR GetEPDblBufDir(uint8_t bEpNum)
+{
+  if ((uint16_t)(*_pEPRxCount(bEpNum) & 0xFC00) != 0)
+    return(EP_DBUF_OUT);
+  else if (((uint16_t)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0)
+    return(EP_DBUF_IN);
+  else
+    return(EP_DBUF_ERR);
+}
+/*******************************************************************************
+* Function Name  : FreeUserBuffer
+* Description    : free buffer used from the application realizing it to the line
+                   toggles bit SW_BUF in the double buffered endpoint register
+* Input          : bEpNum, bDir
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+void FreeUserBuffer(uint8_t bEpNum, uint8_t bDir)
+{
+  if (bDir == EP_DBUF_OUT)
+  { /* OUT double buffered endpoint */
+    _ToggleDTOG_TX(bEpNum);
+  }
+  else if (bDir == EP_DBUF_IN)
+  { /* IN double buffered endpoint */
+    _ToggleDTOG_RX(bEpNum);
+  }
+}
+
+/*******************************************************************************
+* Function Name  : ToWord
+* Description    : merge two byte in a word.
+* Input          : bh: byte high, bl: bytes low.
+* Output         : None.
+* Return         : resulted word.
+*******************************************************************************/
+uint16_t ToWord(uint8_t bh, uint8_t bl)
+{
+  uint16_t wRet;
+  wRet = (uint16_t)bl | ((uint16_t)bh << 8);
+  return(wRet);
+}
+/*******************************************************************************
+* Function Name  : ByteSwap
+* Description    : Swap two byte in a word.
+* Input          : wSwW: word to Swap.
+* Output         : None.
+* Return         : resulted word.
+*******************************************************************************/
+uint16_t ByteSwap(uint16_t wSwW)
+{
+  uint8_t bTemp;
+  uint16_t wRet;
+  bTemp = (uint8_t)(wSwW & 0xff);
+  wRet =  (wSwW >> 8) | ((uint16_t)bTemp << 8);
+  return(wRet);
+}
+
+#endif /* STM32F10X_CL */
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 126 - 0
bsp/stm32_radio/Libraries/STM32_USB-FS-Device_Driver/src/usb_sil.c

@@ -0,0 +1,126 @@
+/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
+* File Name          : usb_sil.c
+* Author             : MCD Application Team
+* Version            : V3.1.0
+* Date               : 10/30/2009
+* Description        : Simplified Interface Layer for Global Initialization and 
+*                      Endpoint Rea/Write operations.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : USB_SIL_Init
+* Description    : Initialize the USB Device IP and the Endpoint 0.
+* Input          : None.
+* Output         : None.
+* Return         : Status.
+*******************************************************************************/
+uint32_t USB_SIL_Init(void)
+{
+#ifndef STM32F10X_CL
+  
+  /* USB interrupts initialization */
+  /* clear pending interrupts */
+  _SetISTR(0);
+  wInterrupt_Mask = IMR_MSK;
+  /* set interrupts mask */
+  _SetCNTR(wInterrupt_Mask);
+  
+#else
+  
+  /* Perform OTG Device initialization procedure (including EP0 init) */
+  OTG_DEV_Init();
+  
+#endif /* STM32F10X_CL */
+
+  return 0;
+}
+
+/*******************************************************************************
+* Function Name  : USB_SIL_Write
+* Description    : Write a buffer of data to a selected endpoint.
+* Input          : - bEpAddr: The address of the non control endpoint.
+*                  - pBufferPointer: The pointer to the buffer of data to be written
+*                    to the endpoint.
+*                  - wBufferSize: Number of data to be written (in bytes).
+* Output         : None.
+* Return         : Status.
+*******************************************************************************/
+uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize)
+{
+#ifndef STM32F10X_CL
+
+  /* Use the memory interface function to write to the selected endpoint */
+  UserToPMABufferCopy(pBufferPointer, GetEPTxAddr(bEpAddr & 0x7F), wBufferSize);
+
+  /* Update the data length in the control register */
+  SetEPTxCount((bEpAddr & 0x7F), wBufferSize);
+  
+#else
+  
+   /* Use the PCD interface layer function to write to the selected endpoint */
+   OTGD_FS_PCD_EP_Write (bEpAddr, pBufferPointer, wBufferSize); 
+   
+#endif /* STM32F10X_CL */
+
+  return 0;
+}
+
+/*******************************************************************************
+* Function Name  : USB_SIL_Read
+* Description    : Write a buffer of data to a selected endpoint.
+* Input          : - bEpAddr: The address of the non control endpoint.
+*                  - pBufferPointer: The pointer to which will be saved the 
+*                     received data buffer.
+* Output         : None.
+* Return         : Number of received data (in Bytes).
+*******************************************************************************/
+uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer)
+{
+  uint32_t DataLength = 0;
+
+#ifndef STM32F10X_CL
+
+  /* Get the number of received data on the selected Endpoint */
+  DataLength = GetEPRxCount(bEpAddr & 0x7F);
+  
+  /* Use the memory interface function to write to the selected endpoint */
+  PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength);
+
+#else
+  
+  USB_OTG_EP *ep;
+
+  /* Get the structure pointer of the selected Endpoint */
+  ep = OTGD_FS_PCD_GetOutEP(bEpAddr);
+  
+  /* Get the number of received data */
+  DataLength = ep->xfer_len;
+  
+  /* Use the PCD interface layer function to read the selected endpoint */
+  OTGD_FS_PCD_EP_Read (bEpAddr, pBufferPointer, DataLength);
+  
+#endif /* STM32F10X_CL */
+
+  /* Return the number of received data */
+  return DataLength;
+}
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

+ 189 - 121
bsp/stm32_radio/project.Uv2

@@ -7,12 +7,14 @@ Group (Startup)
 Group (Kernel)
 Group (STM32)
 Group (StdPeriph_Driver)
+Group (USB-FS-Device_Driver)
 Group (CMSIS)
 Group (finsh)
 Group (Filesystem)
 Group (LwIP)
 Group (mp3)
 Group (RTGUI)
+Group (Mass_Storage)
 
 File 1,5,<.\rtconfig.h><rtconfig.h>
 File 1,5,<.\board.h><board.h>
@@ -87,126 +89,148 @@ File 4,1,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_spi.c><stm32f10x_
 File 4,1,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_tim.c><stm32f10x_tim.c>
 File 4,1,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_usart.c><stm32f10x_usart.c>
 File 4,1,<.\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_wwdg.c><stm32f10x_wwdg.c>
-File 5,1,<.\Libraries\CMSIS\Core\CM3\core_cm3.c><core_cm3.c>
-File 5,1,<.\Libraries\CMSIS\Core\CM3\system_stm32f10x.c><system_stm32f10x.c>
-File 6,1,<..\..\finsh\finsh_compiler.c><finsh_compiler.c>
-File 6,1,<..\..\finsh\finsh_error.c><finsh_error.c>
-File 6,1,<..\..\finsh\finsh_heap.c><finsh_heap.c>
-File 6,1,<..\..\finsh\finsh_init.c><finsh_init.c>
-File 6,1,<..\..\finsh\finsh_node.c><finsh_node.c>
-File 6,1,<..\..\finsh\finsh_ops.c><finsh_ops.c>
-File 6,1,<..\..\finsh\finsh_parser.c><finsh_parser.c>
-File 6,1,<..\..\finsh\finsh_token.c><finsh_token.c>
-File 6,1,<..\..\finsh\finsh_var.c><finsh_var.c>
-File 6,1,<..\..\finsh\finsh_vm.c><finsh_vm.c>
-File 6,1,<..\..\finsh\shell.c><shell.c>
-File 6,1,<..\..\finsh\symbol.c><symbol.c>
-File 6,1,<..\..\finsh\cmd.c><cmd.c>
-File 7,1,<..\..\filesystem\dfs\src\dfs_init.c><dfs_init.c>
-File 7,1,<..\..\filesystem\dfs\src\dfs_fs.c><dfs_fs.c>
-File 7,1,<..\..\filesystem\dfs\src\dfs_raw.c><dfs_raw.c>
-File 7,1,<..\..\filesystem\dfs\src\dfs_util.c><dfs_util.c>
-File 7,1,<..\..\filesystem\dfs\src\dfs_posix.c><dfs_posix.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\dir.c><dir.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\fat.c><fat.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\file.c><file.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\fs.c><fs.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\ls.c><ls.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\time.c><time.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\ui.c><ui.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\base\plibc.c><plibc.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\base\efs.c><efs.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\base\extract.c><extract.c>
-File 7,1,<..\..\filesystem\dfs\filesystems\efsl\src\base\partition.c><partition.c>
-File 7,1,<..\..\filesystem\dfs\src\dfs_cache.c><dfs_cache.c>
-File 8,1,<..\..\net\lwip\src\core\dhcp.c><dhcp.c>
-File 8,1,<..\..\net\lwip\src\core\dns.c><dns.c>
-File 8,1,<..\..\net\lwip\src\core\init.c><init.c>
-File 8,1,<..\..\net\lwip\src\core\netif.c><netif.c>
-File 8,1,<..\..\net\lwip\src\core\pbuf.c><pbuf.c>
-File 8,1,<..\..\net\lwip\src\core\raw.c><raw.c>
-File 8,1,<..\..\net\lwip\src\core\stats.c><stats.c>
-File 8,1,<..\..\net\lwip\src\core\sys.c><sys.c>
-File 8,1,<..\..\net\lwip\src\core\tcp.c><tcp.c>
-File 8,1,<..\..\net\lwip\src\core\tcp_in.c><tcp_in.c>
-File 8,1,<..\..\net\lwip\src\core\tcp_out.c><tcp_out.c>
-File 8,1,<..\..\net\lwip\src\core\udp.c><udp.c>
-File 8,1,<..\..\net\lwip\src\core\ipv4\autoip.c><autoip.c>
-File 8,1,<..\..\net\lwip\src\core\ipv4\icmp.c><icmp.c>
-File 8,1,<..\..\net\lwip\src\core\ipv4\igmp.c><igmp.c>
-File 8,1,<..\..\net\lwip\src\core\ipv4\inet.c><inet.c>
-File 8,1,<..\..\net\lwip\src\core\ipv4\inet_chksum.c><inet_chksum.c>
-File 8,1,<..\..\net\lwip\src\core\ipv4\ip.c><ip.c>
-File 8,1,<..\..\net\lwip\src\core\ipv4\ip_addr.c><ip_addr.c>
-File 8,1,<..\..\net\lwip\src\core\ipv4\ip_frag.c><ip_frag.c>
-File 8,1,<..\..\net\lwip\src\core\snmp\msg_in.c><msg_in.c>
-File 8,1,<..\..\net\lwip\src\core\snmp\msg_out.c><msg_out.c>
-File 8,1,<..\..\net\lwip\src\api\api_lib.c><api_lib.c>
-File 8,1,<..\..\net\lwip\src\api\api_msg.c><api_msg.c>
-File 8,1,<..\..\net\lwip\src\api\err.c><err.c>
-File 8,1,<..\..\net\lwip\src\api\netbuf.c><netbuf.c>
-File 8,1,<..\..\net\lwip\src\api\netdb.c><netdb.c>
-File 8,1,<..\..\net\lwip\src\api\netifapi.c><netifapi.c>
-File 8,1,<..\..\net\lwip\src\api\tcpip.c><tcpip.c>
-File 8,1,<..\..\net\lwip\src\netif\etharp.c><etharp.c>
-File 8,1,<..\..\net\lwip\src\netif\ethernetif.c><ethernetif.c>
-File 8,1,<..\..\net\lwip\src\netif\loopif.c><loopif.c>
-File 8,1,<..\..\net\lwip\src\arch\sys_arch_init.c><sys_arch_init.c>
-File 8,1,<..\..\net\lwip\src\arch\sys_arch.c><sys_arch.c>
-File 8,1,<..\..\net\lwip\src\api\sockets.c><sockets.c>
-File 8,1,<..\..\net\lwip\src\core\memp_tiny.c><memp_tiny.c>
-File 9,1,<.\mp3\mp3dec.c><mp3dec.c>
-File 9,1,<.\mp3\mp3tabs.c><mp3tabs.c>
-File 9,1,<.\mp3\real\bitstream.c><bitstream.c>
-File 9,1,<.\mp3\real\buffers.c><buffers.c>
-File 9,1,<.\mp3\real\dct32.c><dct32.c>
-File 9,1,<.\mp3\real\dequant.c><dequant.c>
-File 9,1,<.\mp3\real\dqchan.c><dqchan.c>
-File 9,1,<.\mp3\real\huffman.c><huffman.c>
-File 9,1,<.\mp3\real\hufftabs.c><hufftabs.c>
-File 9,1,<.\mp3\real\imdct.c><imdct.c>
-File 9,1,<.\mp3\real\scalfact.c><scalfact.c>
-File 9,1,<.\mp3\real\stproc.c><stproc.c>
-File 9,1,<.\mp3\real\subband.c><subband.c>
-File 9,1,<.\mp3\real\trigtabs.c><trigtabs.c>
-File 9,2,<.\mp3\real\arm\asmpoly_thumb2.s><asmpoly_thumb2.s>
-File 9,2,<.\mp3\real\arm\asmmisc.s><asmmisc.s>
-File 10,1,<..\..\rtgui\common\rtgui_object.c><rtgui_object.c>
-File 10,1,<..\..\rtgui\common\rtgui_system.c><rtgui_system.c>
-File 10,1,<..\..\rtgui\common\rtgui_theme.c><rtgui_theme.c>
-File 10,1,<..\..\rtgui\common\asc12font.c><asc12font.c>
-File 10,1,<..\..\rtgui\common\asc16font.c><asc16font.c>
-File 10,1,<..\..\rtgui\common\color.c><color.c>
-File 10,1,<..\..\rtgui\common\dc.c><dc.c>
-File 10,1,<..\..\rtgui\common\dc_buffer.c><dc_buffer.c>
-File 10,1,<..\..\rtgui\common\dc_hw.c><dc_hw.c>
-File 10,1,<..\..\rtgui\common\filerw.c><filerw.c>
-File 10,1,<..\..\rtgui\common\font.c><font.c>
-File 10,1,<..\..\rtgui\common\image.c><image.c>
-File 10,1,<..\..\rtgui\common\image_xpm.c><image_xpm.c>
-File 10,1,<..\..\rtgui\common\image_hdc.c><image_hdc.c>
-File 10,1,<..\..\rtgui\common\region.c><region.c>
-File 10,1,<..\..\rtgui\server\server.c><server.c>
-File 10,1,<..\..\rtgui\server\driver.c><driver.c>
-File 10,1,<..\..\rtgui\server\panel.c><panel.c>
-File 10,1,<..\..\rtgui\widgets\widget.c><widget.c>
-File 10,1,<..\..\rtgui\widgets\window.c><window.c>
-File 10,1,<..\..\rtgui\widgets\workbench.c><workbench.c>
-File 10,1,<..\..\rtgui\widgets\view.c><view.c>
-File 10,1,<..\..\rtgui\widgets\box.c><box.c>
-File 10,1,<..\..\rtgui\widgets\button.c><button.c>
-File 10,1,<..\..\rtgui\widgets\container.c><container.c>
-File 10,1,<..\..\rtgui\widgets\iconbox.c><iconbox.c>
-File 10,1,<..\..\rtgui\widgets\label.c><label.c>
-File 10,1,<..\..\rtgui\widgets\textbox.c><textbox.c>
-File 10,1,<..\..\rtgui\widgets\title.c><title.c>
-File 10,1,<..\..\rtgui\widgets\toplevel.c><toplevel.c>
-File 10,1,<..\..\rtgui\server\mouse.c><mouse.c>
-File 10,1,<..\..\rtgui\server\topwin.c><topwin.c>
-File 10,1,<..\..\rtgui\common\caret.c><caret.c>
-File 10,1,<..\..\rtgui\common\font_hz_file.c><font_hz_file.c>
-File 10,1,<..\..\rtgui\common\hz16font.c><hz16font.c>
-File 10,1,<..\..\rtgui\common\hz12font.c><hz12font.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\otgd_fs_cal.c><otgd_fs_cal.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\otgd_fs_dev.c><otgd_fs_dev.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\otgd_fs_int.c><otgd_fs_int.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\otgd_fs_pcd.c><otgd_fs_pcd.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\usb_core.c><usb_core.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\usb_init.c><usb_init.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\usb_int.c><usb_int.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\usb_mem.c><usb_mem.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\usb_regs.c><usb_regs.c>
+File 5,1,<.\Libraries\STM32_USB-FS-Device_Driver\src\usb_sil.c><usb_sil.c>
+File 6,1,<.\Libraries\CMSIS\Core\CM3\core_cm3.c><core_cm3.c>
+File 6,1,<.\Libraries\CMSIS\Core\CM3\system_stm32f10x.c><system_stm32f10x.c>
+File 7,1,<..\..\finsh\finsh_compiler.c><finsh_compiler.c>
+File 7,1,<..\..\finsh\finsh_error.c><finsh_error.c>
+File 7,1,<..\..\finsh\finsh_heap.c><finsh_heap.c>
+File 7,1,<..\..\finsh\finsh_init.c><finsh_init.c>
+File 7,1,<..\..\finsh\finsh_node.c><finsh_node.c>
+File 7,1,<..\..\finsh\finsh_ops.c><finsh_ops.c>
+File 7,1,<..\..\finsh\finsh_parser.c><finsh_parser.c>
+File 7,1,<..\..\finsh\finsh_token.c><finsh_token.c>
+File 7,1,<..\..\finsh\finsh_var.c><finsh_var.c>
+File 7,1,<..\..\finsh\finsh_vm.c><finsh_vm.c>
+File 7,1,<..\..\finsh\shell.c><shell.c>
+File 7,1,<..\..\finsh\symbol.c><symbol.c>
+File 7,1,<..\..\finsh\cmd.c><cmd.c>
+File 8,1,<..\..\filesystem\dfs\src\dfs_init.c><dfs_init.c>
+File 8,1,<..\..\filesystem\dfs\src\dfs_fs.c><dfs_fs.c>
+File 8,1,<..\..\filesystem\dfs\src\dfs_raw.c><dfs_raw.c>
+File 8,1,<..\..\filesystem\dfs\src\dfs_util.c><dfs_util.c>
+File 8,1,<..\..\filesystem\dfs\src\dfs_posix.c><dfs_posix.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\dir.c><dir.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\fat.c><fat.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\file.c><file.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\fs.c><fs.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\ls.c><ls.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\time.c><time.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\fs\vfat\ui.c><ui.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\base\plibc.c><plibc.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\base\efs.c><efs.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\base\extract.c><extract.c>
+File 8,1,<..\..\filesystem\dfs\filesystems\efsl\src\base\partition.c><partition.c>
+File 8,1,<..\..\filesystem\dfs\src\dfs_cache.c><dfs_cache.c>
+File 9,1,<..\..\net\lwip\src\core\dhcp.c><dhcp.c>
+File 9,1,<..\..\net\lwip\src\core\dns.c><dns.c>
+File 9,1,<..\..\net\lwip\src\core\init.c><init.c>
+File 9,1,<..\..\net\lwip\src\core\netif.c><netif.c>
+File 9,1,<..\..\net\lwip\src\core\pbuf.c><pbuf.c>
+File 9,1,<..\..\net\lwip\src\core\raw.c><raw.c>
+File 9,1,<..\..\net\lwip\src\core\stats.c><stats.c>
+File 9,1,<..\..\net\lwip\src\core\sys.c><sys.c>
+File 9,1,<..\..\net\lwip\src\core\tcp.c><tcp.c>
+File 9,1,<..\..\net\lwip\src\core\tcp_in.c><tcp_in.c>
+File 9,1,<..\..\net\lwip\src\core\tcp_out.c><tcp_out.c>
+File 9,1,<..\..\net\lwip\src\core\udp.c><udp.c>
+File 9,1,<..\..\net\lwip\src\core\ipv4\autoip.c><autoip.c>
+File 9,1,<..\..\net\lwip\src\core\ipv4\icmp.c><icmp.c>
+File 9,1,<..\..\net\lwip\src\core\ipv4\igmp.c><igmp.c>
+File 9,1,<..\..\net\lwip\src\core\ipv4\inet.c><inet.c>
+File 9,1,<..\..\net\lwip\src\core\ipv4\inet_chksum.c><inet_chksum.c>
+File 9,1,<..\..\net\lwip\src\core\ipv4\ip.c><ip.c>
+File 9,1,<..\..\net\lwip\src\core\ipv4\ip_addr.c><ip_addr.c>
+File 9,1,<..\..\net\lwip\src\core\ipv4\ip_frag.c><ip_frag.c>
+File 9,1,<..\..\net\lwip\src\core\snmp\msg_in.c><msg_in.c>
+File 9,1,<..\..\net\lwip\src\core\snmp\msg_out.c><msg_out.c>
+File 9,1,<..\..\net\lwip\src\api\api_lib.c><api_lib.c>
+File 9,1,<..\..\net\lwip\src\api\api_msg.c><api_msg.c>
+File 9,1,<..\..\net\lwip\src\api\err.c><err.c>
+File 9,1,<..\..\net\lwip\src\api\netbuf.c><netbuf.c>
+File 9,1,<..\..\net\lwip\src\api\netdb.c><netdb.c>
+File 9,1,<..\..\net\lwip\src\api\netifapi.c><netifapi.c>
+File 9,1,<..\..\net\lwip\src\api\tcpip.c><tcpip.c>
+File 9,1,<..\..\net\lwip\src\netif\etharp.c><etharp.c>
+File 9,1,<..\..\net\lwip\src\netif\ethernetif.c><ethernetif.c>
+File 9,1,<..\..\net\lwip\src\netif\loopif.c><loopif.c>
+File 9,1,<..\..\net\lwip\src\arch\sys_arch_init.c><sys_arch_init.c>
+File 9,1,<..\..\net\lwip\src\arch\sys_arch.c><sys_arch.c>
+File 9,1,<..\..\net\lwip\src\api\sockets.c><sockets.c>
+File 9,1,<..\..\net\lwip\src\core\memp_tiny.c><memp_tiny.c>
+File 10,1,<.\mp3\mp3dec.c><mp3dec.c>
+File 10,1,<.\mp3\mp3tabs.c><mp3tabs.c>
+File 10,1,<.\mp3\real\bitstream.c><bitstream.c>
+File 10,1,<.\mp3\real\buffers.c><buffers.c>
+File 10,1,<.\mp3\real\dct32.c><dct32.c>
+File 10,1,<.\mp3\real\dequant.c><dequant.c>
+File 10,1,<.\mp3\real\dqchan.c><dqchan.c>
+File 10,1,<.\mp3\real\huffman.c><huffman.c>
+File 10,1,<.\mp3\real\hufftabs.c><hufftabs.c>
+File 10,1,<.\mp3\real\imdct.c><imdct.c>
+File 10,1,<.\mp3\real\scalfact.c><scalfact.c>
+File 10,1,<.\mp3\real\stproc.c><stproc.c>
+File 10,1,<.\mp3\real\subband.c><subband.c>
+File 10,1,<.\mp3\real\trigtabs.c><trigtabs.c>
+File 10,2,<.\mp3\real\arm\asmpoly_thumb2.s><asmpoly_thumb2.s>
+File 10,2,<.\mp3\real\arm\asmmisc.s><asmmisc.s>
+File 11,1,<..\..\rtgui\common\rtgui_object.c><rtgui_object.c>
+File 11,1,<..\..\rtgui\common\rtgui_system.c><rtgui_system.c>
+File 11,1,<..\..\rtgui\common\rtgui_theme.c><rtgui_theme.c>
+File 11,1,<..\..\rtgui\common\asc12font.c><asc12font.c>
+File 11,1,<..\..\rtgui\common\asc16font.c><asc16font.c>
+File 11,1,<..\..\rtgui\common\color.c><color.c>
+File 11,1,<..\..\rtgui\common\dc.c><dc.c>
+File 11,1,<..\..\rtgui\common\dc_buffer.c><dc_buffer.c>
+File 11,1,<..\..\rtgui\common\dc_hw.c><dc_hw.c>
+File 11,1,<..\..\rtgui\common\filerw.c><filerw.c>
+File 11,1,<..\..\rtgui\common\font.c><font.c>
+File 11,1,<..\..\rtgui\common\image.c><image.c>
+File 11,1,<..\..\rtgui\common\image_xpm.c><image_xpm.c>
+File 11,1,<..\..\rtgui\common\image_hdc.c><image_hdc.c>
+File 11,1,<..\..\rtgui\common\region.c><region.c>
+File 11,1,<..\..\rtgui\server\server.c><server.c>
+File 11,1,<..\..\rtgui\server\driver.c><driver.c>
+File 11,1,<..\..\rtgui\server\panel.c><panel.c>
+File 11,1,<..\..\rtgui\widgets\widget.c><widget.c>
+File 11,1,<..\..\rtgui\widgets\window.c><window.c>
+File 11,1,<..\..\rtgui\widgets\workbench.c><workbench.c>
+File 11,1,<..\..\rtgui\widgets\view.c><view.c>
+File 11,1,<..\..\rtgui\widgets\box.c><box.c>
+File 11,1,<..\..\rtgui\widgets\button.c><button.c>
+File 11,1,<..\..\rtgui\widgets\container.c><container.c>
+File 11,1,<..\..\rtgui\widgets\iconbox.c><iconbox.c>
+File 11,1,<..\..\rtgui\widgets\label.c><label.c>
+File 11,1,<..\..\rtgui\widgets\textbox.c><textbox.c>
+File 11,1,<..\..\rtgui\widgets\title.c><title.c>
+File 11,1,<..\..\rtgui\widgets\toplevel.c><toplevel.c>
+File 11,1,<..\..\rtgui\server\mouse.c><mouse.c>
+File 11,1,<..\..\rtgui\server\topwin.c><topwin.c>
+File 11,1,<..\..\rtgui\common\caret.c><caret.c>
+File 11,1,<..\..\rtgui\common\font_hz_file.c><font_hz_file.c>
+File 11,1,<..\..\rtgui\common\hz16font.c><hz16font.c>
+File 11,1,<..\..\rtgui\common\hz12font.c><hz12font.c>
+File 12,1,<.\Libraries\Mass_Storage\src\hw_config.c><hw_config.c>
+File 12,1,<.\Libraries\Mass_Storage\src\mass_mal.c><mass_mal.c>
+File 12,1,<.\Libraries\Mass_Storage\src\memory.c><memory.c>
+File 12,1,<.\Libraries\Mass_Storage\src\usb_bot.c><usb_bot.c>
+File 12,1,<.\Libraries\Mass_Storage\src\scsi_data.c><scsi_data.c>
+File 12,1,<.\Libraries\Mass_Storage\src\usb_desc.c><usb_desc.c>
+File 12,1,<.\Libraries\Mass_Storage\src\usb_endp.c><usb_endp.c>
+File 12,1,<.\Libraries\Mass_Storage\src\usb_istr.c><usb_istr.c>
+File 12,1,<.\Libraries\Mass_Storage\src\usb_prop.c><usb_prop.c>
+File 12,1,<.\Libraries\Mass_Storage\src\usb_pwr.c><usb_pwr.c>
+File 12,1,<.\Libraries\Mass_Storage\src\usb_scsi.c><usb_scsi.c>
+File 12,1,<.\Libraries\Mass_Storage\src\usb_main.c><usb_main.c>
 
 
 Options 1,0,0  // Target 'RT-Thread STM32 Radio'
@@ -299,7 +323,29 @@ Options 1,0,0  // Target 'RT-Thread STM32 Radio'
  FLASH4 ()
 EndOpt
 
-Options 1,9,0  // Group 'mp3'
+Options 1,5,0  // Group 'USB-FS-Device_Driver'
+ PropFld { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+ IncBld=2
+ AlwaysBuild=2
+ GenAsm=2
+ AsmAsm=2
+ PublicsOnly=2
+ StopCode=11
+ CustArgs ()
+ LibMods ()
+ ADSCCFLG { 2,84,85,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+ ADSCMISC ()
+ ADSCDEFN ()
+ ADSCUDEF ()
+ ADSCINCD (.\Libraries\STM32_USB-FS-Device_Driver\inc;.\Libraries\Mass_Storage\inc)
+ ADSASFLG { 170,42,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+ ADSAMISC ()
+ ADSADEFN ()
+ ADSAUDEF ()
+ ADSAINCD ()
+EndOpt
+
+Options 1,10,0  // Group 'mp3'
  PropFld { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
  IncBld=2
  AlwaysBuild=2
@@ -321,3 +367,25 @@ Options 1,9,0  // Group 'mp3'
  ADSAINCD ()
 EndOpt
 
+Options 1,12,0  // Group 'Mass_Storage'
+ PropFld { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+ IncBld=2
+ AlwaysBuild=2
+ GenAsm=2
+ AsmAsm=2
+ PublicsOnly=2
+ StopCode=11
+ CustArgs ()
+ LibMods ()
+ ADSCCFLG { 2,84,85,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+ ADSCMISC ()
+ ADSCDEFN ()
+ ADSCUDEF ()
+ ADSCINCD (.\Libraries\Mass_Storage\inc;.\Libraries\STM32_USB-FS-Device_Driver\inc)
+ ADSASFLG { 170,42,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+ ADSAMISC ()
+ ADSADEFN ()
+ ADSAUDEF ()
+ ADSAINCD ()
+EndOpt
+

+ 6 - 6
bsp/stm32_radio/sdcard.c

@@ -958,14 +958,14 @@ SD_Error SD_ReadBlock(uint32_t addr, uint32_t *readbuff, uint16_t BlockSize)
   }
   else if (DeviceMode == SD_DMA_MODE)
   {
-    int cnt = 0; 
+    int cnt = 0;
     SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
     SDIO_DMACmd(ENABLE);
     DMA_RxConfiguration(readbuff, BlockSize);
     while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
     {
-		cnt ++; 
-		if (cnt > 10 * 50000) 
+		cnt ++;
+		if (cnt > 10 * 50000)
 		{
 			rt_kprintf("DMA flag 0x%08x\n", DMA_GetFlagStatus(DMA2_FLAG_TC4));
 			/* Clear all DPSM configuration */
@@ -977,9 +977,9 @@ SD_Error SD_ReadBlock(uint32_t addr, uint32_t *readbuff, uint16_t BlockSize)
 			SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable;
 			SDIO_DataConfig(&SDIO_DataInitStructure);
 			SDIO_DMACmd(DISABLE);
-			errorstatus = SD_ERROR; 
+			errorstatus = SD_ERROR;
 			break;
-		} 
+		}
 	}
   }
   return(errorstatus);
@@ -3140,7 +3140,7 @@ void rt_hw_sdcard_init()
 		sdcard_device.control = rt_sdcard_control;
 
 		/* no private */
-		sdcard_device.private = RT_NULL;
+		sdcard_device.private = &SDCardInfo;
 
 		rt_device_register(&sdcard_device, "sd0",
 			RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);

+ 13 - 0
bsp/stm32_radio/stm32f10x_it.c

@@ -684,3 +684,16 @@ void DMA2_Channel2_IRQHandler(void)
     rt_interrupt_leave();
 }
 #endif
+
+/* add on 2009-12-31 usb */
+extern void CTR_HP(void);
+extern void USB_Istr(void);
+void USB_HP_CAN1_TX_IRQHandler(void)
+{
+    CTR_HP();
+}
+
+void USB_LP_CAN1_RX0_IRQHandler(void)
+{
+    USB_Istr();
+}