Files
2025-08-27 09:51:58 +01:00

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