|
使用keil例子中的CDC改写
中断程序
- void USB_IRQHandler (void) {
- U32 disr, val, n, m;
- U32 episr, episrCur;
- disr = LPC_USB->USBDevIntSt; /* Device Interrupt Status */
- /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
- if (disr & DEV_STAT_INT) {
- LPC_USB->USBDevIntClr = DEV_STAT_INT;
- WrCmd(CMD_GET_DEV_STAT);
- val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */
- if (val & DEV_RST) { /* Reset */
- USB_Reset();
- #if USB_RESET_EVENT
- USB_Reset_Event();
- #endif
- }
- if (val & DEV_CON_CH) { /* Connect change */
- #if USB_POWER_EVENT
- USB_Power_Event(val & DEV_CON);
- #endif
- }
- if (val & DEV_SUS_CH) { /* Suspend/Resume */
- if (val & DEV_SUS) { /* Suspend */
- USB_Suspend();
- #if USB_SUSPEND_EVENT
- USB_Suspend_Event();
- #endif
- } else { /* Resume */
- USB_Resume();
- #if USB_RESUME_EVENT
- USB_Resume_Event();
- #endif
- }
- }
- goto isr_end;
- }
- #if USB_SOF_EVENT
- /* Start of Frame Interrupt */
- if (disr & FRAME_INT) {
- DEV_INT_CLR = FRAME_INT;
- USB_SOF_Event();
- }
- #endif
- #if USB_ERROR_EVENT
- /* Error Interrupt */
- if (disr & ERR_INT) {
- DEV_INT_CLR = ERR_INT;
- WrCmd(CMD_RD_ERR_STAT);
- val = RdCmdDat(DAT_RD_ERR_STAT);
- USB_Error_Event(val);
- }
- #endif
- /* Endpoint's Slow Interrupt */
- if (disr & EP_SLOW_INT) {
- episrCur = 0;
- episr = LPC_USB->USBEpIntSt;
- for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */
- if (episr == episrCur) break; /* break if all EP interrupts handled */
- if (episr & (1 << n)) {
- episrCur |= (1 << n);
- m = n >> 1;
-
- LPC_USB->USBEpIntClr = (1 << n);
- while ((LPC_USB->USBDevIntSt & CDFULL_INT) == 0);
- val = LPC_USB->USBCmdData;
-
- if ((n & 1) == 0) { /* OUT Endpoint */
- if (n == 0) { /* Control OUT Endpoint */
- if (val & EP_SEL_STP) { /* Setup Packet */
- if (USB_P_EP[0]) {
- USB_P_EP[0](USB_EVT_SETUP);
- continue;
- }
- }
- }
- if (USB_P_EP[m]) {
- USB_P_EP[m](USB_EVT_OUT);
- }
- } else { /* IN Endpoint */
- if (USB_P_EP[m]) {
- USB_P_EP[m](USB_EVT_IN);
- }
- }
- }
- }
- LPC_USB->USBDevIntClr = EP_SLOW_INT;
- }
- #if USB_DMA
- /* USB_DMA not yet supported */
- #endif /* USB_DMA */
- isr_end:
- ;
- }
复制代码 端点读写- /*
- * Read USB Endpoint Data
- * Parameters: EPNum: Endpoint Number
- * EPNum.0..3: Address
- * EPNum.7: Dir
- * pData: Pointer to Data Buffer
- * Return Value: Number of bytes read
- */
- U32 USB_ReadEP (U32 EPNum, U8 *pData) {
- U32 cnt, n;
- LPC_USB->USBCtrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN;
- do {
- cnt = LPC_USB->USBRxPLen;
- } while ((cnt & PKT_RDY) == 0);
- cnt &= PKT_LNGTH_MASK;
- for (n = 0; n < (cnt + 3) / 4; n++) {
- *((__packed U32 *)pData) = LPC_USB->USBRxData;
- pData += 4;
- }
- LPC_USB->USBCtrl = 0;
- if (((EP_MSK_ISO >> (EPNum & 0x0F)) & 1) == 0) { /* Non-Isochronous Endpoint */
- WrCmdEP(EPNum, CMD_CLR_BUF);
- }
- return (cnt);
- }
- /*
- * Write USB Endpoint Data
- * Parameters: EPNum: Endpoint Number
- * EPNum.0..3: Address
- * EPNum.7: Dir
- * pData: Pointer to Data Buffer
- * cnt: Number of bytes to write
- * Return Value: Number of bytes written
- */
- U32 USB_WriteEP (U32 EPNum, U8 *pData, U32 cnt) {
- U32 n;
- LPC_USB->USBCtrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
- LPC_USB->USBTxPLen = cnt;
- for (n = 0; n < (cnt + 3) / 4; n++) {
- LPC_USB->USBTxData = *((__packed U32 *)pData);
- pData += 4;
- }
- LPC_USB->USBCtrl = 0;
- WrCmdEP(EPNum, CMD_VALID_BUF);
- return (cnt);
- }
复制代码 端点中断程序- void USB_EndPoint2 (U32 event)
- {
- LED2_ON;
-
- switch (event)
- {
- case USB_EVT_IN:
- USBSndRdy=1;
- break;
- case USB_EVT_OUT:
- USBRecRdy=1;
- break;
- }
- }
复制代码 接收数据:
主机向端点2发送OUT包-》lpc产生USB中断(在此清除中断)-》调USB_EndPoint2 函数-》在主循环中检查 USBRecRdy状态,如果状态为1,调USB_ReadEP ,在USB_ReadEP 中读取数据
-》 调 WrCmdEP(EPNum, CMD_CLR_BUF); 释放缓存-》准备再次接受数据。
在此过程中如果不释放缓存,还会接收主机的数据吗?如果会,是否就覆盖当前缓存?
发送数据:
检查USBSndRdy状态,如果为1-》调USB_WriteEP 写数据到usb缓存,确认缓存后-》主机下一个in后数据发送到主机,产生USB_EndPoint2 IN中断, 设置 USBSndRdy=1;如果以后无数据直接写0字节数据。
此过程是否是只要确认缓存就产生in中断?确认缓存后如果主机没有in数据,接着再次写数据是否会覆盖原先的数据?
发送和接收是否不能小于1ms?
请大家帮忙分析一下! |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|