/****************************************Copyright (c)**************************************************
** 广州周立功单片机发展有限公司
** 研 究 所
** 产品一部
**
** http://www.zlgmcu.com
**
** 文 件 名: D12Driver.c
** 最后修改日期: 2004年7月2日
** 描 述: USB驱动程序软件包: PDIUSBD12 设备端驱动程序 应用层
** 版 本: V1.0
**********************************************************************************************************/
#include "config.h"
#include "D12Config.h"
#include "D12CI.h"
#include "D12HAL.h"
#include "Chap_9.h"
#include "D12Driver.h"
extern EPPFLAGS bEPPflags;
/** Setup包处理任务堆栈 */
OS_STK TaskSetupStk[128];
/** Setup包处理任务事件指针 ***/
OS_EVENT *pSetup_Event;
/******* PDIUSBD12各端点对应的 USB 接收或发送控制块 *********/
CTRL_USB UsbRec_Ep2; //端点2接收控制块
CTRL_USB UsbRec_Ep1; //端点1接收控制块
CTRL_USB UsbSend_Ep2; //端点2发送控制块
CTRL_USB UsbSend_Ep1; //端点1发送控制块
/***********************************************************************
** 函数名称: INT8U WritePort1(INT32U len,INT8U *sendbuff,INT16U timeout)
** 功能描述: 用端点 1 发送len个字节
** 输 入: INT32U len: 发送的字节数(取值范围为0x00000001 ~ 0xFFFFFFFF)
INT8U sendbuff: 发送缓冲区指针
INT16U timeout: 超时等待时间, 必须大于等于0
** 输 出: 0: 发送成功 > 0: 发送失败(错误码)
************************************************************************/
INT8U WritePort1(INT32U len,INT8U *sendbuff,INT16U timeout)
{
return (USB_WritePort(3,16,1,&UsbSend_Ep1,sendbuff,len,timeout));
} //往端点1(端点索引号3)发送数据
/***********************************************************************
** 函数名称: INT8U WritePort2(INT32U len,INT8U *sendbuff,INT16U timeout)
** 功能描述: 用端点 2 发送len个字节
** 输 入: INT32U len: 发送的字节数(取值范围为0x00000001 ~ 0xFFFFFFFF)
INT8U *sendbuff: 发送指针
INT16U timeout: 超时时间, 必须大于等于0
** 输 出: 0: 发送成功 > 0: 发送失败(错误码)
***********************************************************************/
INT8U WritePort2(INT32U len,INT8U *sendbuff,INT16U timeout)
{
return (USB_WritePort(5,64,2,&UsbSend_Ep2,sendbuff,len,timeout));
} //往端点2(端点索引号5)发送数据
/**********************************************************************
** 函数名称: INT8U ReadPort1(INT32U len,INT8U *recbuff,INT16U timeout)
** 功能描述: 从端点 1 读出 len个字节
** 输 入: INT32U len: 要读出的字节数(取值范围为0x00000001 ~ 0xFFFFFFFF)
INT8U *recbuff: 接收数据指针
INT16U timeout: 超时时间, 必须大于等于0
** 输 出: 0: 读出成功 > 0: 读出失败(错误码)
***********************************************************************/
INT8U ReadPort1(INT32U len,INT8U *recbuff,INT16U timeout)
{
return (USB_ReadPort(2,&UsbRec_Ep1,len,recbuff,timeout));
}
/**********************************************************************
** 函数名称: INT8U ReadPort2(INT32U len,INT8U *recbuff,INT16U timeout)
** 功能描述: 从端点 2 读出len个字节
** 输 入: INT32U len: 要读出的字节数(取值范围为0x00000001 ~ 0xFFFFFFFF)
INT8U *recbuff: 接收数据指针
INT16U timeout: 超时时间, 必须大于等于0
** 输 出: 0: 读出成功 > 0: 读出失败(错误码)
**********************************************************************/
INT8U ReadPort2(INT32U len,INT8U *recbuff,INT16U timeout)
{
return (USB_ReadPort(4,&UsbRec_Ep2,len,recbuff,timeout));
}
/*********************************************************************
** 函数名称: INT8U Init_D12(void)
** 功能描述: 设置D12与硬件的连接, 初始化D12, 复位D12
** 输 入: 无
** 输 出: 0: 初始化成功 1: 初始化失败
**********************************************************************/
INT8U Init_D12(void)
{
INT32U i;
OS_ENTER_CRITICAL();
Init_D12Port(); //初始化PDIUSBD12与LPC2200的连接的硬件配置
Rst_D12(); //复位PDIUSBD12
reconnect_USB(); //重新连接USB
if (readchipid() != 0x1012){ //读取芯片ID号,如果不为 1012H
OS_EXIT_CRITICAL();
return 1; //则复位失败
}
bEPPflags.value = 0; //初始化USB事件标志变量
UsbRec_Ep1.Sem = 0; //端点1接收资源允许使用
UsbRec_Ep2.Sem = 0; //端点1接收资源允许使用
UsbSend_Ep1.Sem = 0; //端点1发送资源允许使用
UsbSend_Ep2.Sem = 0; //端点1发送资源允许使用
UsbRec_Ep1.Grp = 0; //端点1无任务等待接收
UsbRec_Ep2.Grp = 0; //端点2无任务等待接收
UsbSend_Ep1.Grp = 0; //端点1无任务等待发送
UsbSend_Ep2.Grp = 0; //端点2无任务等待发送
for (i = 0; i < OS_RDY_TBL_SIZE; i++){
UsbRec_Ep1.Tbl[i] = 0; //清空端点1和2接收与发送等待任务列表
UsbRec_Ep2.Tbl[i] = 0;
UsbSend_Ep1.Tbl[i] = 0;
UsbSend_Ep2.Tbl[i] = 0;
}
pSetup_Event = OSSemCreate(0); //创建Setup包处理任务信号量
if (pSetup_Event == NULL) //如果返回的事件指针为空
{
OS_EXIT_CRITICAL();
return 1; //则初始化失败
}
OS_EXIT_CRITICAL();
return 0; //初始化成功
}
//总线复位处理子程序
void bus_reset(void)
{
}
//DMA结束处理
void dma_eot(void)
{
}
//总线挂起改变
void usb_suspend(void)
{
}
/******************************************
** 函数名称: void Usb_Exception(void)
** 功能描述: D12中断服务程序
*******************************************/
void Usb_Exception(void)
{
INT16U i_st;
OS_ENTER_CRITICAL();; //进入D12中断服务程序时关中断
i_st = D12_ReadInterruptRegister(); //读取PDIUSBD12中断寄存器值
if(i_st != 0) {
if(i_st & D12_INT_BUSRESET)
bus_reset(); //总线复位处理
if(i_st & D12_INT_EOT)
dma_eot(); //DMA传输技术处理
if(i_st & D12_INT_SUSPENDCHANGE)
usb_suspend(); //总线挂起改变
if(i_st & D12_INT_ENDP0IN)
ep0_txdone(); //控制端点发送数据处理
if(i_st & D12_INT_ENDP0OUT)
ep0_rxdone(); //控制端点接收数据处理
if(i_st & D12_INT_ENDP1IN)
USB_WriteISR(&UsbSend_Ep1,3,16,1); //端点 1发送数据处理
if(i_st & D12_INT_ENDP1OUT)
USB_ReadISR(&UsbRec_Ep1,2,16,1); //端点 1接收数据处理
if(i_st & D12_INT_ENDP2IN)
USB_WriteISR(&UsbSend_Ep2,5,64,2); //端点 2发送数据处理
if(i_st & D12_INT_ENDP2OUT)
USB_ReadISR(&UsbRec_Ep2,4,64,2); //端点 2接收数据处理
}
//add for uC/OS-II
CLR_INTD12(); //清除PDIUSBD12的中断标志
CLR_INT(); //通知中断结束
OS_EXIT_CRITICAL(); //退出D12中断服务程序时开中断
}
/*******************************************************************
** 函数名称: void TaskSetup(void *pdata)
** 功能描述: 控制传输处理
** 输 入: void *pdata 任务参数
** 输 出: 无
** 注 意: 该任务的优先级应高于其它任务,才能在任何情况下传输Setup包
********************************************************************/
void TaskSetup(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U err;
pdata = pdata; /* Prevent compiler warning */
for (;;)
{
OSSemPend(pSetup_Event,0,&err); //等待Setup包
if (err == OS_NO_ERR){ //接收到Setup包
OS_ENTER_CRITICAL(); //关中断
control_handler(); //进行控制传输处理
OS_EXIT_CRITICAL(); //开中断
}
}
}
/*******************************************************************************************
** 函数名称: void USB_ReadISR(CTRL_USB *pUsb,INT8U endp,INT32U eppsize,INT8U buffnums)
** 功能描述: USB 端点接收中断服务程序
** 输 入: CTRL_USB *pUsb: USB 接收与发送控制结构体指针
INT8U endp: 端点索引号
INT32U eppsize: 端点最大信息包大小
INT8U buffnums: 该端点缓冲区个数(如D12的端点2有两个接收缓冲区)�
** 输 出: 无
********************************************************************************************/
void USB_ReadISR(CTRL_USB *pUsb,INT8U endp,INT3