📄 usb.c
字号:
default: /*unsupported standard req*/
bitset(EPC0,STALL); /*stall the endpoint */
break;
}
break;
case 0x20: /*class request */
switch (usb_buf[1]) /*decode request code */
{
case GET_REPORT:
getreport();
break;
case SET_REPORT:
setreport();
break;
case GET_IDLE:
getidle();
break;
case SET_IDLE:
setidle();
break;
default: /*unsupported standard req*/
bitset(EPC0,STALL); /*stall the endpoint */
break;
}
break;
default: /*unsupported req type */
bitset(EPC0,STALL); /*stall the endpoint */
break;
}
/*the following is done for all setup packets. Note that if*/
/*no data was stuffed into the FIFO, the result of the fol- */
/*lowing will be a zero-length response. */
write_usb(TXC0,TX_TOGL+TX_EN); /*enable the TX (DATA1) */
CLRBIT(dtapid,TGL0PID); /*store NEXT PID state */
}
/*if not a setup packet, it must be an OUT packet ***************/
/* Note that there is no RX_ERR bit in RXS0, so we don't look */
/* for and handle them the way we do in the other RX event */
/* handlers. */
else
{
if (TSTBIT(status,MLTIPKT)) /*multi-pkt status stage? */
{
/*test for errors (zero length, correct PID) */
if ((rxstat& 0x5F)!=0x10) /*length error?? */
{
}
CLR_MLTIPKT; /*exit multi-packet mode */
FLUSHTX0; /*flush TX0 and disable */
}
write_usb(RXC0,RX_EN); /*re-enable the receiver */
}
/*we do this stuff for all rx_0 events **************************/
}
/**********************************************************************/
/* This subroutine handles RX events for FIFO1 (endpoint 2) */
/**********************************************************************/
void rx_1(void)
{
rxstat=read_usb(RXS1); /*get receiver status */
if(rxstat & SETUP_R)
{
}
else if (rxstat & RX_ERR)
{
}
else
{
/*check to see if this is a valid command packet **************/
/*we don't have to worry about the UART receiver stomping on */
/*us because it has a lower priority interrupt. The USB might*/
/*well stomp the UART's data, but the assumption is that any */
/*debug activity on the RS-232 port is stompable */
SETBIT(status,USB_CMD); /*select USB command mode */
rsnc=read_usb(RXD1); /*move data from FIFO */
rcmd=read_usb(RXD1);
rdta=read_usb(RXD1);
radh=read_usb(RXD1);
radl=read_usb(RXD1);
rcks=read_usb(RXD1);
if (rsnc==SYNCBYT) /*if sync code is valid */
if (rcks==(unsigned char)(rsnc+rcmd+rdta+radh+radl))
{
FLUSHTX1; /*flush TX1 and disable */
do_cmd(); /*do the command */
TXEN1_PID_NO_TGL; /*enable TX, choose PID */
}
CLRBIT(status,USB_CMD); /*exit USB command mode */
}
FLUSHRX1; /*flush RX1 and disable */
write_usb(RXC1,RX_EN); /*re-enable the receiver */
}
/**********************************************************************/
/* This subroutine handles RX events for FIFO2 (endpoint 4) */
/**********************************************************************/
void rx_2(void)
{
rxstat=read_usb(RXS2); /*get receiver status */
}
/**********************************************************************/
/* This subroutine handles RX events for FIFO3 (endpoint 6) */
/**********************************************************************/
void rx_3(void)
{
rxstat=read_usb(RXS3); /*get receiver status */
if(rxstat & SETUP_R)
{
}
else if (rxstat & RX_ERR)
{
FLUSHRX3; /*flush RX3 and disable */
}
else
{
rcount3+=32; /*update count */
}
write_usb(RXC3,RX_EN); /*re-enable the receiver */
}
/**********************************************************************/
/* This subroutine handles TX events for FIFO0 (endpoint 0) */
/**********************************************************************/
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 in multi-packet mode, queue next piece if nec. */
if(TSTBIT(status,MLTIPKT))
{
/*move the data into the FIFO */
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
TXEN0_PID; /*enable TX, choose 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 */
}
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)
{
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 & ACK_STAT) && (txstat & TX_DONE))
{
TGLBIT(dtapid,TGL1PID); /*flip the data toggle */
FLUSHTX1; /*flush the FIFO */
write_usb(TXD1,0x0DE); /*send data to the FIFO */
write_usb(TXD1,0x0AD); /*send data to the FIFO */
write_usb(TXD1,0x0BE); /*send data to the FIFO */
write_usb(TXD1,0x0EF); /*send data to the FIFO */
TXEN1_PID_NO_TGL; /*enable TX, choose PID */
}
else
{
}
}
/**********************************************************************/
/* This subroutine handles TX events for FIFO2 (endpoint 3) */
/**********************************************************************/
void tx_2(void)
{
txstat=read_usb(TXS2); /*get transmitter status */
}
/**********************************************************************/
/* This subroutine handles TX events for FIFO3 (endpoint 5) */
/**********************************************************************/
void tx_3(void)
{
txstat=read_usb(TXS3); /*get transmitter status */
FLUSHTX3; /*flush the FIFO */
/*if a transmission has completed successfully, update the data */
/*toggle and queue up a dummy packet ****************************/
if ((txstat & ACK_STAT) && (txstat & TX_DONE))
{
TGLBIT(dtapid,TGL3PID); /*flip the data toggle */
}
else
{
}
}
/**********************************************************************/
/* 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,MLTIPKT)) /*multi-pkt status stage? */
{
CLR_MLTIPKT; /*exit multi-packet mode */
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 INP NAK events for FIFO3 (endpoint 5) */
/**********************************************************************/
void inak3(void)
{
FLUSHTX3; /*flush the FIFO */
if(TSTBIT(status,RPTCHNG)) /*if new data to report */
{
queue_rpt(TXD3); /*queue a report */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -