日期:2014-05-16  浏览次数:20601 次

自娱自乐8之Linux UDC驱动4(自编udc驱动,基本功能完成)

直接上代码,可以和我之前写的模板比较比较

/***********************************
 Copyright(C), 2013 LDP
 FileName:  s3c2440_udc.h
 Author:    wwxxxxll
 Date:          
 Description:  
 History:       
 Author       Date            Desc
************************************/
#ifndef __S3C2440_UDC_H__
#define __S3C2440_UDC_H__
/*************配置选项**************/
#define S3C2440_DEBUG_FS  //使用debugfs
#define DEBUG
#ifdef DEBUG
#define printInfo(ARGs...) printk(ARGs)
#else
#define printInfo(ARGs...)
#endif
//struct usb_ep_ops
//#define S3C2440_NEWSTYLE  //使用udc_start
#define S3C2440_SETWEDHE  //实现set_weght方法
#define S3C2440_FIFO_STATUS //支持fifo_status方法
#define S3C2440_FIFO_FLUSH //支持fifo_flush方法

//struct usb_gadget_ops
#define S3C2440_S3C2440_GET_FRAME //支持get_frame
#define S3C2440_WAKEUP //支持wakeup功能
#define S3C2440_SELFPOWERED //selfpowered支持
//#define S3C2440_VBUS_SESSION //vbus连接控制支持
//#define S3C2440_VBBUS_DRAW
#define S3C2440X_PULLUP //usb连接控制支持

//s3c2440 有时钟控制
//寄存器CLKSLOW开启UPLL
//CLKCON开启USB device时钟,我会定义两个clk,见下面的结构体
//我可以直接操作寄存器,但是那样太粗鲁了,我们还是用平台提供
//的时钟机制解决吧
#define S3C2440_HAVE_CLK  //有专用的CLK
#ifdef S3C2440_HAVE_CLK
#define CLK_DELAY_TIME 10 //ms
#endif

#define S3C2440_USE_IRQ

//端口信息
#define S3C2440_ENDPOINTS 5 //端口数
//一个端点的最大数据包
#define EP0_FIFO_SIZE 8
#define EP1_FIFO_SIZE 64
#define EP2_FIFO_SIZE 64
#define EP3_FIFO_SIZE 64
#define EP4_FIFO_SIZE 64

#define EP1_ADDRESS 1
#define EP2_ADDRESS 2
#define EP3_ADDRESS 3
#define EP4_ADDRESS 4

#define EP1_ATTR USB_ENDPOINT_XFER_BULK
#define EP2_ATTR USB_ENDPOINT_XFER_BULK
#define EP3_ATTR USB_ENDPOINT_XFER_BULK
#define EP4_ATTR USB_ENDPOINT_XFER_BULK

//fifo长度
#define S3C2440_EP0_FIFO_SIZE 16
#define S3C2440_EP1_FIFO_SIZE 128
#define S3C2440_EP2_FIFO_SIZE 128
#define S3C2440_EP3_FIFO_SIZE 128
#define S3C2440_EP4_FIFO_SIZE 128
/***********************************/

/*************寄存器定义************/
//s3c2440 有个MISCCR控制usb1为设备还是主机
//芯片默认为设备,我就不控制了。MISCCR的USB挂起
//主要为芯片进入睡眠时用的
//如果按字节模式访问则偏移地址在大端和小端模式中是不同的。
//我是小端的地址
#define FUNC_ADDR_REG 0x140
//func_addr_reg 存储usb地址,更新地址时,第7位置位
#define PWR_REG       0x144
/*
pwr_reg:
3: USB_RESET R  主机发复位信号,由USB置位
2: MCS_RESUME R/W MCU置位来给MCU重置,在挂起模式时,产生10ms重置信号
1: SUSPEND_MODE R 设备进入挂起模式时由USB置位。
0: SUBSPEND_EN R 挂起使能位,0:禁止 1:使能
*/
//一旦 MCU 发生中断,MCU 应该读取中断相关寄存器的内容并且如果需要写回清除其内容。
#define EP_INT_REG 0x148
#define USB_INT_REG 0x158

//中断使能
#define EP_INT_EN_REG 0x15c
#define USB_INT_EN_REG 0x16c

//帧号
#define FRAME_NUM1_REG 0x170 //低字节
#define FRAME_NUM2_REG 0x174 //高字节

//通常被标记的寄存器随INDEX寄存器(INDEX_REG)(偏移地址:0X178)值而定。例如如果希望改写EP0 
//CSR寄存器,必须在写IN_CSR1寄存器前写入‘0x00’到INDEX_REG中
#define INDEX_REG 0x178

#define MAXP_REG 0x180
/*
推荐:
EP0 MAXP=8
EP1~4 MAXP=64, 64自动使能双数据包模式 就是data0和data1
*/

#define EP0_CSR 0x184 

#define IN_CSR1_REG 0x184
#define IN_CSR2_REG 0x188

#define OUT_CSR1_REG 0x190
#define OUT_CSR2_REG 0x194

//FIFO
//端点输出写计数寄存器
//此寄存器保存着包的字节数,该数由MCU卸载
#define OUT_FIFO_CNT1 0x198
#define OUT_FIFO_CNT2 0x19c

//EPn_FIFO_REG使能MCU访问EPn FIFO
#define EP0_FIFO 0x1c0
#define EP1_FIFO 0x1c4
#define EP2_FIFO 0x1c8
#define EP3_FIFO 0x1cc
#define EP4_FIFO 0x1d0

//DMA
#define EP1_DMA_CON 0x200
#define EP2_DMA_CON 0x218
#define EP3_DMA_CON 0x240
#define EP4_DMA_CON 0x258

#define EP1_DMA_UNIT 0x204
#define EP2_DMA_UNIT 0x21c
#define EP3_DMA_UNIT 0x244
#define EP4_DMA_UNIT 0x25c

#define EP1_DMA_FIFO 0x208
#define EP2_DMA_FIFO 0x220
#define EP3_DMA_FIFO 0x248
#define EP4_DMA_FIFO 0x260

#define EP1_DMA_TTC_L 0x20c
#define EP1_DMA_TTC_M 0x210
#define EP1_DMA_TTC_H 0x214
#define EP2_DMA_TTC_L 0x224
#define EP2_DMA_TTC_M 0x228
#define EP2_DMA_TTC_H 0x22c
#define EP3_DMA_TTC_L 0x24c
#define EP3_DMA_TTC_M 0x250 
#define EP3_DMA_TTC_H 0x254
#define EP4_DMA_TTC_L 0x264
#define EP4_DMA_TTC_M 0x268
#define EP4_DMA_TTC_H 0x26c

/***********************************/

/************操作定义***************/
#define WRITE_REG(_s3c2440_udc, reg, data) writel(data, _s3c2440_udc->virl_addr + reg)
#defin