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
I have finished my program for USB-CDC with some problem. my problem is now i can read but cannot write. Is it like can communicate from Host to usb but cannot usb to host? Does anybody has any idea about this problem?
How do you expect anyone to make any comment on your program without seeing your program?
It is like saying, "My car doesn't work - what's wrong with it"
Remember: nobody knows anything about you, your project, or your code apart from what you provide in your posts!
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?