void _USBNTransmitEvent(void) { unsigned char event; void (*ptr)(); event = USBNRead(TXEV); //USBNDebug("tx event\r\n"); if(event & TX_FIFO0) _USBNTransmitFIFO0(); // dynamic function call else if(event & TX_FIFO1) { USBNRead(TXS1); if(txfifos.tx1==1){ ptr = txfifos.func1; (*ptr)(); } return; } else { #if DEBUG USBNDebug("tx event\r\n"); #endif //USBNRead(TXS1); // get transmitter status USBNRead(TXS2); // get transmitter status USBNRead(TXS3); // get transmitter status } }
void _USBNReceiveEvent(void) { unsigned char event; void (*ptr)(); char buf[64]; char *bufp=&buf[0]; event = USBNRead(RXEV); int i=0; if(event & RX_FIFO0) _USBNReceiveFIFO0(); // dynamic function call else if(event & RX_FIFO1) { USBNRead(RXS1); *bufp = USBNRead(RXD1); for(i;i<63;i++) *(++bufp)=USBNBurstRead(); ptr = RX1Callback; (*ptr)(&buf); USBNWrite(RXC1,FLUSH); USBNWrite(RXC1,RX_EN); return; } else {} }
void _USBNTransmitEvent(void) { unsigned char event; event = USBNRead(TXEV); //USBNDebug("tx event\r\n"); if(event & TX_FIFO0) _USBNTransmitFIFO0(); else { #if DEBUG USBNDebug("tx event\r\n"); #endif USBNRead(TXS1); // get transmitter status USBNRead(TXS2); // get transmitter status USBNRead(TXS3); // get transmitter status } }
void _USBNAlternateEvent(void) { unsigned char event; event = USBNRead(ALTEV); #if 0 //USBNDebug("alt event\r\n"); if(event & ALT_RESET) { USBNWrite(NFSR,RST_ST); // NFS = NodeReset USBNWrite(FAR,AD_EN+0); USBNWrite(EPC0,0x00); USBNWrite(TXC0,FLUSH); USBNWrite(RXC0,RX_EN); // allow reception USBNWrite(NFSR,OPR_ST); // NFS = NodeOperational } else if(event & ALT_SD3) { USBNWrite(ALTMSK,ALT_RESUME+ALT_RESET); // adjust interrupts USBNWrite(NFSR,SUS_ST); // enter suspend state } else if(event & ALT_RESUME) { USBNWrite(ALTMSK,ALT_SD3+ALT_RESET); USBNWrite(NFSR,OPR_ST); } else { } #endif }
void USBNStart(void) { _USBNInitEP0(); // usbn starts here USBNWrite(MCNTRL,SRST); // clear all registers while(USBNRead(MCNTRL)&SRST); //USBNWrite(CCONF, 0x80); // clock output off, divisor to 4 MHz USBNWrite(CCONF, 0x02); // clock to 16 MHz //USBNWrite(NAKMSK,0xFF); USBNWrite(NAKMSK,NAK_OUT0); USBNWrite(FAR,AD_EN+0x00); // set default address USBNWrite(EPC0,DEF); USBNWrite(TXC0,FLUSH); // FLUSHTX0; USBNWrite(RXC0,RX_EN+FLUSH); // enable EP0 receive //USBNWrite(RXC1,RX_EN); // enable EP0 receive USBNWrite(RXMSK, RX_FIFO0+RX_FIFO1+RX_FIFO2+RX_FIFO3); // data incoming EP0 USBNWrite(TXMSK, TX_FIFO0+TX_FIFO1+TX_FIFO2+TX_FIFO3); // data incoming EP0 USBNWrite(ALTMSK, ALT_RESET+ALT_SD3); USBNWrite(MAMSK, (INTR_E+RX_EV+ALT+TX_EV+NAK) ); USBNWrite(NFSR,OPR_ST); USBNWrite(MCNTRL, VGE+NAT+INT_L_P); // VGE, no NAT, interrupt on high return ; }
void USBNInterrupt(void) { unsigned char maev,mask; maev = USBNRead(MAEV); if(maev & RX_EV) _USBNReceiveEvent(); else if(maev & TX_EV) _USBNTransmitEvent(); else if(maev & ALT) _USBNAlternateEvent(); else if(maev & NAK) _USBNNackEvent(); mask = USBNRead(MAMSK); USBNWrite(MAMSK,0x00); // disable irq USBNWrite(MAMSK,mask); }
// class requests void USBNDecodeClassRequest(DeviceRequest *req,EPInfo* ep) { UARTWrite("class"); static unsigned char serialNotification[10] = {0xa1,0x20,0,0,0,0,2,0,3,0}; int loop; switch(req->bRequest) { case 0x20: //SET_LINE_CODING: UARTWrite("set line\r\n"); USBNWrite(RXC0,RX_EN); USBNRead(RXD0); USBNRead(RXD0); USBNRead(RXD0); USBNRead(RXD0); USBNRead(RXD0); USBNRead(RXD0); USBNRead(RXD0); //USBNWrite(RXC0,RX_EN); //USBNWrite(RXC0,FLUSH); USBNWrite(TXC0,FLUSH); USBNWrite(TXC0,TX_TOGL+TX_EN); break; case 0x21: // GET_LINE_CODING: //UARTWrite("get line coding"); USBNWrite(TXC0,FLUSH); // baud rate USBNWrite(TXD0,0x80); USBNWrite(TXD0,0x25); USBNWrite(TXD0,0); USBNWrite(TXD0,0); USBNWrite(TXD0,0); //stopbit USBNWrite(TXD0,0); // parity USBNWrite(TXD0,8); // databits interrupt_ep_send(); USBNWrite(TXC0,TX_TOGL+TX_EN); break; case 0x22: //SET_CONTROL_LINE_STATE: //UARTWrite("set ctrl line state"); USBNWrite(TXC1,FLUSH); // fill endpoint fifo for(loop=0;loop<8;loop++) USBNWrite(TXD1,serialNotification[loop]); //send and control togl bit interrupt_ep_send(); USBNWrite(TXC0,TX_TOGL+TX_EN); break; } }
void _USBNTransmitFIFO0(void) { unsigned char txstat; txstat = USBNRead(TXS0); // get transmitter status #if DEBUG USBNDebug("t"); #endif if(txstat & TX_DONE) // if transmit completed { USBNWrite(TXC0,FLUSH); // flush TX0 and disable //USBNDebug("tx done "); if(txstat & ACK_STAT) // ACK received { //USBNDebug("tx ack "); if(EP0tx.Index < EP0tx.Size) { //USBNDebug("next packets "); _USBNTransmit(&EP0tx); } else // not in multi-packet mode { //USBNDebug("no multi packet "); //USBNWrite(RXC0,FLUSH); // re-enable the receiver //USBNWrite(TXC0,TX_EN); // re-enable the receiver USBNWrite(RXC0,RX_EN); // re-enable the receiver } } else // this probably means we issued a stall handshake { #if DEBUG USBNDebug("stall handshake "); #endif //USBNFunctionInfo.GetDesc=0; // exit multi-packet mode USBNWrite(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 { #if DEBUG USBNDebug("tx0 error\n"); #endif } // we do this stuff for all tx_0 events }
void _USBNNackEvent(void) { unsigned char event; event = USBNRead(NAKEV); //UARTWrite("n"); //USBNWrite(RXC0,FLUSH); //re-enable the receiver //USBNWrite(RXC0,RX_EN); //re-enable the receiver /* USBNWrite(RXC1,FLUSH); //re-enable the receiver USBNWrite(RXC1,RX_EN); //re-enable the receiver */ //USBNWrite(TXC1,FLUSH); //re-enable the receiver //USBNWrite(TXC0,TX_EN); //re-enable the receiver //USBNWrite(TXC1,TX_EN); //enable the TX (DATA1) /* if(EP0tx.DataPid==1){ //EP0tx.DataPid=0; USBNWrite(TXC0,TX_TOGL+TX_EN); //enable the TX (DATA1) } else { //EP0tx.DataPid=1; USBNWrite(TXC0,TX_EN); //enable the TX (DATA1) } */ /* if(EP0tx.DataPid==0){ //ep->DataPid=1; USBNWrite(TXC0,TX_EN); //re-enable the receiver } else{ //ep->DataPid=0; USBNWrite(TXC0,TX_TOGL+TX_EN); //enable the TX (DATA1) } */ /* if (EP0tx.Size > EP0tx.usbnfifo) //multi-pkt status stage? { //USBNDebug("flush"); USBNWrite(TXC0,FLUSH); //flush TX0 and disable //USBNWrite(RXC0,RX_EN); //re-enable the receiver EP0tx.DataPid = 1; } */ }
void _USBNNackEvent(void) { unsigned char event; //void (*ptr)(); event = USBNRead(NAKEV); //SendHex(event); //ptr = rxfifos.nack_callback; //(*ptr)((unsigned int)event); if(event & 0x01) { } /* transmit fifo 1 */ if(event & 0x02) { //USBNWrite(RXC1,FLUSH); //re-enable the receiver //USBNWrite(RXC1,RX_EN); //re-enable the receiver /* USBNWrite(TXC1,FLUSH); //re-enable the receiver USBNWrite(TXC1,TX_LAST+TX_EN+TX_TOGL); USBNWrite(TXC1,FLUSH); //re-enable the receiver USBNWrite(TXC1,TX_LAST+TX_EN); */ //USBNWrite(TXC1,RX_EN); //re-enable the receiver } /* USBNWrite(RXC1,FLUSH); //re-enable the receiver USBNWrite(RXC1,RX_EN); //re-enable the receiver #if DEBUG USBNDebug("nack event\r\n"); #endif if (EP0tx.Size > EP0tx.usbnfifo) //multi-pkt status stage? { #if DEBUG USBNDebug("flush"); #endif USBNWrite(TXC0,FLUSH); //flush TX0 and disable USBNWrite(RXC0,RX_EN); //re-enable the receiver EP0tx.DataPid = 1; } */ }
void _USBNNackEvent(void) { unsigned char event; event = USBNRead(NAKEV); //USBNWrite(RXC1,FLUSH); //re-enable the receiver //USBNWrite(RXC1,RX_EN); //re-enable the receiver /* if (EP0tx.Size > EP0tx.usbnfifo) //multi-pkt status stage? { //USBNDebug("flush"); USBNWrite(TXC0,FLUSH); //flush TX0 and disable //USBNWrite(RXC0,RX_EN); //re-enable the receiver EP0tx.DataPid = 1; } */ }
void _USBNAlternateEvent(void) { unsigned char event; event = USBNRead(ALTEV); #if DEBUG USBNDebug("alt event\r\n"); #endif if(event & ALT_RESET) { USBNWrite(NFSR,RST_ST); // NFS = NodeReset USBNWrite(FAR,AD_EN+0); USBNWrite(EPC0,0x00); USBNWrite(TXC0,FLUSH); USBNWrite(RXC0,RX_EN); // allow reception USBNWrite(NFSR,OPR_ST); // NFS = NodeOperational #if DEBUG USBNDebug("reset\r\n"); #endif } if(event & ALT_SD3) { USBNWrite(ALTMSK,ALT_RESUME+ALT_RESET); // adjust interrupts /* USBNWrite(NFSR,SUS_ST); // enter suspend state USBNDebug("sd3\r\n"); */ } if(event & ALT_RESUME) { USBNWrite(ALTMSK,ALT_SD3+ALT_RESET+ALT_RESUME); /* USBNWrite(EPC0,0x00); USBNWrite(RXC0,RX_EN); // allow reception USBNWrite(TXC0,FLUSH); USBNWrite(NFSR,OPR_ST); USBNDebug("resume\r\n"); */ } if(event & ALT_EOP) { #if DEBUG USBNDebug("eop\r\n"); #endif } }
//this is only my debug tool void Terminal(char cmd) { char h,l; unsigned char tmp; int i; struct list_entry *ptr; char *values; switch(cmd) { case 'i': USBNStart(); break; // write to usb register case 'w': //UARTWrite("write to USB reg:"); //USBNDEBUGPRINT("write to USB reg:"); h = UARTGetChar(); l = UARTGetChar(); SendHex(AsciiToHex(h,l)); tmp = AsciiToHex(h,l); UARTWrite("value:"); h = UARTGetChar(); l = UARTGetChar(); SendHex(AsciiToHex(h,l)); //USBNWrite(tmp,AsciiToHex(h,l)); UARTWrite("result:"); SendHex(USBNRead(tmp)); UARTWrite("\r\n"); break; // read from usb register case 'r': UARTWrite("read USB reg:"); h = UARTGetChar(); l = UARTGetChar(); SendHex(AsciiToHex(h,l)); UARTWrite("->"); SendHex(USBNRead(AsciiToHex(h,l))); UARTWrite("\r\n"); break; case 'h': UARTWrite("i usbn init procedure\r\n"); UARTWrite("w write USBN Register <h,l>(address) <h,l> (value) e.g 05 00\r\n"); UARTWrite("r read USBN Register <h,l> e.g. 02 ( RID)\r\n"); UARTWrite("s show all USBN Registers\r\n"); UARTWrite("b send test data from func to host\r\n"); UARTWrite("d show descriptors\r\n"); break; // show all registers case 's': for(i=0;i<=63;i++) { SendHex(i); UARTWrite("->"); SendHex(USBNRead(i)); UARTWrite("\r\n"); } break; case 'd': USBNDebug("\r\nDescriptor List\r\n"); ptr = DescriptorList; while(ptr != NULL) { values = (char*)ptr->data; SendHex(ptr->type); SendHex(ptr->len); SendHex(ptr->conf); SendHex(ptr->interf); USBNDebug(" "); for(i=0;i<ptr->len;i++) SendHex(values[i]); USBNDebug("\r\n"); ptr=ptr->next; } break; case 'b': UARTWrite("send test data from fifo1\r\n"); int j,i; char stat; USBNWrite(TXC1,FLUSH); USBNWrite(TXD1,0x01); for(j=0;j<63;j++) USBNBurstWrite((unsigned char)j); USBNWrite(TXC1,TX_LAST+TX_EN); //USBNWrite(TXC1,TX_LAST+TX_EN+TX_TOGL); break; case 'p': USBNWrite(TXC1,TX_LAST+TX_EN); break; default: UARTWrite("unknown command\r\n"); } }
void _USBNReceiveEvent(void) { unsigned char event; void (*ptr)(); char buf[64]; char *bufp=&buf[0]; event = USBNRead(RXEV); char tmp; int i=0; USBNDebug("rx event\r\n"); if(event & RX_FIFO0) _USBNReceiveFIFO0(); // dynamic function call else if(event & RX_FIFO1) { USBNRead(RXS1); *bufp = USBNRead(RXD1); for(i=0;i<63;i++) *(++bufp)=USBNBurstRead(); if(rxfifos.rx1==1){ ptr = rxfifos.func1; (*ptr)(&buf); } USBNWrite(RXC1,FLUSH); USBNWrite(RXC1,RX_EN); return; } // dynamic function call else if(event & RX_FIFO2) { USBNRead(RXS2); *bufp = USBNRead(RXD2); for(i=0;i<63;i++) *(++bufp)=USBNBurstRead(); if(rxfifos.rx2==1){ ptr = rxfifos.func2; (*ptr)(&buf); } USBNWrite(RXC2,FLUSH); USBNWrite(RXC2,RX_EN); return; } // dynamic function call else if(event & RX_FIFO3) { USBNRead(RXS3); for(i=0;i<64;i++) buf[i]=USBNRead(RXD3); if(rxfifos.rx3==1){ ptr = rxfifos.func1; (*ptr)(&buf); } } else {} }
// ******************************************************************** // Receive and Transmit functions for EPs // ******************************************************************** void _USBNReceiveFIFO0(void) { unsigned char rxstatus; char Buf[8]; DeviceRequest *req; int i; #if DEBUG USBNDebug("rx\r\n"); #endif rxstatus = USBNRead(RXS0); if(rxstatus & SETUP_R) { for(i=0;i<8;i++){ Buf[i] = USBNRead(EP0rx.usbnData); } #if DEBUG for(i=0;i<8;i++) SendHex(Buf[i]); // type - get descr or set address USBNDebug("\r\n"); #endif req = (DeviceRequest*)(Buf); USBNWrite(RXC0,FLUSH); // make sure the RX is off USBNWrite(TXC0,FLUSH); // make sure the TX is off USBNWrite(EPC0,USBNRead(EPC0)&0x7F); // turn of stall switch (req->bmRequestType & 0x60) // decode request type { case DO_STANDARD: // standard request USBNDebug("HALLO STANDARD "); SendHex(req->bRequest); USBNDebug("\n\r"); switch (req->bRequest) // decode request code { case CLR_FEATURE: #if DEBUG USBNDebug("CLR FEATURE\n\r"); #endif //_USBNClearFeature(req); break; case GET_CONFIGURATION: #if DEBUG //USBNDebug("GET CONFIG\n\r"); #endif _USBNGetConfiguration(req); break; case GET_DESCRIPTOR: #if DEBUG USBNDebug("GET DESCRIPTOR\n\r"); #endif _USBNGetDescriptor(req); break; case GET_INTERFACE: #if DEBUG USBNDebug("GET INTERFACE\n\r"); #endif break; case GET_STATUS: #if DEBUG #endif USBNDebug("GET STATUS\n\r"); //_USBNGetStatus(req); USBNWrite(TXC0,FLUSH); USBNWrite(TXD0,1); USBNWrite(TXD0,0); USBNWrite(TXC0,TX_TOGL+TX_EN); //enable the TX (DATA1) break; case SET_ADDRESS: #if DEBUG USBNDebug("SET ADDRESS "); #endif _USBNSetAddress(req); break; case SET_CONFIGURATION: #if DEBUG USBNDebug("SET CONFIGURATION\n\r"); #endif _USBNSetConfiguration(req); break; case SET_FEATURE: #if DEBUG USBNDebug("SET FEATURE\n\r"); #endif USBNWrite(TXC0,TX_TOGL+TX_EN); //enable the TX (DATA1) break; case SET_INTERFACE: #if DEBUG USBNDebug("SET INTERFACE\n\r"); #endif USBNWrite(TXC0,TX_TOGL+TX_EN); //enable the TX (DATA1) break; default: // unsupported standard req #if DEBUG USBNDebug("unsupported standard req\n\r"); #endif USBNWrite(EPC0,USBNRead(EPC0)+STALL); // stall the endpoint break; } break; case DO_CLASS: // class request #if DEBUG USBNDebug("Class request\n\r"); #endif //USBNDecodeClassRequest(req); USBNWrite(TXC0,TX_TOGL+TX_EN); //enable the TX (DATA1) break; case DO_VENDOR: // vendor request #if DEBUG USBNDebug("Vendor request\n\r"); #endif USBNDecodeVendorRequest(req); USBNWrite(TXC0,TX_TOGL+TX_EN); //enable the TX (DATA1) break; default: // unsupported req type #if DEBUG USBNDebug("unsupported req type\r\n"); #endif USBNWrite(EPC0,USBNRead(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. // only for stage 2 transfers if(req->bmRequestType == 0x00) USBNWrite(TXC0,TX_TOGL+TX_EN); //enable the TX (DATA1) } else // if not a setuppacket { USBNDebug("error transmit\r\n"); if (EP0tx.Size > EP0tx.usbnfifo) // multi-pkt status stage? { if ((rxstatus& 0x5F)!=0x10) // length error?? { #if DEBUG USBNDebug("length error\r\n"); #endif } EP0tx.Size=0; // exit multi-packet mode USBNWrite(TXC0,FLUSH); // flush TX0 and disable USBNWrite(RXC0,RX_EN); // re-enable the receiver } } }