268 lines
8.5 KiB
C
268 lines
8.5 KiB
C
/*****************************************************************************
|
|
* Module : usb
|
|
* File : usb.c
|
|
* Author :
|
|
* Function : USB驱动的一些公用模块
|
|
*****************************************************************************/
|
|
#ifndef USB_H
|
|
#define USB_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
//typedef int8 bool;
|
|
|
|
#define MAX_EP 2 //最大的EP号
|
|
|
|
//in IC, in latest FPGA
|
|
#define USB_FIX_BUG_0 0 //=0, =1
|
|
#define USB_FIX_BUG_1 0 //=1, =1
|
|
#define USB_FIX_BUG_2 0 //=0, =1
|
|
#define USB_FIX_BUG_3 0 //=0, =1
|
|
#define USB_FIX_BUG_4 0 //=0, =1
|
|
|
|
#define UCFG2_CNT 0x2000
|
|
//USB SIE REG(common)
|
|
#define M_FADDR 0x00
|
|
#define M_POWER 0x01
|
|
#define M_INTRTX1 0x02
|
|
#define M_INTRTX2 0x03
|
|
#define M_INTRRX1 0x04
|
|
#define M_INTRRX2 0x05
|
|
#define M_INTRUSB 0x06
|
|
#define M_INTRTX1E 0x07
|
|
#define M_INTRTX2E 0x08
|
|
#define M_INTRRX1E 0x09
|
|
#define M_INTRRX2E 0x0A
|
|
#define M_INTRUSBE 0x0B
|
|
#define M_FRAMENUM1 0x0C
|
|
#define M_FRAMENUM2 0x0D
|
|
#define M_INDEX 0x0E
|
|
#define M_DEVCTL 0x0F
|
|
//USB SIE REG(host & slave)
|
|
#define M_TXMAXP 0x10
|
|
#define M_CSR0 0x11
|
|
#define M_TXCSR1 0x11
|
|
#define M_TXCSR2 0x12
|
|
#define M_RXMAXP 0x13
|
|
#define M_RXCSR1 0x14
|
|
#define M_RXCSR2 0x15
|
|
#define M_COUNT0 0x16
|
|
#define M_RXCOUNT1 0x16
|
|
#define M_RXCOUNT2 0x17
|
|
#define M_TXTYPE 0x18
|
|
#define M_TXINTERVAL 0x19
|
|
#define M_RXTYPE 0x1A
|
|
#define M_RXINTERVAL 0x1B
|
|
|
|
#define M_FIFOSIZE 0x1F
|
|
|
|
|
|
#define M_FIFO0 0x20 //FIFOS for endpoint0
|
|
#define M_FIFO1 0x24 //FIFOS for endpoint1
|
|
#define M_FIFO2 0x28 //FIFOS for endpoint2
|
|
|
|
/* Interrupt register bit */
|
|
#define M_INTR_SUSPEND 0x01
|
|
#define M_INTR_RESUME 0x02
|
|
#define M_INTR_RESET 0x04
|
|
#define M_INTR_SOF 0x08
|
|
#define M_INTR_CONNECT 0x10
|
|
#define M_INTR_DIS_CONNECT 0x20
|
|
#define M_INTR_SESS_REQ 0x40
|
|
#define M_INTR_VBUS_ERR 0x80
|
|
|
|
///USB DMA1_CTL/DMA2_CTL
|
|
#define UDC_BUS_ERR (1<<15)
|
|
#define UDC_MAXPKT_8BYTE(n) (((n)&0x7F)<<8)
|
|
#define UDC_EP(n) (((n)&0xF)<<4)
|
|
#define UDC_IE (1<<3)
|
|
#define UDC_MODE(n) (((n)&0x1)<<2)
|
|
#define UDC_DIR_RX ((0)<<1)
|
|
#define UDC_DIR_TX ((1)<<1)
|
|
#define UDC_EN ((1)<<0)
|
|
|
|
///UCFG1
|
|
#define DMA4_MASK (1<<22)
|
|
#define DMA3_MASK (1<<21)
|
|
#define DMA2_MASK (1<<20)
|
|
#define DMA1_MASK (1<<19)
|
|
#define VBUS_Error_MASK (1<<18)
|
|
#define Sess_Req_MASK (1<<17)
|
|
#define Discon_MASK (1<<16)
|
|
#define Conn_MASK (1<<15)
|
|
#define Reset_MASK (1<<14)
|
|
#define Resume_MASK (1<<13)
|
|
#define Suspend_MASK (1<<12)
|
|
#define EP2TX_MASK (1<<11)
|
|
#define EP1TX_MASK (1<<10)
|
|
#define EP0_MASK (1<<9)
|
|
#define EP2RX_MASK (1<<8)
|
|
#define EP1RX_MASK (1<<7)
|
|
#define SOF_MASK (1<<6)
|
|
|
|
#define USB_DIF (1<<3)
|
|
#define USB_DIM (1<<2)
|
|
#define USB_DIP (1<<1)
|
|
#define USB_TM1 (1<<0) ///0: normal mode 1:testmode, shorter time for simulation
|
|
|
|
#define USBIE_EN() //NVIC_EnableIRQ(USB_CTL_IRQn);
|
|
#define USBIE_DIS() //NVIC_DisableIRQ(USB_CTL_IRQn);
|
|
|
|
#define USB_REG_CRITICAL_ENTER() //osMutexWait(usb_reg_lock_id, osWaitForever);
|
|
#define USB_REG_CRITICAL_EXIT() //osMutexRelease(usb_reg_lock_id);
|
|
|
|
//写USB SIE寄存器
|
|
#define write_usb_reg(reg_addr, reg_data) do {p_dev->usb_hw->SIE##reg_addr = reg_data;} while(0)
|
|
//void write_usb_reg_index(uint8_t index, uint32_t reg_addr, uint8_t reg_data);
|
|
#define write_usb_reg_index(index, reg_addr, reg_data)\
|
|
do {\
|
|
USB_REG_CRITICAL_ENTER();\
|
|
p_dev->usb_hw->SIEM_INDEX = index;\
|
|
*((volatile uint8_t *)((uint32_t)&p_dev->usb_hw->SIEM_FADDR + reg_addr)) = reg_data;\
|
|
USB_REG_CRITICAL_EXIT();\
|
|
} while(0)
|
|
|
|
|
|
//读USB SIE寄存器
|
|
#define read_usb_reg(reg_addr) (p_dev->usb_hw->SIE##reg_addr)
|
|
//uint8_t read_usb_reg_index(uint8_t index, uint32_t reg_addr);
|
|
#define read_usb_reg_index(index, reg_addr, reg_data)\
|
|
do {\
|
|
USB_REG_CRITICAL_ENTER();\
|
|
p_dev->usb_hw->SIEM_INDEX = index;\
|
|
reg_data = *((volatile uint8_t *)((uint32_t)&p_dev->usb_hw->SIEM_FADDR + reg_addr));\
|
|
USB_REG_CRITICAL_EXIT();\
|
|
} while(0)
|
|
|
|
|
|
|
|
|
|
//USB当前状态机
|
|
enum {
|
|
USB_DEFAULT_STATE,
|
|
USB_ADDRESS_STATE,
|
|
USB_CONFIG_STATE
|
|
};
|
|
|
|
//EP0状态机
|
|
enum {
|
|
IDLE_STATE,
|
|
TRANSER_OVER_STATE,
|
|
TRANSFERING_STATE,
|
|
RECEIVING_STATE
|
|
};
|
|
|
|
//接收者
|
|
enum {
|
|
REQUEST_TO_DEVICE,
|
|
REQUEST_TO_INTERFACE,
|
|
REQUEST_TO_ENDPOINT
|
|
};
|
|
|
|
//设备描述符
|
|
enum {
|
|
DEVICE_DESCRIPTOR = 1,
|
|
CONFIGURATION_DESCRIPTOR,
|
|
STRING_DESCRIPTOR,
|
|
INTERFACE_DESCRIPTOR,
|
|
ENDPOINT_DESCRIPTOR,
|
|
DEVICE_QUALIFIER_DESCRIPTOR,
|
|
// OTHER_SPEED_CONFIG_DESCRIPTOR, USB 1.1没有该选项
|
|
|
|
HID_REPORT = 0x22,
|
|
};
|
|
|
|
//Feature Selector
|
|
enum {
|
|
ENDPOINT_STALL,
|
|
REMOTE_WAKEUP,
|
|
TEST_MODE
|
|
};
|
|
|
|
//检测模式
|
|
enum {
|
|
USB_CHECK_HOST, //尝试主机检测
|
|
USB_CHECK_OTG, //尝试OTG检测,是否连接PC
|
|
USB_STABLE_HOST, //已成功检测为USB主机
|
|
USB_STABLE_DEVICE, //已成功检测为USB设备
|
|
};
|
|
|
|
//返回值
|
|
enum {
|
|
USB_CONNECTED_NONE, //未连接
|
|
USB_CONNECTED_PC, //连接PC,当Device
|
|
USB_CONNECTED_DEVICE, //外接U盘,当Host
|
|
};
|
|
|
|
//USB控制结构体
|
|
struct hgusb11_dev_ctrl {
|
|
uint8_t error; //USB通信错误
|
|
|
|
struct {
|
|
uint16_t vid; //VID
|
|
uint16_t pid; //PID
|
|
uint16_t ver; //Version
|
|
} info;
|
|
|
|
//EP0接收的命令
|
|
struct {
|
|
uint8_t rtype;
|
|
uint8_t request;
|
|
uint16_t value;
|
|
uint16_t index;
|
|
uint16_t length;
|
|
} cmd;
|
|
|
|
uint8_t reserved[2];
|
|
};
|
|
|
|
struct hgusb11_dev_chk {
|
|
uint8_t check_mode;
|
|
uint8_t check_cnt;
|
|
uint8_t check_delay;
|
|
} ;
|
|
|
|
|
|
#define BYTE0(n) ((uint8_t)((uint16_t)(n)))
|
|
#define BYTE1(n) ((uint8_t)(((uint16_t)(n))>>8))
|
|
#define BYTE2(n) ((uint8_t)(((uint16_t)(((uint32_t)(n))>>8))>>8))
|
|
#define BYTE3(n) ((uint8_t)(((uint16_t)(((uint32_t)(n))>>16))>>8))
|
|
|
|
#define LOAD_U32B(p) ((((volatile uint8_t *)(p))[0]<<24) | (((volatile uint8_t *)(p))[1]<<16) | (((volatile uint8_t *)(p))[2]<<8) | (((volatile uint8_t *)(p))[3]<<0))
|
|
#define LOAD_U32L(p) ((((volatile uint8_t *)(p))[0]<<0) | (((volatile uint8_t *)(p))[1]<<8) | (((volatile uint8_t *)(p))[2]<<16)| (((volatile uint8_t *)(p))[3]<<24))
|
|
#define LOAD_U16B(p) ((((volatile uint8_t *)(p))[0]<<8) | (((volatile uint8_t *)(p))[1]<<0))
|
|
#define LOAD_U16L(p) ((((volatile uint8_t *)(p))[0]<<0) | (((volatile uint8_t *)(p))[1]<<8))
|
|
|
|
#define SAVE_U32B(p, num) do { \
|
|
((volatile uint8_t *)(p))[0] = BYTE3(num); \
|
|
((volatile uint8_t *)(p))[1] = BYTE2(num); \
|
|
((volatile uint8_t *)(p))[2] = BYTE1(num); \
|
|
((volatile uint8_t *)(p))[3] = BYTE0(num); \
|
|
} while(0)
|
|
|
|
#define SAVE_U32L(p, num) do { \
|
|
((volatile uint8_t *)(p))[0] = BYTE0(num); \
|
|
((volatile uint8_t *)(p))[1] = BYTE1(num); \
|
|
((volatile uint8_t *)(p))[2] = BYTE2(num); \
|
|
((volatile uint8_t *)(p))[3] = BYTE3(num); \
|
|
} while(0)
|
|
|
|
#define SAVE_U16B(p, num) do { \
|
|
((volatile uint8_t *)(p))[0] = BYTE1(num); \
|
|
((volatile uint8_t *)(p))[1] = BYTE0(num); \
|
|
} while(0)
|
|
|
|
#define SAVE_U16L(p, num) do { \
|
|
((volatile uint8_t *)(p))[0] = BYTE0(num); \
|
|
((volatile uint8_t *)(p))[1] = BYTE1(num); \
|
|
} while(0)
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|