Hello all
I am Raju Kamal, a Student from University of offenburg, Germany. Now I am faceing a problem to implement the USB-CDC protocal by using MAX3420e interface with our Microprocessor. Can any body send me the c source code for MAX3420e for USB-CDC. It will be gratefull from me!!!
Best regards Raju Kamal
ok, i am sending my code with couple of pages: #include <io.h> #include <string.h> #include "SD_driver.h" #include "FAT.h" #include "MAX3420E_BF1.h" // MAX3420E registers (rREGNAME), bits (bmBITNAME), and subroutine-definitions
//Hauptprogramm int main() { long int g; int i; int msec_timer=0; int PC_DTR=0; int USB_int=0;
// Enumeration, Initialisierung des internen FPGA-USB-Controllers ////////// for(g=0;g<4000000;g++); putport(0x13,4); for(g=0;g<3000000;g++); putport(0x13,0); for(g=0;g<3000000;g++); //Warte bis USB bereit! //////////////////////////////////////////////////////////////////////////// // Enumeration, Initialisierung des USB-Maxim3420E-Controllers ///////////// initialize_MAX(); // Enumeration-Interrupt abwarten for(g=0;g<3000000;g++); //Warte bis MaxUSB enumeriert ist
USB_writeln(_Copyright); //Ausgabe der Versionsnummer
if(loadData()!=0) USB_writeln("Karte nicht lesbar!\r\n\0"); while(1) //Endlosschleife der Befehlzeile { USB_writeln("\r\nSD\0"); USB_writeln(_path); //Aktueller Pfad USB_writeln(">\0");
MaxUSB_readln(_stinp); //Befehl einlesen USB_writeln("\r\n\0"); USB_writeln2(" juhu\r\n\0");
if((getport(0x16)&1)!=0) //SD-Karte gesteckt? Nein -> Meldung USB_writeln("Keine Karte vorhanden!\r\n\0"); else if(checkState()!=0) //SD-Karte initialisiert? { if(loadData()!=0) USB_writeln("Karte nicht lesbar!\r\n\0"); } else { for(i=0;_stinp[i]!='\0';i++)//Eingabe in Großbuchstaben wandeln if(_stinp[i]>0x60&&_stinp[i]<0x7B) _stinp[i]-=0x20;
if(runProc(_stinp)!=0) //Auswertung der Befehlszeile
USB_writeln("Befehl oder Dateiname nicht gefunden\r\n\0"); }
} return 0; }
// USB-Maxim3420E Routinen #include "EnumApp_enum_data.h" //CDC enumeration data #include "USB_SPI_COM.c" #include "USB_INIT.c" #include "USB_Enumeration.c" //#include "USB_Interrupt_handle.c" #include "USB_CDC_Appl.c" // SD-Karte bzw. Dateisystemroutinen #include "SD_driver.c" #include "FAT.c"
Now why did you post your code without specifying that it was code?
Look once more at the information you see when posting comments - there is one sentence specifically mentioning what you should do when posting code. If you don't follow that instruction, the code you paste will be practically unreadable.
// basic function call that handles a SETUP transfer request. // The main loop calls this function whenever the MAX3420E asserts the SUDAVIRQ bit. void _USBmax3420E_ENUM(void) { readbytes(rSUDFIFO,9,SUD); // got a SETUP packet. Read 8 SETUP bytes
switch(SUD[bmRequestType]&0x60) // Parse the SETUP packet. For request type, look only at b6&b5 { case 0x00: std_request(); break; case 0x20: class_request(); break; // just a stub/placeholder in this program // case 0x40: vendor_request(); break; // just a stub/placeholder in this program default: STALL_EP0 // unrecognized request type // If no legal case value is found, the correct peripheral // response is to send the STALL handshake instead of // ACK or NAK to indicate that it failed to recognize the request. } }
// Standard USB request void std_request(void) { BYTE a;
switch(SUD[bRequest]) // bRequest byte of the SETUP data packet // The ‘SR_’ names in the switch statement correspond to the nomenclature // in Chapter 9 of the USB Specification, which defines the USB standard // requests and data formats. // The SET_FEATURE and CLEAR_FEATURE requests are served by a single feature() // function that takes an argument indicating which operation, set (1) or // clear (0), is required. The SET_ADDRESS request does nothing but set the // ACKSTAT bit by doing a dummy read to the REVISION register. This is // because the MAX3420E hardware automatically handles the Set_Address request. { case SR_GET_DESCRIPTOR: send_descriptor(); break; case SR_SET_INTERFACE: set_interface(); break; case SR_GET_INTERFACE: get_interface(); break; case SR_GET_CONFIGURATION: get_configuration(); break; case SR_SET_CONFIGURATION: set_configuration(); break; case SR_SET_ADDRESS: a= rregAS(rFNADDR); break; // discard return value default: STALL_EP0 //wreg(9,0x23); } }
// ************************************************************************** // // ************************************************************************** // // About Descriptors // Our application uses the following USB descriptor types: // - Device // - Configuration // *Interface // - Endpoint // - String // - (Report) // The include file EnumApp_enum_data.h contains the various descriptors used to // give our peripheral device its personality. A USB device can have multiple // configurations and interfaces, but our application uses only one of each. // The descriptors in parenthesis above are unique to the HID class,and would // be omitted by a non-HID device.
void send_descriptor(void) { WORD reqlen,sendlen,desclen; BYTE *pDdata; // pointer to ROM Descriptor data to send int send_ZLP=FALSE; // // NOTE This function assumes all descriptors are 64 or fewer bytes and can be sent in a single packet // The send_descriptor function uses two variables to determine the number of bytes // to send: the requested length, reqlen; and the actual descriptor length, desclen, // which it retrieves from the descriptor tables. The function starts by setting // desclen = 0. If desclen is still zero after all the descriptor-type checks are // complete, a valid descriptor type was not found and the function sends the STALL handshake. // The requested lengths are found in the wLengthL and wLengthH bytes of the SUD array. // After loading this 16-bit value into the reqlen variable, the function uses a // switch statement to check for various values of wValueH, which indicates the descriptor type.
desclen = 0; // check for zero as error condition (no case statements satisfied) reqlen = SUD[wLengthL] + 256*SUD[wLengthH]; // 16-bit // showword(reqlen);
switch (SUD[wValueH]) // wValueH is descriptor type { case GD_DEVICE: desclen = DD[0]; // descriptor length pDdata =(BYTE*) DD; break;
case GD_CONFIGURATION: if(SUD[wLengthL] > CD[2]) desclen = CD[2]; // Config descriptor includes interface, header and ep descriptors (67 Bytes [0x0043]) else desclen = SUD[wLengthL];
if(SUD[wLengthH]!=0) desclen = CD[2]; // wLengthH=1 (last byte) pDdata = (BYTE *) CD; break;
case GD_STRING: desclen = strDesc[SUD[wValueL]][0]; // wValueL=string index, array[0] is the length pDdata =(BYTE*) strDesc[SUD[wValueL]]; // point to first array element break; case CS_INTERFACE:
if(SUD[wIndexL]==0) // Interface Number=0. Del EndPoint 2 (interrupción), Communication { //if(SUD[wLengthL]>CD[9]) desclen = CD[9]; //else desclen = SUD[wLengthL]; pDdata = (BYTE *) &CD[9]; }
else if (SUD[wIndexL]==1)// Interface Number=1. Del EndPoint 1 (bulk), Datos { //if(SUD[wLengthL]>CD[44]) desclen = CD[44]; //else desclen = SUD[wLengthL]; pDdata = (BYTE *) &CD[44]; } break;
case GD_REPORT: desclen = CD[25]; pDdata = (BYTE*)RepD; break;
} // end switch on descriptor type
sorry every body i send again from the first
int main() { long int g; int i; int msec_timer=0; int PC_DTR=0; int USB_int=0; // Enumeration, Initialisierung des internen FPGA-USB-Controllers ////////// for(g=0;g<4000000;g++); putport(0x13,4); for(g=0;g<3000000;g++); putport(0x13,0); for(g=0;g<3000000;g++); //Warte bis USB bereit! //////////////////////////////////////////////////////////////////////////// // Enumeration, Initialisierung des USB-Maxim3420E-Controllers ///////////// initialize_MAX(); // Enumeration-Interrupt abwarten for(g=0;g<3000000;g++); //Warte bis MaxUSB enumeriert ist USB_writeln(_Copyright); //Ausgabe der Versionsnummer if(loadData()!=0) USB_writeln("Karte nicht lesbar!\r\n\0"); while(1) //Endlosschleife der Befehlzeile { USB_writeln("\r\nSD\0"); USB_writeln(_path); //Aktueller Pfad USB_writeln(">\0"); // USB_readln(_stinp); //Befehl einlesen MaxUSB_readln(_stinp); // USB_writeln(_stinp); USB_writeln("\r\n\0"); USB_writeln2(" juhu\r\n\0"); if((getport(0x16)&1)!=0) //SD-Karte gesteckt? Nein -> Meldung USB_writeln("Keine Karte vorhanden!\r\n\0"); else if(checkState()!=0) //SD-Karte initialisiert? { if(loadData()!=0) USB_writeln("Karte nicht lesbar!\r\n\0"); } else { for(i=0;_stinp[i]!='\0';i++)//Eingabe in Großbuchstaben wandeln if(_stinp[i]>0x60&&_stinp[i]<0x7B) _stinp[i]-=0x20; if(runProc(_stinp)!=0) //Auswertung der Befehlszeile USB_writeln("Befehl oder Dateiname nicht gefunden\r\n\0"); } } return 0; }
void _USBmax3420E_ENUM(void) { readbytes(rSUDFIFO,9,SUD); // got a SETUP packet. Read 8 SETUP bytes switch(SUD[bmRequestType]&0x60) // Parse the SETUP packet. For request type, look only at b6&b5 { case 0x00: std_request(); break; case 0x20: class_request(); break; // just a stub/placeholder in this program // case 0x40: vendor_request(); break; // just a stub/placeholder in this program default: STALL_EP0 // unrecognized request type // If no legal case value is found, the correct peripheral // response is to send the STALL handshake instead of // ACK or NAK to indicate that it failed to recognize the request. } } // Standard USB request void std_request(void) { BYTE a; switch(SUD[bRequest]) // bRequest byte of the SETUP data packet // The ‘SR_’ names in the switch statement correspond to the nomenclature // in Chapter 9 of the USB Specification, which defines the USB standard // requests and data formats. // The SET_FEATURE and CLEAR_FEATURE requests are served by a single feature() // function that takes an argument indicating which operation, set (1) or // clear (0), is required. The SET_ADDRESS request does nothing but set the // ACKSTAT bit by doing a dummy read to the REVISION register. This is // because the MAX3420E hardware automatically handles the Set_Address request. { case SR_GET_DESCRIPTOR: send_descriptor(); break; case SR_SET_INTERFACE: set_interface(); break; case SR_GET_INTERFACE: get_interface(); break; case SR_GET_CONFIGURATION: get_configuration(); break; case SR_SET_CONFIGURATION: set_configuration(); break; case SR_SET_ADDRESS: a= rregAS(rFNADDR); break; // discard return value default: STALL_EP0 //wreg(9,0x23); } } ************************************************************************** / // About Descriptors // Our application uses the following USB descriptor types: // - Device // - Configuration // *Interface // - Endpoint // - String // - (Report) // The include file EnumApp_enum_data.h contains the various descriptors used to // give our peripheral device its personality. A USB device can have multiple // configurations and interfaces, but our application uses only one of each. // The descriptors in parenthesis above are unique to the HID class,and would // be omitted by a non-HID device. void send_descriptor(void) { WORD reqlen,sendlen,desclen; BYTE *pDdata; // pointer to ROM Descriptor data to send int send_ZLP=FALSE; // // NOTE This function assumes all descriptors are 64 or fewer bytes and can be sent in a single packet // The send_descriptor function uses two variables to determine the number of bytes // to send: the requested length, reqlen; and the actual descriptor length, desclen, // which it retrieves from the descriptor tables. The function starts by setting // desclen = 0. If desclen is still zero after all the descriptor-type checks are // complete, a valid descriptor type was not found and the function sends the STALL handshake. // The requested lengths are found in the wLengthL and wLengthH bytes of the SUD array. // After loading this 16-bit value into the reqlen variable, the function uses a // switch statement to check for various values of wValueH, which indicates the descriptor type. desclen = 0; // check for zero as error condition (no case statements satisfied) reqlen = SUD[wLengthL] + 256*SUD[wLengthH]; // 16-bit switch (SUD[wValueH]) // wValueH is descriptor type { case GD_DEVICE: desclen = DD[0]; // descriptor length pDdata =(BYTE*) DD; break; case GD_CONFIGURATION: if(SUD[wLengthL] > CD[2]) desclen = CD[2]; // Config descriptor includes interface, header and ep descriptors (67 Bytes [0x0043]) else desclen = SUD[wLengthL]; if(SUD[wLengthH]!=0) desclen = CD[2]; // wLengthH=1 (last byte) pDdata = (BYTE *) CD; break; case GD_STRING: desclen = strDesc[SUD[wValueL]][0]; // wValueL=string index, array[0] is the length pDdata =(BYTE*) strDesc[SUD[wValueL]]; // point to first array element break; case CS_INTERFACE: if(SUD[wIndexL]==0) // Interface Number=0. Del EndPoint 2 (interrupción), Communication { //if(SUD[wLengthL]>CD[9]) desclen = CD[9]; //else desclen = SUD[wLengthL]; pDdata = (BYTE *) &CD[9]; } else if (SUD[wIndexL]==1) // Interface Number=1. Del EndPoint 1 (bulk), Datos { //if(SUD[wLengthL]>CD[44]) desclen = CD[44]; //else desclen = SUD[wLengthL]; pDdata = (BYTE *) &CD[44]; } break; case GD_REPORT: desclen = CD[25]; pDdata = (BYTE*)RepD; break; } // end switch on descriptor type
///////////// Send out the Enumeration data to the bus ///////////////////////// if (desclen!=0) // one of the case statements above filled in a value { sendlen = desclen; // Send Lower data if((desclen % 64) == 0) send_ZLP=TRUE; // Flag to send ZLP while(desclen > 0) { if (desclen>64) sendlen=64; // if packet>64 bytes else sendlen=desclen; // if packet<=64 bytes while(!(rreg(rEPIRQ) & bmIN0BAVIRQ)); // Waiting for Enumeration-FIFO While out buff. isn't free // USB_writeln("\n\r\0"); writebytes(rEP0FIFO,sendlen,pDdata);// Write data in FIFO (EP_CONTROL) pDdata=(pDdata+sendlen); if (desclen < 64) wregAS(rEP0BC,sendlen); // load EP0BC to arm the EP0-IN transfer & ACKSTAT else wreg(rEP0BC,sendlen); // load EP0BC to arm the EP0-IN transfer & ACKSTAT desclen-=sendlen; // Resta los datos ya enviados } if(send_ZLP) wregAS(rEP0BC,0); // load EP0BC to arm the EP0-IN transfer & ACKSTAT } else STALL_EP0; // none of the descriptor types match } // ************************************************************************** // // ************************************************************************** // // FUNCTION: Set/Get_Feature. Call as feature(1) for Set_Feature or feature(0) for Clear_Feature. // There are two set/clear feature requests: // To a DEVICE: Remote Wakeup (RWU). // To an ENDPOINT: Stall (EP3 only for this app) // void feature(BYTE sc) { int b; BYTE mask,a; if((SUD[bmRequestType]==0x02) // dir=h->p, recipient = ENDPOINT && (SUD[wValueL]==0x00) // wValueL is feature selector, 00 is EP Halt && (SUD[wIndexL]==0x83)) // wIndexL is endpoint number IN3=83 { mask=rreg(rEPSTALLS); // read existing bits if(sc==1) // set_feature { mask += bmSTLEP3IN; // Halt EP3IN ep3stall=1; } else // clear_feature { // mask &= ~bmSTLEP3IN; // UnHalt EP3IN b = ~bmSTLEP3IN; mask &=b; ep3stall=0; wreg(rCLRTOGS,bmCTGEP3IN); // clear the EP3 data toggle } wreg(rEPSTALLS,(mask|bmACKSTAT)); // Don't use wregAS for this--directly writing the ACKSTAT bit } else if ((SUD[bmRequestType]==0x00) // dir=h->p, recipient = DEVICE && (SUD[wValueL]==0x01)) // wValueL is feature selector, 01 is Device_Remote_Wakeup { RWU_enabled = sc<<1; // =2 for set, =0 for clear feature. The shift puts it in the get_status bit position. a=rregAS(rFNADDR); // dummy read to set ACKSTAT } else STALL_EP0 } ************************************************************************** // // The get_status function in Figure 19 first decodes that portion of the USB // peripheral to which the request is directed: device, interface, or endpoint. void get_status(void) { BYTE testbyte; testbyte=SUD[bmRequestType]; switch(testbyte) { case 0x80: // directed to DEVICE wreg(rEP0FIFO,(RWU_enabled+1)); // first byte is 000000rs where r=enabled for RWU and s=self-powered. wreg(rEP0FIFO,0x00); // second byte is always 0 wregAS(rEP0BC,2); // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer break; case 0x81: // directed to INTERFACE wreg(rEP0FIFO,0x00); // this one is easy--two zero bytes wreg(rEP0FIFO,0x00); wregAS(rEP0BC,2); // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer break; case 0x82: // directed to ENDPOINT if(SUD[wIndexL]==0x83) // We only reported ep3, so it's the only one the host can stall IN3=83 { wreg(rEP0FIFO,ep3stall); // first byte is 0000000h where h is the halt (stall) bit wreg(rEP0FIFO,0x00); // second byte is always 0 wregAS(rEP0BC,2); // load byte count, arm the IN transfer, ACK the status stage of the CTL transfer break; } else STALL_EP0 // Host tried to stall an invalid endpoint (not 3) default: STALL_EP0 // don't recognize the request } } / ************************************************************************** // void set_interface(void) // All we accept are Interface=0 and AlternateSetting=0, otherwise send STALL { BYTE dumval; if((SUD[wValueL]==0) // wValueL=Alternate Setting index &&(SUD[wIndexL]==0)) // wIndexL=Interface index dumval=rregAS(rFNADDR); // dummy read to set the ACKSTAT bit else STALL_EP0 } // ************************************************************************** // void get_interface(void) // Check for Interface=0, always report AlternateSetting=0 { if(SUD[wIndexL]==0) // wIndexL=Interface index { wreg(rEP0FIFO,0); // AS=0 wregAS(rEP0BC,1); // send one byte, ACKSTAT } else STALL_EP0 } ************************************************************************** void set_configuration(void) {BYTE a; configval=SUD[wValueL]; // Store the config value if(configval != 0) // If we are configured, SETBIT(rUSBIEN,bmSUSPIE); // start looking for SUSPEND interrupts a=rregAS(rFNADDR); // dummy read to set the ACKSTAT bit } void get_configuration(void) { wreg(rEP0FIFO,configval); // Send the config value wregAS(rEP0BC,1); }
************************************************************************** // void class_request(void) { switch (SUD[bRequest]) { case SEND_ENCAPSULATED_COMMAND: wregAS(rEP0BC, 0); break; // send_encapsulated_command(); break; case GET_ENCAPSULATED_RESPONSE: wregAS(rEP0BC, 0); break; // send_encapsulated_command(); break; // get_encapsulated_response(); break; case SET_COMM_FEATURE: break; case GET_COMM_FEATURE: break; case CLEAR_COMM_FEATURE:break; case SET_LINE_CONDING: { wregAS(rEP0BC, 0); // EnvÃa un paquete de longitud 0 para la etapa de 'STATUS' (?) if(SUD[wLengthL]>0) { while(!(rreg(rEPIRQ) & bmOUT0DAVIRQ) && SUD[7]<=5) SUD[7]++; readbytes(rEP0FIFO,SUD[wLengthL],(unsigned char *)&SUD[0]); // Lee la configuración serie por el EP0 (hay que cambiar algo para que lea?) } } break; case GET_LINE_CODING: { wregAS(rEP0BC, 0); // EnvÃa un paquete de longitud 0 para la etapa de 'STATUS' (?) writebytes(rEP0FIFO,SUD[wLengthL],(unsigned char *)&SerialConf[0]); wreg(rEP0BC, SUD[wLengthL]); } break; case SET_CONTROL_LINE_STATE: { if(configval) { USB_init=1; // Si llega a este punto, el dispositivo ha terminado de inicializarse if((SUD[wValueL]&0x01)==0x01)// PC listo para aceptar tramas del AZC PC_DTR=1; if(SUD[wValueL]==0x00) // Se ha cortado la comunicación con el PC PC_DTR=0; } wregAS(rEP3INBC, 0); } break; case SEND_BREAK: break; default: STALL_EP0; // none of the descriptor types match } } void vendor_request(void) { STALL_EP0; }
// Intialisation from the USB-Maxim3420E-Controller void initialize_MAX(void) { BYTE rd; int int_mask; // software flags configval=0; // at pwr on OR bus reset we're unconfigured Suspended=0; RWU_enabled=0; // Set by host Set_Feature(enable RWU) request // Mask out of the USB-Maxim-Interrupt in the Interruptcontroller of the SIRIUS-System // USB-Interrupt-Position in SIRIUS-System: Bit 7 int_mask= ((getport(0x23)) & 0xBF); putport (0x23, int_mask); // Always set the FDUPSPI bit in the PINCTL register FIRST if you are using the SPI port in // full duplex mode. This configures the port properly for subsequent SPI accesses. // Fullduplex means SPI with Data-In and Data-Out wires // INTLEVEL=0 --> Edge-Interrupts ; INTLEVEL=1 --> Level-Interrupts // POSINT=0 --> 1-0 transition for interrupts ; POSINT=1 --> 0-1 transition for interrupts //------------------------------------------------------------------------------ // PINCTL-Register: // | EP3INAK | EP2INAK | EP0INAK | FDUPSPI | INTLEVEL | POSINT | GPXB | GPXA | //------------------------------------------------------------------------------ //wreg(rPINCTL,(bmFDUPSPI+bmPOSINT+gpxSOF)); // (17h) MAX3420: SPI=full-duplex, INT=from 0 to 1 for interrupt, GPX=SOF wreg(rPINCTL,0x13); // MAX3420: SPI=full-duplex, INTLEVEL=0(edge-ints), POSINT=0 --> 1-0 interrupts, GPX=SOF // DEBUG //rd = rreg(rPINCTL); //showbyte(rd); // Maxim-USB-Chip reset to initial conditions Reset_MAX(); // This is a self-powered design, so the host could turn off Vbus while we are powered. // Therefore set the VBGATE bit to have the MAX3420E automatically disconnect the D+ // pullup resistor in the absense of Vbus. Note: the VBCOMP pin must be connected to Vbus // or pulled high for this code to work--a low on VBCOMP will prevent USB connection. wreg(rUSBCTL,(bmCONNECT+bmVBGATE)); // VBGATE=1 disconnects D+ pullup if host turns off VBUS // In SIRIUS-System the Interrupt line is inverted !! // For a POSINT=0 -> 1-0 transistion --> inverter in SIRIUS-System // --> Interrupt-Edge-Register must be programmed to 0-1 transition means high active int_mask= ((getport(0x22)) | 0x40); putport (0x22, int_mask); //ENABLE_IRQS //wreg(rEPIEN,0x34); //bmSUDAVIE+bmIN3BAVIE+bmOUT1DAVIE = 110100b =64hex wreg(rEPIEN,0x3C); //bmSUDAVIE+bmIN3BAVIE+bmIN2BAVIE+bmOUT1DAVIE = 0011 1100b =3Chex wreg(rUSBIEN,(bmURESIE+bmURESDNIE)); wreg(rCPUCTL,bmIE); // Enable the INT pin // Enbling the USB-Maxim-Interruptbit in the SIRIUS-Interrupcontroller int_mask= ((getport(0x23)) | 0x40); //int_mask = getport(0x23); //int_mask = int_mask | 0x40; putport (0x23, int_mask); } // Reset Routine welche den Max-Chip zurücksetzt. void Reset_MAX(void) { BYTE dum; wreg(rUSBCTL,0x20); // chip reset wreg(rUSBCTL,0x00); // remove the reset do // Chip reset stops the oscillator. Wait for it to stabilize. { dum=rreg(rUSBIRQ); dum &= bmOSCOKIRQ; } while (dum==0); }
// Possible Interrupts for our application: // a. Setup Data arrived (SUDAVIRQ). // b. The host requested keyboard data by sending a data request to EP3-IN. // c. The host suspended the bus by stopping traffic for three milliseconds. // d. The host initiated a bus reset. // e. The host completed bus reset signaling. // Poll the Interrupt line from the USB-Max-Chip // --> Later it should work automtically in a Interrupt-Service-Routine //BYTE MAX_Int_Pending(void) //{ //return (BYTE)((USB_CYPRESSFLAG&0x01)==1); // USB_Cypressflag=1 --> true //} // *********************************** // // Interrupt Service Requests // *********************************** // // This function checks 4 IRQ bits // 1. bmSUDAVIRQ A SETUP packet arrived. // The host controls a device by sending SETUP packets. // 2. bmIN3BAVIRQ The host asked for another data packet from the HID keyboard. // It uses endpoint 3-IN for this request. BAV means Buffer Available. // 3. bmURESIRQ The host started signaling a bus reset. // 4. bmUSBRESDNIRQ The host finished signaling a bus reset //void _service_irqs(void) void _service_irqs(void) { // Read out the two IRQ-Register and save the result in variables BYTE itest1,itest2; itest1 = rreg(rEPIRQ); // Check the EPIRQ bits itest2 = rreg(rUSBIRQ); // Check the USBIRQ bits // // Debug it // beep(45,46); // Debug-AHI-Ton // USB_writeln("itest1="); // showByte(itest1); // USB_writeln("itest2="); // showByte(itest2); // USB_writeln("\n\r\0"); if(itest1 & bmSUDAVIRQ) // Check for SETUP data { // beep(45,46); // Debug-AHI-Ton wreg(rEPIRQ,bmSUDAVIRQ); // clear the SUDAV IRQ _USBmax3420E_ENUM(); } if(itest1 & bmIN3BAVIRQ) // Was an EP3-IN packet just dispatched to the host? { // do_IN3(); // Yes--load another keystroke and arm the endpoint } // NOTE: don't clear the IN3BAVIRQ bit here--loading the EP3-IN byte // count register in the do_IN3() function does it. if((configval != 0) && (itest2&bmSUSPIRQ)) // HOST suspended bus for 3 msec { wreg(rUSBIRQ,(bmSUSPIRQ+bmBUSACTIRQ)); // clear the IRQ and bus activity IRQ // L2_ON // turn on the SUSPEND light // L3_OFF // turn off blinking light (in case it's on) Suspended=1; // signal the main loop } // The last two checks handle USB bus reset. These code sections clear the // IRQ bits and turn a bus reset light on and off. Note that MAX3420E code // should always include a test for a USB bus reset. This is because the // MAX3420E clears most of its interrupt enable register bits during a USB bus // reset. Therefore, the code should be alert to a bus reset. When the reset is // complete (signaled by the USBRESDN IRQ), it should re-enable the interrupts // that it is using for the application. if(rreg(rUSBIRQ)& bmURESIRQ) { // USB_writeln("Clear URESIRQ\n\0"); wreg(rUSBIRQ,bmURESIRQ); // clear the IRQ } if(rreg(rUSBIRQ) & bmURESDNIRQ) { // USB_writeln("Clear URESDNIRQ\n\0"); wreg(rUSBIRQ,bmURESDNIRQ); // clear the IRQ bit // Suspended=0; // in case we were suspended //ENABLE_IRQS // ...because a bus reset clears the IE bits wreg(rEPIEN,(bmSUDAVIE+bmIN3BAVIE)); wreg(rUSBIEN,(bmURESIE+bmURESDNIE)); } }
// ********************************************************* // // ****************** SPI - Routinen *********************** // // ********************************************************* // // ------------------------------------------------------------ // The code below customizes this app for the SIRIUS-uC-System // microprocessor and the Rowley compiler. Only this // section changes if you use a different uP and/or compiler. // ------------------------------------------------------------ // ************************************************************************** // // First byte of every SPI transfer is a command byte like following format: // ---------------------------------------- // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | // ---------------------------------------- // |Reg4|Reg3|Reg2|Reg1|Reg0| 0 |DIR |ACK | // ---------------------------------------- // Bit7 to 3 = Register Address // Bit1 = Direction (DIR=0=Read ; DIR=1=Write) // Bit0 = ACKSTAT bit in R9 // ************************************************************************** // // Liest ueber den SPI-Bus ein Register des Max-USB-Chips aus BYTE rreg(BYTE reg) { BYTE dum; // putport(0x3E, 0x66); putport(SPI_SIRIUS_PORT_STEUER,0x03); // Set CS2=0 writeSPI(reg); // Set on USB-Max-Chip the reg number w. dir=0 (IN) dum = readSPI(); // Read the register value putport(SPI_SIRIUS_PORT_STEUER,0x07); // Set CS2=1 return(dum); } // Schreibt ueber den SPI-Bus ein Register des Max-USB-Chips void wreg(BYTE reg, BYTE dat) { putport(SPI_SIRIUS_PORT_STEUER,0x03); // 0000_0011 --> Mode0 , CS2=0 reg = reg+2; // Write-Bit = +2 writeSPI(reg); // Send the register-number with the DIR bit (b1) set to WRITE writeSPI(dat); // Send the data to the register putport(SPI_SIRIUS_PORT_STEUER,0x07); // Set CS2 high } // Liest ueber den SPI-Bus ein Register des Max-USB-Chips aus. // Das ACKSTAT-Bit wird im Commando-Byte gesetzt BYTE rregAS(BYTE reg) { BYTE dum; putport(SPI_SIRIUS_PORT_STEUER,0x03); // Set CS2=0 writeSPI(reg+1); // Reg number with dir=0 (IN) and ACKSTAT=1 dum = readSPI(); // Read the register value putport(SPI_SIRIUS_PORT_STEUER,0x07); // Set CS2=1 return(dum); } // Schreibt ueber den SPI-Bus ein Register des Max-USB-Chips void wregAS(BYTE reg, BYTE dat) { putport(SPI_SIRIUS_PORT_STEUER,0x03); // 0000_0011 --> Mode0 , CS2=0 reg = reg+3; // Write-Bit und Ack-Bit = +3 writeSPI(reg); // Reg number with DIR=1 (write) and ACKSTAT=1 writeSPI(dat); // Send the data to the register putport(SPI_SIRIUS_PORT_STEUER,0x07) ; // Set CS2 high } // Liest N-Bytes ueber den SPI-Bus eines Register des Max-USB-Chips aus. void readbytes(BYTE reg, BYTE N, BYTE *p) { BYTE j; putport(SPI_SIRIUS_PORT_STEUER,0x03); // 0000_0011 --> Mode0 , CS2=0 writeSPI(reg); // Write-Bit b1=0 to command a read operation // Read-Loop for(j=0; j<N; j++) { *p = readSPI(); // Store it in the data array p++; // Bump the pointer } putport(SPI_SIRIUS_PORT_STEUER,0x07); // Set CS2 high } // Schreibt N-Bytes ueber den SPI-Bus eines Register des Max-USB-Chips. void writebytes(BYTE reg, BYTE N, BYTE *p) { BYTE j,wd; putport(SPI_SIRIUS_PORT_STEUER,0x03); // 0000_0011 --> Mode0 , CS2=0 writeSPI( reg+2); // write bit b1=1 to command a write operation // Writes N Bytes for(j=0; j<N; j++) { wd = *p; // write the array value // showbyte(wd); writeSPI(wd); // write the byte from the array position p++; // Bump the pointer } putport(SPI_SIRIUS_PORT_STEUER,0x07); // Set CS2 high } // Zeigt ueber den intern FPGA-integrierten USB-Controller ein Byte im USB-COM an void showByte(char Byte) { int i; char x; char *e={"00\0"}; for(i=1;i>=0;i--) { x=(Byte&0xF); Byte=Byte>>4; if(x<10) e[i]=x+0x30; else e[i]=x+0x41-10; } USB_writeln(e); } //Word in HEX ausgeben void showword(U16 Word) { int i; U08 x; char *e={"0000\0"}; for(i=3;i>=0;i--) { x=(Word&0xF); Word=Word>>4; if(x<10) e[i]=x+0x30; else e[i]=x+0x41-10; } USB_writeln(e); } void check_for_resume(void) { // SPI_ini(0); // USB_CSE; putport(SPI_SIRIUS_PORT_STEUER,0x03); if(rreg(rUSBIRQ) & bmBUSACTIRQ) // THE HOST RESUMED BUS TRAFFIC Suspended=0; // no longer suspended // USB_CSD; putport(SPI_SIRIUS_PORT_STEUER,0x07); }
void USB_writeln2(char *name) { int g; // namelength = sizeof(name); // so we can check for the end of the message // showByte(namelength); // while(USB_Max_EP3_flag==0) {} // wait for an interrupt which set the flag //beep(0x55,0x55); for(g=0; g < 64; g++) { // USB_writeln("test"); if (name[g]==0) // Strings are 0 terminated //wreg( rEP1OUTFIFO,0); // Rest of the bytes are 0 wreg(rEP2INFIFO,0); else //wreg(rEP1OUTFIFO,name[g]); wreg(rEP2INFIFO,name[g]); // Load the string (64 times) // wreg( rEP1OUTFIFO,0x2); } wreg(rEP2INBC,64); // wreg( rEP1OUTBC,64);
First i would like to say sorry because of some miscommunication and some bad posting. Now whatever i have send is my code, some of them i have found from this forum and some from maxim. As well as i also need to change some to compatible with our compiler.
So Now i am faceing a problem for writing by the usb. For my project i need to use the hyperterminal com. for coummincation i am using Docklight Scripting software. the final position is now if i send any data by the docklight or windows hyperterminal, it shows me transfer data but does not show receiving data. If it is still confuse please inform me i will try to explain it more.
my problem is now i can read but cannot write
the final position is now if i send any data by the docklight or windows hyperterminal, it shows me transfer data but does not show receiving data.
The above statements are very confusing to me.
I don't know much about this, but normally, you should use an USB Analyzer to analyze what happens during the USB communication.
A. USB Host to USB device -> OK. USB device to USB Host -> Failed.
B. USB Host to USB device -> Failed. USB device to USB Host -> OK.
Your problem is A or B? How do you know/confirm that, it is OK/Failed?
Did you put a breakpoint at the beginning of the USB ISR to see what happens?