📄 usb_isr.c
字号:
/*********************************************************************
** Module Name: USB_ISR.c **
** Author: ZhangQuan **
** Version: 1.0 **
** CreateDate: 2001-05-18 **
** Description: PDISUBD12 Interrupt Service Program **
** Remark: **
** Revision History: **
**********************************************************************/
//#include <linux/interrupt.h>
//#include <asm/segment.h>
#include "DataType.h"
#include "MC68VZ328.h"
#define PD12_DEBUG 0
#define DMA_IDLE 0x00
#define DMA_RUNNING 0x01
#define DMA_PENDING 0x02
// Variable Definitions
//UCHAR GenEpBuf[EP1_PACKET_SIZE];
// Functions Declarations
void usb_initialize(void);
void usb_isr(int irq, void* dev_id, struct pt_regs * regs);
void usb_bus_reset(void);
void ep0_rxdone(void);
void ep0_txdone(void);
void ep1_txdone(void);
void ep1_rxdone(void);
void main_rxdone(void);
void main_txdone(void);
// Functions Definitions
void usb_initialize(void) // Initialization for USB
{
cli();
//Following three instructions : Disable the interrupt level 7(Caused by keyboard)
/*PFDIR |= 0x70;
PFSEL |= 0x70;
PFPUEN |= 0x70;
// PDIUSBD12 Chip Select
PKDIR |= 0x01;
PKSEL |= 0x01;
PKPUEN |= 0x01;
// PDIUSBD12 Read/Write Control
PKDIR |= 0x60;
PKSEL |= 0x60;
PKPUEN |= 0x60;
// PDIUSBD12 Other Control
PKDIR |= 0x10;
PKSEL |= 0x10;
PKPUEN |= 0x10;
// PDIUSBD12 Data
PCDIR = 0xFF;
PCSEL = 0xFF;
PCPDEN = 0xFF;*/
// PDIUSBD12 Interrupt //Modified by Mike Chan: PD6/IRQ3
PDPUEN |= 0x40;
PDSEL &= (~0x40);
// Initialize Port Value
/*PCDATA = 0xFF;
PKDATA |= 0x01;
PKDATA |= 0x60;
PKDATA &= (~0x10);*/
bEPPflags.bits.set_d12 = 0;
// Enable PDIUSBD12 Interrupt
D12_ReadInterruptRegister();
sti();
}
//extern UCHAR Flagwrite;
//void usb_isr(int irq, void * dev_id, struct pt_regs* regs)
void usb_isr()
{
UWORD ists;
ULONG tmp = IMR;
IMR = 0x01FFFFFF;
//cli();
//if (Flagwrite == 1)
if (bD12flags.bits.BOT_state == USBFSM4BOT_DATAOVER)
return;
if (bEPPflags.bits.in_isr == 1)
return;
bEPPflags.bits.in_isr = 1;
ists = D12_ReadInterruptRegister();
// printf("in isr=%x\n",ists);
if(ists != 0x00)
{
if(ists & D12_INT_BUS_RESET)
{
usb_bus_reset();
}
else
{
if(ists & D12_INT_SUSPEND_CHANGE)
{
UCHAR ch;
ch = PKDATA;
}
if(ists & D12_INT_EP0_IN)
{
ep0_txdone();
}
if(ists & D12_INT_EP0_OUT)
{
ep0_rxdone();
}
if(ists & D12_INT_EP1_IN)
{
ep1_txdone();
}
if(ists & D12_INT_EP1_OUT)
{
ep1_rxdone();
}
if(ists & D12_INT_EP2_IN)
{
main_txdone();
}
if(ists & D12_INT_EP2_OUT)
{
main_rxdone();
}
}
}
bEPPflags.bits.in_isr = 0;
//sti();
IMR = tmp;
}
void usb_bus_reset(void)
{
UWORD i,j;
cli();
if(bEPPflags.bits.set_d12 == 0)
{
bEPPflags.bits.set_d12 = 1;
D12_SetAddressEnable(0x00,0x01);
D12_SetEndpointEnable(0x01);
D12_SetEndpointStatus(4, 0);
D12_SetEndpointStatus(5, 0);
// enable normal+sof interrupt
D12_SetDMA(D12_DMA_EP4_INT_ENABLE | D12_DMA_EP5_INT_ENABLE);
// Initialize D12 configuration
D12_SetMode(D12_NO_LAZY_CLOCK | D12_CLOCK_RUNNING | D12_SOFT_CONNECT, D12_CLOCK_12M | D12_SET_TO_ONE);
}
bD12flags.bits.BOT_state = USBFSM4BOT_IDLE;//Modified by Mike Chan
sti();
return;
}
extern void control_handler(void);
void ep0_rxdone(void)
{
UWORD ep_last, i;
cli();
ep_last = D12_ReadLastTransactionStatus(0); // Clear interrupt flag
if(ep_last & D12_SETUPPACKET)
{
//OK, it is a setup packet;
ControlData.wLength = 0;
ControlData.wCount = 0;
ep_last = D12_ReadEndpoint(0, (UCHAR *)(&(ControlData.DeviceRequest)), sizeof(ControlData.DeviceRequest));
if(ep_last != sizeof(DEVICE_REQUEST))
{
//If the package received is wrong, then let Host terminate the transfer.
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1);
bEPPflags.bits.control_state = USB_IDLE;
sti();
return;
}
//OK. the data in setup package received is right;
ControlData.DeviceRequest.wValue = SWAP(ControlData.DeviceRequest.wValue);
ControlData.DeviceRequest.wIndex = SWAP(ControlData.DeviceRequest.wIndex);
ControlData.DeviceRequest.wLength = SWAP(ControlData.DeviceRequest.wLength);
// Acknowledge setup here to unlock in/out endp
//The data are read out, so the endpoint can be reused;
D12_AcknowledgeEndpoint(0);
D12_AcknowledgeEndpoint(1);
ControlData.wLength = ControlData.DeviceRequest.wLength;
ControlData.wCount = 0;
if(ControlData.DeviceRequest.bmRequestType & (UCHAR )USB_DATA_TRANSMIT_DEVICE_TO_HOST)
{
bEPPflags.bits.control_state = USB_TRANSMIT; // get command//Modified by ChenXiaotian
control_handler();
}
else
{
if(ControlData.DeviceRequest.wLength == 0)
{
bEPPflags.bits.control_state = USB_IDLE; // set command
control_handler();
}
else
{
if(ControlData.DeviceRequest.wLength > MAX_CONTROLDATA_SIZE)
{
bEPPflags.bits.control_state = USB_IDLE;
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1); //Wrong receive
}
else
bEPPflags.bits.control_state = USB_RECEIVE; // set command with OUT token
} // set command with data
} // else set command
} // if setup packet
else if(bEPPflags.bits.control_state == USB_RECEIVE)
{
//Not the setup package, it is the phase which receives the data.
i = D12_ReadEndpoint(0, ControlData.dataBuffer + ControlData.wCount, EP0_PACKET_SIZE);
ControlData.wCount += i;
if(i != EP0_PACKET_SIZE || ControlData.wCount >= ControlData.wLength)
{
bEPPflags.bits.control_state = USB_IDLE; //Receive over
control_handler();
}
}
else
{
bEPPflags.bits.control_state = USB_IDLE;
}
sti();
}
void ep0_txdone(void)
{
SLONG i;
cli();
i = ControlData.wLength - ControlData.wCount;
D12_ReadLastTransactionStatus(1); // Clear interrupt flag
if(bEPPflags.bits.control_state != USB_TRANSMIT)
{
sti();
return;
}
if( i >= EP0_PACKET_SIZE)
{
D12_WriteEndpoint(1, ControlData.pData + ControlData.wCount, EP0_PACKET_SIZE);
ControlData.wCount += EP0_PACKET_SIZE;
bEPPflags.bits.control_state = USB_TRANSMIT;
}
else if(i != 0)
{
D12_WriteEndpoint(1, ControlData.pData + ControlData.wCount, i);
ControlData.wCount += i;
bEPPflags.bits.control_state = USB_IDLE;
}
else if(i == 0)
{
D12_WriteEndpoint(1, 0, 0); // Send zero packet at the end ???
bEPPflags.bits.control_state = USB_IDLE;
}
sti();
}
void ep1_txdone(void)
{
cli();
D12_ReadLastTransactionStatus(3); // Clear interrupt flag
sti();
}
void ep1_rxdone(void)
{
UCHAR len;
cli();
D12_ReadLastTransactionStatus(2); // Clear interrupt flag
len = D12_ReadEndpoint(2, Allbuffer, EP1_PACKET_SIZE);
if(len != 0) bEPPflags.bits.do_ep1_rxdone = 1;
sti();
}
void main_rxdone(void)
{
UCHAR c;
UCHAR *cbwpt;
ULONG i;
c = D12_ReadLastTransactionStatus(4); // Clear interrupt flag
if(!(c & D12_TRANSMIT_SUCCESS))
{
printk("Fatal Error: Isr_MainRxDone ReadLastTranactionStatus=%x\n",c);
return ;
}
//Receive the CBW block;
switch(bD12flags.bits.BOT_state)
{
UCHAR c1;
case USBFSM4BOT_IDLE: // The Only state can receive CBW
c = D12_ReadEndpointStatus(4);
if(c & (D12_BUFFER0FULL | D12_BUFFER1FULL))
{
bD12flags.bits.BOT_state = USBFSM4BOT_CBWPROC;
//TPBulk_CBWHandler();
}
break;
case USBFSM4BOT_DATAOUT:
// Normal Path, Data-Out Stage of Command/Data/Status Flow
c = D12_ReadEndpointStatus(4);
c1 = c & 0x60;
i = D12_ReadMainEndpoint(ControlData.pData + ControlData.wCount);
ControlData.wCount += i;
if(c1==0x60)
{
i = D12_ReadMainEndpoint(ControlData.pData + ControlData.wCount);
ControlData.wCount += i;
}
if(ControlData.wCount == ControlData.wLength)
{
bD12flags.bits.BOT_state = USBFSM4BOT_DATAOVER;
}
//The last frame is processed here.
/* else if(ControlData.wCount >= ControlData.wLength-64)
{
}*/
break;
case USBFSM4BOT_DATAOVER:
case USBFSM4BOT_CBWPROC:
case USBFSM4BOT_CSW:
break;
default:
// Something wrong here, Stall Bulk-Out and ask host to start recovery routine.
printk("Fatal error in MainRx !\n");
D12_SetEndpointStatus(4, 1);
D12_SetEndpointStatus(5, 1);
bD12flags.bits.BOT_state = USBFSM4BOT_STALL;
break;
}
//sti();
}
void main_txdone(void)
{
SLONG i;
UCHAR c,c1;
cli();
i = ControlData.wLength - ControlData.wCount;
D12_ReadLastTransactionStatus(5); // Clear interrupt flag
if(bD12flags.bits.BOT_state == USBFSM4BOT_CSW)
{
c = D12_ReadEndpointStatus(4);
c1= c & 0x60;
if( c & (D12_BUFFER0FULL | D12_BUFFER1FULL))
{
bD12flags.bits.BOT_state = USBFSM4BOT_CBWPROC;
//TPBulk_CBWHandler();
}
else bD12flags.bits.BOT_state = USBFSM4BOT_IDLE;
sti();
return;
}
if (bD12flags.bits.BOT_state != USBFSM4BOT_DATAIN) return;
if(i >= EP2_PACKET_SIZE)
{
D12_WriteEndpoint(5, ControlData.pData+ControlData.wCount,EP2_PACKET_SIZE);//Corrected by Mike Chan
ControlData.wCount += EP2_PACKET_SIZE;
bD12flags.bits.BOT_state = USBFSM4BOT_DATAIN;
}
else if(i != 0)
{
D12_WriteEndpoint(5, ControlData.pData, i);
ControlData.wCount += i;
TPBulk_CSWHandler();
}
else if (i == 0)
{
TPBulk_CSWHandler();
}
sti();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -