📄 usb.c
字号:
}
/*we do this stuff for all tx_0 events **************************/
}
/**********************************************************************/
/* This subroutine handles TX events for FIFO1 (endpoint 1) */
/**********************************************************************/
unsigned rlen;
extern unsigned short rbuf[256];
void tx_1(void)
{
U32 Pointer,i;
txstat=read_usb(TXS1); /*get transmitter status */
/*if a transmission has completed successfully, update the data */
/*toggle and queue up a dummy packet ****************************/
if (txstat & TX_DONE)
{
FLUSHTX1; /*flush the FIFO(first of all)*/
if(txstat & ACK_STAT) /*ACK received: */
{
/*
* this DATAIN is ONLY for read operation in fact!!
* because other DATAIN operations are all less than 64 bytes
* and cannot enter thsi tx_1 isr
* so we need not other FSMstate
*/
if(BOTFSMstate == FSM4BOT_DATAIN)
{
if(BOTXfer_wResidue == 0)
{
/* set FSM state to IDLE */
BOTFSMstate = BOTFSM_IDLE;
/* handle CSW procedure */
TPBulk_CSWHandler();
}
else
{
/* send 64 byte data to the tx1 FIFO */
for(i=0; i<64; i++)
write_usb(TXD1,((INT8 *)BOTXfer_pData)[i]);
BOTXfer_pData += 64;
BOTXfer_wResidue -= 64;
//Uart_Printf("%d\n", rlen);
// Uart_Printf("rlen = %d LBA_W32 = %d BOTXfer_pData = %x BOTXfer_wResidue = %x\n",
// rlen, LBA_W32, (int)BOTXfer_pData, BOTXfer_wResidue);
/* enable TX, choose PID, and flip the data toggle */
TXEN1_PID;
}
}
else
{
}
}
}
else
{
}
}
void tx_2(void)
{}
void tx_3(void)
{}
/*******************************************************************
***** USB ALT(alternate)事件处理程序 *****
*******************************************************************/
void usb_alt(void)
{
evnt = read_usb(ALTEV); /*读入Alternate Event Register*/
/*判断为何种ALT事件 */
if(evnt & RESET_A) /*reset event */
{
write_usb(NFSR,RST_ST); /*enter reset state */
write_usb(FAR,AD_EN+0); /*set default address */
write_usb(EPC0, 0x00); /*enable EP0 only */
FLUSHTX0; /*flush TX0 and disable */
write_usb(RXC0,RX_EN); /*enable the receiver */
/*adjusting ints is nec. here in case we were in suspend */
write_usb(ALTMSK,NORMAL_ALTMSK);/*adjust interrupts */
write_usb(NFSR,OPR_ST); /*go operational */
}
else if(evnt & RESUME_A) /*resume event */
{
write_usb(ALTMSK,NORMAL_ALTMSK);/*adjust interrupts */
write_usb(NFSR,OPR_ST); /*go operational */
}
else if((evnt & SD3)&&(suscntr==0)) /*suspend event */
{
write_usb(ALTMSK,RESUME_A+RESET_A);/*adj interrupts */
write_usb(NFSR,SUS_ST); /*enter suspend state */
deep_sleep(); /*reduce power cons. */
suscntr=SUSPND_TO; /*start suspend cntr(flag prevent suspend again)*/
}
else /*spurious alt. event! */
{
}
}
/**********************************************************************/
/* This subroutine handles OUT NAK events for FIFO0 (endpoint 0) */
/**********************************************************************/
void onak0(void)
{
/*important note: even after servicing a NAK, another NAK */
/*interrupt may occur if another 'OUT' or 'IN' packet comes in */
/*during our NAK service. */
/*if we're currently doing something that requires multiple 'IN'*/
/*transactions, 'OUT' requests will get NAKs because the FIFO is*/
/*busy with the TX data. Since the 'OUT' here means a premature*/
/*end to the previous transfer, just flush the FIFO, disable the*/
/*transmitter, and re-enable the receiver. */
if (TSTBIT(status,READSTA) || TSTBIT(status,GETDESC))/*multi-pkt status stage? */
{
if( TSTBIT(status,READSTA) ) /*exit multi-packet mode */
CLR_READSTA;
if( TSTBIT(status,GETDESC) )
CLR_GETDESC;
FLUSHTX0; /*flush TX0 and disable */
write_usb(RXC0,RX_EN); /*re-enable the receiver */
}
/*we do this stuff for all onak0 events **************************/
}
/**********************************************************************/
/* This subroutine handles OUT NAK events for FIFO1 (endpoint 2) */
/**********************************************************************/
void onak1(void)
{}
/**********************************************************************/
/* This subroutine handles OUT NAK events for FIFO2 (endpoint 4) */
/**********************************************************************/
void onak2(void)
{}
/**********************************************************************/
/* This subroutine handles OUT NAK events for FIFO3 (endpoint 6) */
/**********************************************************************/
void onak3(void)
{}
/**********************************************************************/
/* This subroutine handles INP NAK events for FIFO0 (endpoint 0) */
/**********************************************************************/
void inak0(void)
{}
/**********************************************************************/
/* This subroutine handles INP NAK events for FIFO1 (endpoint 1) */
/**********************************************************************/
void inak1(void)
{}
/**********************************************************************/
/* This subroutine handles INP NAK events for FIFO02(endpoint 3) */
/**********************************************************************/
void inak2(void)
{}
/**********************************************************************/
/* This subroutine handles INP NAK events for FIFO3 (endpoint 5) */
/**********************************************************************/
void inak3(void)
{}
/*******************************************************************
***** USBN9603的中断服务程序 *****
*******************************************************************/
void __irq usb_isr(void) /*USBN9603的中断输出接在8051的INT0*/
{
/*clear interrupt source IN 41100*/
rI_ISPC = BIT_EINT0;
evnt = read_usb(MAEV); /*读入Main Event Register,以判断何种中断事件*/
if (evnt & RX_EV) /*如果为接收事件*/
{
evnt=read_usb(RXEV); /*check the RX events */
if (evnt&RXFIFO0)
rx_0(); /*endpoint 0 */
else if (evnt&RXFIFO1)
rx_1(); /*endpoint 2 */
else if (evnt&RXFIFO2)
rx_2(); /*endpoint 4(not use) */
else if (evnt&RXFIFO3)
rx_3(); /*endpoint 6(not use) */
else /*some other RX event */
{}
}
else if (evnt & TX_EV) /*如果为发送事件*/
{
evnt=read_usb(TXEV); /*check the TX events */
if (evnt&TXFIFO0)
tx_0(); /*endpoint 0 */
else if (evnt&TXFIFO1)
tx_1(); /*endpoint 1 */
else if (evnt&TXFIFO2)
tx_2(); /*endpoint 3(not use) */
else if (evnt&TXFIFO3)
tx_3(); /*endpoint 5(not use) */
else /*some other TX event */
{}
}
else if (evnt & ALT) usb_alt(); /*如果为ALT事件*/
/*NAKs can come so fast and furious (especially with OHCI hosts)*/
/*that they MUST have a lower priority than the other events. If*/
/*they did not, the other events could get starved out. */
else if (evnt & NAK)
{
evnt=read_usb(NAKEV); /*如果为NAK*/
if (evnt&NAK_O0) onak0(); /*endpoint 0 */
else if (evnt&NAK_O1) onak1(); /*endpoint 2(not use) */
else if (evnt&NAK_O2) onak2(); /*endpoint 4(not use) */
else if (evnt&NAK_O3) onak3(); /*endpoint 6(not use) */
else if (evnt&NAK_I0) inak0(); /*endpoint 0(not use) */
else if (evnt&NAK_I1) inak1(); /*endpoint 1(not use) */
else if (evnt&NAK_I2) inak2(); /*endpoint 2(not use) */
else if (evnt&NAK_I3) inak3(); /*endpoint 5 */
else /*some other NAK event */
{
}
}
else /*如果为其它的未能识别的事件*/
{
}
/*由于USBN9603 的中断为电平触发型,而有些MCU的中断触发为边沿型 */
/*为了使程序有更好的移植性,先禁止USBN9603中断输出,然后再使能它 */
/*从而得到下一次中断产生时的触发边沿。 */
evnt=read_usb(MAMSK); /*保存原来的中断设置 */
write_usb(MAMSK,0); /*禁止USBN9603的中断输出*/
write_usb(MAMSK,evnt); /*恢复原来的中断设置 */
evnt=0; /*clear the evnt flag*/
}
/*******************************************************************
***** 初始化USBN9603 *****
*******************************************************************/
void init_usb(void)
{
/*toss out any previous state ***********************************/
CLR_MLTIPKT;/*exit multi-packet mode */
usb_cfg =0;
/*对USBN9603进行一次软件复位*/
write_usb(MCNTRL,SRST); /*写 0x01 到 MCNTRL*/
/*INTOC(1-0)=00 :禁止中断输出 */
/*NAT=0 :禁止被USB总线检测 */
/*VEG=0 :禁止内部3.3V稳压 */
/*SRST=1 :进行软件复位 */
/*等待软件复位完成*/
while(read_usb(MCNTRL)&0x01==0x00)
{
usb_cfg=0;
}
evnt=read_usb(RID); /*读取USBN9603的版本识别号*/
/*该数值因为0x02,由此可判断USBN9603是否被正确地挂在总线上*/
if(evnt==0x02)
{
Uart_Printf("\n* USBN9603 is found! *");
Uart_Printf("\n* USB interface is active now! *");
Uart_Printf("\n*-----------------------------------------------------------------------*");
}
else
Uart_Printf("\nUSBN9603 is not found!Pls check your hardware!");
write_usb(MCNTRL,VGE+INT_L_O); /*写0x04+0x40=0x44 到 MCNTRL(该句能否省略?)*/
/*INTOC(1-0)=01 :中断为低电平有效输出*/
/*VEG=0 :使能内部3.3V稳压 */
/*设置USBN9603的时钟输出*/
write_usb(CCONF,CLKDIV); /*输出时钟频率为4MHZ */
/* CLKDIV=5=0x0101=11,so frequency=48MHz/(CLKDIV+1)=4MHZ*/
/*set default address, enable EP0 only **************************/
write_usb(FAR,AD_EN+0); /*FAR is "Function Address Register"*/
/*write 0x80+0x00=0x80 to FAR*/
/*AD_EN=1 :Address Enable. When set to 1, bits AD6-0 are used in address comparison.*/
/* When cleared, the device does not respond to any token on the USB bus. */
/*采用寻址方式访问端点*/
write_usb(EPC0,0x00); /*设置端点0的寻址地址*/
/* 设置USBN9603的中断屏蔽位 */
write_usb(NAKMSK,NAK_O0); /*NAK evnts*/
/*NAK_O0=0x10*/
/*当EndPoint0收到OUT token时,MAEV中的NAK位将被置位*/
// write_usb(TXMSK,TXFIFO0);
write_usb(TXMSK,TXFIFO0+TXFIFO1+TXFIFO2+TXFIFO3); /*TX events*/
/*使能EndPoint0的发送中断*/
// write_usb(RXMSK,RXFIFO0);
write_usb(RXMSK,RXFIFO0+RXFIFO1+RXFIFO2+RXFIFO3); /*RX events*/
/*使能EndPoint0的接收中断*/
write_usb(ALTMSK,NORMAL_ALTMSK);
/*NORMAL_ALTMSK=SD3+RESET_A*/
/*使能Reset和SD3中断*/
/*SD3 :Suspend Detect 3 mS. This bit is set after 3 mS of IDLE is detected */
/* on the upstream port, indicating that the device should be */
/* suspended. The suspend occurs under firmware control by writing */
/* the suspend value to the Node Functional State (NF-SR) register. */
/* This bit is cleared when the register is read. */
/*RESET :This bit is set when 2.5 mS of SEO is detected on the upstream port.*/
/* In response, the functional state should be reset (NFS in the NFSR */
/* register is set to RESET), where it must remain for at least 100 mS.*/
/* The functional state can then return to Op-erational state. This bit*/
/* is cleared when the register is read. */
write_usb(MAMSK,(INTR_E+RX_EV+NAK+TX_EV+ALT));
/*向MAMSK写入INTR_E=0x80(master interrupt enable)*/
/* 和RX_EV=0x40(receive event) */
/* 和NAK=0x10(NAK event) */
/* 和TX_EV=0x04(transmit event) */
/* 和ALT=0x02(alternate event) */
/*enable the receiver and go operational ************************/
FLUSHTX0; /*置TX0为Idle,并清除其FIFO的读写指针*/
write_usb(RXC0,RX_EN); /*使能 RX0接收 */
write_usb(NFSR,OPR_ST); /*将OPR_ST=0x02写到NFSR中,置USBN9603为Operational State*/
write_usb(MCNTRL,VGE+INT_L_O+NAT); /*允许USB总线检测到USBN9603的接入*/
// LED1=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -