📄 usb.c
字号:
if(n_size==0)
{//download is finished
total=0;
CLR_DOWNLOAD;
usb_status=0xFF;
Uart_Printf("\nNow download is finished,Please type 'r' or 'R' to run it!");
}
}
}
else
{
for(i = 0; i < 64; i++)
rx_buf[total++] = read_usb(RXD1); //rx1_buf == 512, then write to disk!
if(total%512 == 0)
{
n_size--;
if(n_size == 0)
{
write_file(FileEnd,rx_buf);
total = 0;
close_file(); //将修改后的Root information写回Block0
CLR_DOWNLOAD; //Exit download state!
usb_status = 0xFF;
}
else
{
if((total == 16*1024))
{
total = 0;
write_file(NotEnd,rx_buf);
}
}
}
}
}
else
{}
}
FLUSHRX1; /*flush RX1 and disable */
write_usb(RXC1,RX_EN); /*re-enable the receiver */
}
void rx_2(void)
{}
void rx_3(void)
{}
/***********************************/
/* USB EndPoint0(FIFO0)发送处理程序 */
/***********************************/
void tx_0(void)
{
txstat=read_usb(TXS0); /*get transmitter status */
if(txstat & TX_DONE) /*if transmit completed */
{
FLUSHTX0; /*flush TX0 and disable */
if(txstat & ACK_STAT) /*ACK received: xmit ok */
{
if(TSTBIT(status,GETDESC)||TSTBIT(status,READSTA))
{
/*move the data into the FIFO(ugly code : assume 8 packets */
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
TXEN0_PID; /*enable TX, toggle PID */
}
else /*not in multi-packet mode*/
{
if(setaddr) /*if SET_ADDRESS in progr.*/
{
write_usb(FAR,setaddr); /*load new address */
setaddr=0; /*clear state */
}
/* otherwise send a zero_length packet */
write_usb(RXC0,RX_EN); /*re-enable the receiver */
}
}
else /*no ACK: xmit failed */
{ /*this probably means we issued a stall handshake */
CLR_MLTIPKT; /*exit multi-packet mode */
write_usb(RXC0,RX_EN); /*re-enable the receiver */
}
}
/*otherwise something must have gone wrong with the previous ****/
/*transmission, or we got here somehow we shouldn't have ********/
else /*xmit didn't complete?? */
{
}
/*we do this stuff for all tx_0 events **************************/
}
/**********************************************************************/
/* This subroutine handles TX events for FIFO1 (endpoint 1) */
/**********************************************************************/
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: */
{
if(TSTBIT(status, UPLOAD)) //upload state
{
//n_size--;
for(i = 0; i < 64; i++)
write_usb(TXD1, tx_buf[total+i]);
total += 64;
if(total%512 == 0)
{
n_size--;
if(n_size == 0) //the end of file !
{
CLR_UPLOAD;
usb_status = 0xFF;
}
else
{
if((total == 16*1024))
{
total = 0;
read_file(tx_buf);
}
}
}
TXEN1_PID; //enable TX, choose PID, and flip the data toggle
}
else if(TSTBIT(status, READROOT)) //dir state
{
for(i = 0; i < 64; i++)
{
Pointer=(256-n_size)*64+i;
write_usb(TXD1,root_buf[Pointer/32][Pointer%32]); /*send data to the tx1 FIFO */
}
n_size--;
if(n_size == 0)
{
CLR_ROOT; /*last packet and clear dir flag */
usb_status = 0xFF;
}
TXEN1_PID; /*enable TX, choose PID, and flip the data toggle*/
}
else if(TSTBIT(status, READMEM)) //mem state
{
CLR_MEM;
usb_status = 0xFF;
}
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 /*如果为其它的未能识别的事件*/
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -