This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6745 USB0 FIFO0 TX does not work

Other Parts Discussed in Thread: TMS320C6745

Hi, all.

I am developing an original USB protocol stack which works as a device with my own TMS320C6745 board. Thank you for much information from this community, my code well handles interrupts and receives host requests such as GET_DESCRIPTOR and SET_ADDRESS by reading FIFO0.

However, my code seems to fail sending information back to a host with FIFO0. The procedure is based on 2.7.1.1.3 of sprufm9h, that is, loading data to FIFO0, setting TXPKTRDY bit, and finally setting DATAEND bit (if need) in the USB EP0 interrupt routine. Altough TXPKTRDY would be cleared automatically according to sprufm9h, with my codes TXPKTRDY is not cleared. As results, host issues RESET because of timeout and the enumeration fails like showing "Unknown device (VID=0x0000, PID=0x0000)".

Could you advise me? I am suspecting that not only the interrupt routine, but also the initialization are wrong.

The whole code is available from here, and the key interrupt routine is USB0_OTG::handle_ep0() in usb0.cpp. The summary of the code is:

 if(ep0_state == EP_TX){
  Uint16 control_reg(usbRegs->EPCSR[0].TXCSR.PERI_CSR0);
  if(control_reg & CSL_USB_OTG_PERI_CSR0_TXPKTRDY_MASK){return;}
  Uint16 sent(min(ep0_rw_size, 0x40));
  for(int i(0); i < sent / sizeof(Uint32); i++){
    usbRegs->FIFO0 = *(Uint32 *)ep0_rw_buf; // type of ep0_rw_buf is Uint8*
    ep0_rw_buf += sizeof(Uint32);
  }
  if(sent & sizeof(Uint16)){
    usbRegs->FIFO0 = *(Uint16 *)ep0_rw_buf;
    ep0_rw_buf += sizeof(Uint16);
  }
  if(sent & sizeof(Uint8)){
    usbRegs->FIFO0 = *ep0_rw_buf;
    ep0_rw_buf += sizeof(Uint8);
  }
  control_reg |= CSL_USB_OTG_PERI_CSR0_TXPKTRDY_MASK;
  if((ep0_rw_size -= sent) == 0){
    if(ep0_callback){(*ep0_callback)();} // Do something if callback
    control_reg |= CSL_USB_OTG_PERI_CSR0_DATAEND_MASK;
    ep0_state = EP_IDLE;
  }
  usbRegs->EPCSR[0].TXCSR.PERI_CSR0 = control_reg;
}

In addition, unfortunately, I cannot use TI's DSP/BIOS USB module, because my project requires whole source code is open.

Thanks

  • Hi,

    You probably want to set DataEnd and TxPktRdy together.

    Here is part of the code snipset I use:

     // Write32bit data
     while (bytes > 4) {
      switch (endpoint) {
       case 0: usbRegs->FIFO0 = *(buffer++); break; // Write 4-Bytes to EP0 TX FIFO & advance buffer pointer
       case 1: usbRegs->FIFO1 = *(buffer++); break; // Write 4-Bytes to EP1 TX FIFO & advance buffer pointer
       case 2: usbRegs->FIFO2 = *(buffer++); break; // Write 4-Bytes to EP2 TX FIFO & advance buffer pointer
       case 3: usbRegs->FIFO3 = *(buffer++); break; // Write 4-Bytes to EP3 TX FIFO & advance buffer pointer
       case 4: usbRegs->FIFO4 = *(buffer++); break; // Write 4-Bytes to EP4 TX FIFO & advance buffer pointer
      }
      bytes -= 4;      // Four less bytes to send
     }

     // Write remaining bytes
     buffer8 = (unsigned char *) buffer; // Pointer to 8-bit words
     while (bytes > 0) {
      switch (endpoint) {
       case 0: *((unsigned char*)(&usbRegs->FIFO0)) = *(buffer8++); break; // Write 4-Bytes to EP0 TX FIFO & advance buffer pointer
       case 1: *((unsigned char*)(&usbRegs->FIFO1)) = *(buffer8++); break; // Write 4-Bytes to EP1 TX FIFO & advance buffer pointer
       case 2: *((unsigned char*)(&usbRegs->FIFO2)) = *(buffer8++); break; // Write 4-Bytes to EP2 TX FIFO & advance buffer pointer
       case 3: *((unsigned char*)(&usbRegs->FIFO3)) = *(buffer8++); break; // Write 4-Bytes to EP3 TX FIFO & advance buffer pointer
       case 4: *((unsigned char*)(&usbRegs->FIFO4)) = *(buffer8++); break; // Write 4-Bytes to EP4 TX FIFO & advance buffer pointer
      }
      bytes -= 1;      // One less byte to send
     }


     if (endpoint == 0)
      usbRegs->TXCSR.PERI_CSR0 |= 0x000A; // DataEnd & TxPktRdy
     else
      //  For Endpoints 1 to 4, TxPktRdy is set.
      usbRegs->TXCSR.PERI_TXCSR |= 0x0001; // TxPktRdy.

    Best regards, Zegeye

  • Thank you for your kind reply, Zegeye. I tried again along with your code, that is, omitting (Uint16 *) section, but the situation has not been improved. I am further investigating my problem, and I think the case of this problem seems to be similar to http://e2e.ti.com/support/dsp/tms320c6000_high_performance_dsps/f/115/p/12190/47477.aspx#47477 .

    Thanks