提交 aecf1601 编写于 作者: wuyangyong's avatar wuyangyong

add mass_storage for stm32_radio

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@269 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 e79dec8f
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
#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);
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
/******************** (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****/
......@@ -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
......@@ -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);
......
......@@ -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();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册