📄 usbintrhandler.c
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright (C) 2002 Motorola Semiconductors HK Ltd * */// This is the main handler for USB interrups.// It will then call appropriate routine to according to the nature of the// interrupt.#include "prototype.h"#include "define.h"#include "variable.h"#include "mx1.h"void _iUsbProcessCommand(void);void ep0_interrupt(int irq, void *dev_id, struct pt_regs *regs){#ifdef KAREN_DEBUG printk("ep0_interrupt: get one \n");#endif _iUsbHandleDevReq();// DPRINTK("EP0 ISR before clear: 0x%08x\n", _reg_USBD_EP0_INTR_STAT); _reg_USBD_EP0_INTR_STAT = 0x1FF; // clear all interrupts// DPRINTK("EP0 ISR after clear : 0x%08x\n", _reg_USBD_EP0_INTR_STAT);}void ep1_interrupt(int irq, void *dev_id, struct pt_regs *regs){ U32 i;#ifdef KAREN_DEBUG printk("ep1_interrupt: get one \n");#endif // we use EOF interrupt for EP1 only --_gUsbPacketCount; if (_gUsbPacketCount > 0) {// for (i=0; i<7; i++)// _reg_USBD_EP1_FDAT = *(_gpUsbBufPtr++);// _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet// _reg_USBD_EP1_FDAT = *(_gpUsbBufPtr++); for (i=0; i<31; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = *(_gpUsbBufPtr++); _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = *(_gpUsbBufPtr++); } else { // now the CSW _reg_USBD_EP1_FDAT = 0x55534253; // signature in BIG endian for (i=0; i<4; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i]; // CSWtag _reg_USBD_EP1_FDAT = 0; // data residue _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0; // status: passed _reg_USBD_EP1_INTR_MASK |= EOF_MASK; // disable interrupt } _reg_USBD_EP1_INTR_STAT |= EOF_MASK; // clear interrupt}// handle OUT endpoint activities (command and data from host)void ep2_interrupt(int irq, void *dev_id, struct pt_regs *regs){ U8 i;#ifdef KAREN_DEBUG printk("ep2_interrupt: get one \n");#endif if (_reg_USBD_EP2_INTR_STAT & EOT_MASK) { // EOT interrupt, command from host// _reg_USB_MASK = ENABLE_CFG_CHG & ENABLE_RESET; _iUsbProcessCommand(); } if (_reg_USBD_EP2_INTR_STAT & EOF_MASK & ~_reg_USBD_EP2_INTR_MASK) { // EOF interrupt, data transfer from host complete// _iUsbProcessDataFromHost(); if (_gUsbPacketCount > 0) { while (((_reg_USBD_EP2_STAT >> 16) & 0x7F) >= 0x20) { for (i=0; i<32; i++) *(_gpUsbBufPtr++) = *((volatile U8 *)((U32)&_reg_USBD_EP2_FDAT+3)); --_gUsbPacketCount;//DPRINTK("Packet count: 0x%04x\n", _gUsbPacketCount); } if (_gUsbPacketCount == 0) { // now the CSW _reg_USBD_EP1_FDAT = 0x55534253; // signature in BIG endian for (i=0; i<4; i++) *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = _gCBW[4+i]; // CSWtag _reg_USBD_EP1_FDAT = 0; // data residue _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0; // status: passed printk("."); } }/* else { if (_gUsbDataToHost) {DPRINTK("Send ACK\n"); // return 0x5000 to host to acknowledge *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x50; _reg_USBD_EP1_FCTRL |= 0x20000000; // next is last word in packet *((volatile U8 *)((U32)&_reg_USBD_EP1_FDAT+3)) = 0x00; _gUsbDataToHost = FALSE; }// _reg_USBD_EP2_INTR_MASK |= EOF_MASK; // disable interrupt }*/ } _reg_USBD_EP2_INTR_STAT = 0x1FF; // clear all interrupts}void usb_interrupt(int irq, void *dev_id, struct pt_regs *regs)//void _UsbIntrHandler(void){// DPRINTK("Interrupt source: %d\n", irq);// DPRINTK("intr stat before: 0x%08x\n",_reg_USBD_INTR_STAT);/* // reset signalling from host ? if (_reg_USBD_INTR_STAT & RST_START_MASK) { _iUsbReset(); } // It seems that the command over mechanism is not functioning // properly. So we'll signal command over every frame.*/#ifdef KAREN_DEBUG printk("usb_interrupt: get one \n");#endif if (_reg_USBD_INTR_STAT & SOF_MASK) { _reg_USBD_CTRL |= CMD_OVER_MASK; // signal CMD_OVER } _reg_USBD_INTR_STAT = 0x800000FF;// DPRINTK("intr stat after : 0x%08x\n",_reg_USBD_INTR_STAT);/* // handle general interrupt if (_reg_USB_ISR & USB_INTR_GEN_MASK) { // nothing to be done for CFG_CHG interrupt, just clear the interrupt flag// if (_reg_USB_GEN_ISR & USB_CFG_CHG_MASK)// {// } // reset signalling from host if (_reg_USB_GEN_ISR & USB_RESET_MASK) { _iUsbReset(); } // It seems that the command over mechanism is not functioning // properly. So we'll signal command over every frame. if (_reg_USB_GEN_ISR & USB_SOF_MASK) { _reg_USB_CTRL |= USB_CTRL_CMOV_MASK; // signal CMD_OVER } _reg_USB_GEN_ISR = 0x800000FF; } // handle interrupt from EP0 (device request) if (_reg_USB_ISR & USB_INTR_EP0_MASK) { _iUsbHandleDevReq(); _reg_USB_EP0_ISR = 0x1FF; // clear all interrupts } // handle interrupt from EP3 if (_reg_USB_ISR & USB_INTR_EP3_MASK) { if (_reg_USB_EP3_ISR & USB_EPINTR_EOT_MASK) { // EOT interrupt, command from host _reg_USB_MASK = ENABLE_CFG_CHG & ENABLE_RESET; _iUsbProcessCommand(); } if (_reg_USB_EP3_ISR & USB_EPINTR_EOF_MASK) { // EOF interrupt, data transfer from host complete _iUsbProcessDataFromHost(); } _reg_USB_EP3_ISR = 0x1FF; // clear all interrupts } // handle interrupt from EP4 (EOF interrupt, data transfer to host complete) if (_reg_USB_ISR & USB_INTR_EP4_MASK) { _iUsbProcessDataToHost(); _reg_USB_EP4_ISR = 0x1FF; // clear all interrupts }*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -