This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

USB-CDC

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

Parents
  • 
    // 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));
        }
    }
    

Reply
  • 
    // 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));
        }
    }
    

Children
  • // ********************************************************* //
    // ****************** 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?

  • 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?

  • 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?

  • 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?

  • Does anybody get the idea what is the problem??
    My communication between PC (host) to usb is ok but USB to PC (host) is not ok.
    For CDC shall i need to use the endpoint2 for Output?
    The last function "void USB_writeln2" use for writing. here i use Endpoint2, is it ok? i also check with other Endpoint but its remain same no improvement.

  • 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?

  • 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?


  • "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?"

    My problem is A. My "USB device to USB host is not ok".
    I have checked with USB analyzer and found USB Host to USB device is ok but the other direction is not ok!!
    I have also used some break point for debugging.
    can you tell me how can do the "bulk transfer". So far i understand there is a interrupt transfer and bulk transfer. i need to know about the bulk transfer.
    If it is still confuse i can write my testing procedure in details.

  • I don't know much about USB/USBCDC. And I am not familiar with your MCU and your USB solution (Library/Source Code).

    But I think/guess that, for most USBCDC device, the Data Flow for sending data from Device to Host (Bulk-In) is:

    1. Host polls Device regularly.
    2. The USB ISR of the device handles such a polling. (USB frame interrupt handler)
    3. The USB ISR of the device puts data into Bulk-In EP. (USB frame interrupt handler)
    4. When Bulk-In EP finishes the data sending, another interrupt triggered. (Interrupt driven data sending)
    5. The USB ISR of the device handles the next Bulk-In. (USB Bulk-In interrupt handler) It puts more data into Bulk-In EP. (Go to Step 4)

    With the USB Analyzer, did you see some regular IN-Packets? How did you respond to such a IN-Packet?

  • -> With the USB Analyzer, did you see some regular IN-Packets? How did you respond to such a IN-Packet? <-

    The above question is incorrect.

    It should be:

    With the USB Analyzer, did you see some regular IN-NAKs?

  • With the USB Analyzer, could you see your Endpoint Descriptor of the Bulk-In EP?