📄 usbdevdma.c
字号:
if ((ucEpIndex % 2) != 0) {
__usbDevDMAWriteISR(&Ctrl_Usb[ucEpIndex - 2],ucEpIndex);
} else {
__usbDevDMAReadISR(&Ctrl_Usb[ucEpIndex - 2],ucEpIndex);
}
}
if ((ucEpIndex % 2) == 0) {
USBEpDMAEn |= (0x01 << ucEpIndex); /* 重新使能该端点DMA功能 */
}
USBEoTIntClr |= (INT32U)(0x01 << ucEpIndex); /* 清除传输结束中断状态寄存器 */
}
}
}
/*********************************************************************************************************
** Function name: __usbDevDMASystemError
** Descriptions: DMA 系统中断错误处理
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void __usbDevDMASystemError (void)
{
INT8U ucEpIndex = 0;
unsigned long ulEpState = 0;
ulEpState = USBSysErrIntSt; /* 读取系统错误中断状态寄存器 */
for (ucEpIndex = 2; ucEpIndex < 5; ucEpIndex++) {
if(ulEpState & ((INT32U)(0x01 << ucEpIndex))) {
__usbDevDMAInitEndpointDD(ucEpIndex); /* 重新初始化DD */
USBEpDMAEn = (INT32U)(0x01 << ucEpIndex); /* 重新使能该端点的DMA功能 */
USBSysErrIntClr |= (INT32U)(0x01 << ucEpIndex); /* 清除系统错误中断 */
if ((ucEpIndex % 2) != 0) {
USBEpIntEn |= (INT32U)(0x01 << ucEpIndex); /* 重新使能该 IN 端点从机中断 */
}
}
}
}
/*********************************************************************************************************
** Function name: __usbDevDMANewDDDone
** Descriptions: DMA 新 DD 请求中断服务程序
** input parameters: ucEpIndex: 物理端点索引
** pstUsb: USB传输控制块结构体指针
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void __usbDevDMANewDDDone (INT8U ucEpIndex,CTRL_USB *pstUsb)
{
INT32U ulLeftLen = 0;
if (pstUsb->bEpUsed != 0) {
/* 有任务在等待接收 */
if (pstUsb->cnt >= pstUsb->len) {
/* 如果接收完毕 */
OSSemPost(Ctrl_Usb[ucEpIndex - 2].Ep_Sem);
} else {
ulLeftLen = pstUsb->len - pstUsb->cnt; /* 计算未传输字节数 */
__usbDevDMASetTransLength(ucEpIndex,ulLeftLen); /* 设置DMA接收/发送的字节长度 */
}
}
}
/*********************************************************************************************************
** Function name: __usbDevDMANewDDRequest
** Descriptions: DMA 新 DD 请求中断服务程序
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void __usbDevDMANewDDRequest (void)
{
INT8U ucEpIndex = 0;
unsigned long ulEpIntState = 0;
ulEpIntState = USBNDDRIntSt; /* 读取新DD请求中断状态寄存器 */
for (ucEpIndex = 2; ucEpIndex <= 5; ucEpIndex++) {
if(ulEpIntState & ((INT32U)(0x01 << ucEpIndex))) {
__usbDevDMANewDDDone(ucEpIndex,&Ctrl_Usb[ucEpIndex - 2]); /* 重新设置该端点的DD */
USBNDDRIntClr = (INT32U)(0x01 << ucEpIndex); /* 清除新DD请求中断 */
if ((ucEpIndex % 2) != 0) {
USBEpIntEn |= (unsigned long)(0x01 << ucEpIndex); /* 重新使能该端点从机中断 */
}
}
}
}
/*********************************************************************************************************
下面为提供给应用层调用的函数
*********************************************************************************************************/
/*********************************************************************************************************
** Function name: __usbDevDMAInit
** Descriptions: 初始化LPC23xx USB设备控制器的DMA引擎
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void __usbDevDMAInit (void)
{
__usbDevDMAInitUdcaTable(); /* 初始化UDCA表 */
__usbDevDMAInitEndpointDD(2); /* 初始化各端点的DD */
__usbDevDMAInitEndpointDD(3);
__usbDevDMAInitEndpointDD(4);
__usbDevDMAInitEndpointDD(5);
USBDMAIntEn = USBDMA_EOT_INT | /* 使能DMA的传输结束中断 */
USBDMA_NDD_INT | /* 使能DMA的新DD请求中断 */
USBDMA_ERR_INT; /* 使能DMA的系统错误中断 */
USBEpDMAEn = (0x01 << 2) | /* 使能端点DMA功能 */
(0x01 << 3) |
(0x01 << 4) |
(0x01 << 5);
}
/*********************************************************************************************************
** Function name: __usbDevDMAService
** Descriptions: DMA 中断服务程序
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void __usbDevDMAService(void)
{
unsigned long ulIntState = 0;
ulIntState = USBDMAIntSt; /* 读DMA中断状态寄存器 */
if (ulIntState & USBDMA_EOT_INT) {
__usbDevDMATransferEnd(); /* 传输结束中断 */
}
if (ulIntState & USBDMA_NDD_INT) {
__usbDevDMANewDDRequest(); /* 新DD请求中断 */
}
if (ulIntState & USBDMA_ERR_INT) {
__usbDevDMASystemError(); /* 系统错误中断 */
}
}
/*********************************************************************************************************
** Function name: __usbDevDMAReadPort
** Descriptions: DMA模式下,从USB Device的OUT端点FIFO中读取数据
** input parameters: ucEpIndex 物理端点索引号2,4等
** ucBufNum 物理端点FIFO个数
** pstUsb 指向物理端点传输控制块结构体的指针
** pucRcvBuf 接收数据缓冲区指针
** ulReadLen 待读取字节数
** usWaitTime 超时等待时间ms,为0时无限等待
** output parameters: 无
** Returned value: 0:操作成功;>0:操作失败
*********************************************************************************************************/
INT8U __usbDevDMAReadPort (INT8U ucEpIndex,
INT8U ucBufNum,
CTRL_USB *pstUsb,
INT8U *pucRcvBuf,
INT32U ulReadLen,
INT16U usWaitTime)
{
INT8U ucErr = 0;
OS_ENTER_CRITICAL();
ucErr = __usbDevRwParam(pstUsb,pucRcvBuf); /* 检查参数正确性 */
if (ucErr != USB_NO_ERR) {
OS_EXIT_CRITICAL();
return ucErr; /* 返回错误码 */
}
OS_EXIT_CRITICAL();
OS_ENTER_CRITICAL();
pstUsb->buff = pucRcvBuf;
pstUsb->len = ulReadLen; /* 要接收的字节长度 */
pstUsb->cnt = 0;
__usbDevDMASetTransLength(ucEpIndex,ulReadLen);
OS_EXIT_CRITICAL();
OSSemPend(pstUsb->Ep_Sem,
usWaitTime,
&ucErr); /* 等待DMA接收数据的完成 */
OS_ENTER_CRITICAL();
pstUsb->bEpUsed = 0;
OS_EXIT_CRITICAL();
if (ucErr == OS_NO_ERR) {
return USB_NO_ERR; /* 接收成功 */
} else {
return USB_ERR_WR_TIMEOUT; /* 接收超时错误 */
}
}
/*********************************************************************************************************
** Function name: __usbDevDMAWritePort
** Descriptions: DMA模式下,向USB Device的IN端点FIFO中写入数据
** input parameters: ucEpIndex 物理端点索引号2,4等
** ucBufNum 物理端点FIFO个数
** pstUsb 指向物理端点传输控制块结构体的指针
** pucSendBuf 发送数据缓冲区
** ulSendLen 待发送字节数
** usWaitTime 超时等待时间ms,为0时无限等待
** output parameters: 无
** Returned value: 0:操作成功;>0:操作失败
*********************************************************************************************************/
INT8U __usbDevDMAWritePort (INT8U ucEpIndex,
INT8U ucBufNum,
CTRL_USB *pstUsb,
INT8U *pucSendBuf,
INT32U ulSendLen,
INT16U usWaitTime)
{
INT8U i = 0;
INT8U ucEpState = 0;
INT8U ucErr = 0;
INT32U ulSetLen = 0;
INT8U *pucDstBuf = NULL;
OS_ENTER_CRITICAL();
ucErr = __usbDevRwParam(pstUsb,pucSendBuf); /* 检查参数正确性 */
if (ucErr != USB_NO_ERR) {
OS_EXIT_CRITICAL();
return ucErr; /* 返回错误码 */
}
OS_EXIT_CRITICAL();
OS_ENTER_CRITICAL();
pstUsb->buff = pucSendBuf;
pstUsb->len = ulSendLen;
pstUsb->cnt = 0;
for (i = 0; i < ucBufNum; i++) {
ucEpState = __usbDevSelectEndpoint(ucEpIndex);
if ((ucEpState & 0x60) != 0) { /* 接收/发送缓冲区不空 */
__usbDevSetEndpointStatus(ucEpIndex, 1); /* 禁止 IN 端点 */
}
}
pucDstBuf = __usbDevDMAGetBuffer(ucEpIndex); /* 取得该端点的DMA缓冲区首地址 */
ulSetLen = __usbDevDMASetTransLength(ucEpIndex,ulSendLen);
memcpy(pucDstBuf,pucSendBuf,ulSetLen); /* 复制数据到DMA发送缓冲区 */
pstUsb->cnt = pstUsb->cnt + ulSetLen; /* 计数器计数 */
__usbDevDMAStartIN(ucEpIndex); /* 启动 IN 端点的 DMA 传输 */
OS_EXIT_CRITICAL();
OSSemPend(pstUsb->Ep_Sem,
usWaitTime,
&ucErr); /* 等待 DMA 发送数据的完成 */
pstUsb->bEpUsed = 0;
if (ucErr == OS_NO_ERR) {
return USB_NO_ERR; /* 发送成功 */
} else {
return USB_ERR_WR_TIMEOUT; /* 发送成功 */
}
}
#endif
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -