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.

usb in omapl137

Other Parts Discussed in Thread: TMS320C6747

hello

i am using tms320c6747 from omapl137 evaluation board and i want to work usb in peripheral mode

i download ehci software from usb.org site and driver usb2 and i transfer command from this software

my first question is whether is there any solution for transfer command from host(computer) to board usb0?

and second question is that my code is below. i send command from host , but i receive data sometimes, sometimes there isn't interrupt for receive command from endpoint0

and third question, whenever i read data from fifo for different command i recieve on code 0x0012000001000680  (device descriptor)

and other question , is there any mistake in my program

thanx


#include <stdio.h>
#include <stdlib.h>
#include <c6x.h>
#include <ctype.h>

#include <ti/pspiom/cslr/cslr_syscfg_OMAPL137.h>
#include <ti/pspiom/cslr/soc_OMAPL137.h>
#include <ti/pspiom/cslr/cslr_psc_OMAPL137.h>
#include <ti/pspiom/cslr/cslr_usb_otg.h>
#include <ti/pspiom/cslr/csl_types.h>
#include <ti/pspiom/cslr/cslr_dspintc.h>

// Declare variables for enumeration
CSL_SyscfgRegsOvly BootCfg = (CSL_SyscfgRegsOvly)(CSL_SYSCFG_0_REGS);
CSL_Usb_otgRegsOvly usbRegs = (CSL_Usb_otgRegsOvly)CSL_USB_0_REGS;

void main()
{

Uint16 I;
Uint32 intrReg; // temp for masked interrupt status register
Uint8 usbIntStat; // USB interrupt status
Uint16 txIntStat; // Tx interrupt status
Uint16 rxIntStat; // Rx interrupt status

Uint32 intOtherCnt = 0; // Counter for Int
Uint32 ep0Intr = 0; // Connter for EP0
unsigned char deviceDesc[18] = {
0x12, // Length
0x01, // Descriptor Type
0x00, // bcdUSB
0x20, // USB2.0
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocal
0x40, // MaxPacketSize0
0x71, // idVendor
0x04,
0xf0, // idProduct
0xff,
0x00, // bcdDevice
0x01,
0x01, // iManufacturer
0x02, // iProduct
0x03, // iSerialNumber
0x01 // Only one configuration
};
unsigned char strDesc[4] = {0x12,0x03,0x04,0x05};
unsigned char cfgDesc[9] = {0x40,0x50,0x30,0x12,0x06,0x34,0x45,0x67,0x78};
int semAddrReq,quantity;
Uint16 Req;
Uint16 wValue;
Uint16 wIndex;
Uint16 wLen;
Uint32 csr;
Uint16 packet_size;
Uint16 count;
Uint32 *deviceDescPtr;
Uint16 Addr;
Uint32 *strDescPtr;
unsigned char input[256];
Uint32 *inPtr;
Uint32 *cfgDescPtr;
Uint32 input2;
int fifosize = 3;
// Define Descriptors for enumeration
#define FIFO_MAXP 8*(1<<fifosize);


// **************************************************************************
// Configure DRVVBUS Pin to be used for USB; Muxed with GPIO4[15]=Bank4 GP15
// PINMUX9[4]=1 and PINMUX9[7]=0
// **************************************************************************
// MAKE SURE WRITE ACCESS KEY IS INITIALIZED PRIOR TO ACCESSING ANY OF THE
// BootCfg REGISTERS.
BootCfg->KICK0R = 0x83e70b13; // Write Access Key 0
BootCfg->KICK1R = 0x95A4F1E0; // Write Access Key 1
BootCfg->PINMUX9 |= (0x1 << 4); // Set bit4 Pinmux9 for USB Use
BootCfg->PINMUX9&= 0xFFFFFF7F; // Clear bit 7 Pinmux9 for USB Use
// Reset the USB controller:
usbRegs->CTRLR |= 0x00000001;
// RESET: Hold PHY in Reset
BootCfg->CFGCHIP2 |= 0x00008000; // Hold PHY in Reset
// Drive Reset for few clock cycles
for (I=0; I < 50; I++);
// RESET: Release PHY from Reset
BootCfg->CFGCHIP2&= 0xFFFF7FFF; // Release PHY from Reset
/* Configure PHY with the Desired Operation */
// OTGMODE
BootCfg->CFGCHIP2&= 0xFFFF9FFF; // 00= > Do Not Override PHY Values Device Host operation
// PHYPWDN
BootCfg->CFGCHIP2&= 0xFFFFFBFF; // 1/0 = > PowerdDown/ NormalOperation 1 00 0000 0000
// OTGPWRDN
BootCfg->CFGCHIP2&= 0xFFFFFDFF; // 1/0 = > PowerDown/ NormalOperation 10 0000 0000
// DATAPOL
BootCfg->CFGCHIP2 |= 0x00000100; // 1/0 = > Normal/ Reversed
// SESNDEN
BootCfg->CFGCHIP2 |= 0x00000020; // 1/0 = > NormalOperation/ SessionEnd
// VBDTCTEN
BootCfg->CFGCHIP2 |= 0x00000010; // 1/0 = > VBUS Comparator Enable/ Disable
/* Configure PHY PLL use and Select Source */
// REF_FREQ[3:0]
BootCfg->CFGCHIP2 |= 0x00000002; // 0010b = > 24MHz Input Source
// USB2PHYCLKMUX: Select External Source
BootCfg->CFGCHIP2&= 0xFFFFF7FF; // 1/0 = > Internal/External(Pin)
// PHY_PLLON: On Simulation PHY PLL is OFF
BootCfg->CFGCHIP2 |= 0x00000040; // 1/0 = > On/ Off
/* Wait Until PHY Clock is Good */
while ((BootCfg->CFGCHIP2 & 0x00020000) == 0); // Wait Until PHY Clock is Good.
#ifndef HS_ENABLE
// Disable high-speed
CSL_FINS(usbRegs->POWER,USB_OTG_POWER_HSEN,0);
#else
// Enable high-speed
CSL_FINS(usbRegs->POWER,USB_OTG_POWER_HSEN,1);
#endif

// Enable Interrupts
// Enable interrupts in OTG block
usbRegs->CTRLR&= 0xFFFFFFF7; // Enable PDR2.0 Interrupt
usbRegs->INTRTXE = 0x1F; // Enable All Core Tx Endpoin Tx/Rx interrupt
usbRegs->INTRRXE = 0x1E; // Enable All Core Rx Endpoin
// Enable all interrupts in OTG block
usbRegs->INTMSKSETR = 0x01FF1E1F;
// Enable all USB interrupts in MUSBMHDRC
usbRegs->INTRUSBE = 0xFF;
// Enable SUSPENDM so that suspend can be seen UTMI signal
CSL_FINS(usbRegs->POWER,USB_OTG_POWER_ENSUSPM,1);
//Clear all pending interrupts
usbRegs->INTCLRR = usbRegs->INTSRCR;
// Set softconn bit
CSL_FINS(usbRegs->POWER,USB_OTG_POWER_SOFTCONN,1);
while ((usbRegs->DEVCTL & 0x01) == 0); //Stay here until controller goes in Session.

while(1) {
//Read the masked interrupt status register
intrReg = usbRegs->INTMASKEDR; // IFR for Unmasked Interrupt (8 Core Ints + 1 DRVVBUS, and 5 Tx and 4 Rx EP ints).

// If any interrupts
if ((intrReg) != 0)
{
//printf("Inrerrupt occured!!!\n");
intOtherCnt++;
//printf("The %dth Int\n",intOtherCnt);
usbIntStat = (Uint8)((intrReg)>>16); //USB interrupt status
txIntStat = (Uint16)((intrReg) & 0x1F); //Tx interrupt status
rxIntStat = (Uint16)((intrReg) & 0x1F00); //Rx interrupt status
rxIntStat = rxIntStat >> 8;

//Clear interrupts, but clear only the ones you saw
usbRegs->INTCLRR = intrReg;
} else txIntStat = 0; // No interrupt

// TX interrupt[0] is for both RX and TX ready on endpoint 0
if (txIntStat & 0x01) // EP0 Tx/Rx Interrupt
{
//printf("EPO Int !!!\n");
// Select endpoint 0 CSRs
usbRegs->INDEX = 0x00;
usbRegs->RXMAXP = FIFO_MAXP;
usbRegs->TXMAXP = FIFO_MAXP;
ep0Intr++;
// printf("The %dth EP0 Int\n",ep0Intr);

//Check the CSR0 register to see if Pkt is received
csr = usbRegs->TXCSR.PERI_CSR0;

//If Pkt is received
if(csr & 0x01) { // RxPktRdy
//Read the input packet. Expecting 8 byte SETUP packet.
packet_size = usbRegs->COUNT.COUNT0;
if (packet_size > 255) packet_size = 255; // Limit on packet size

// Initialize the input buffer pointer
inPtr = (Uint32 *)input;

// Special case for 8-byte packets - just to test various fifo reading methods
if (packet_size == 8) {
// Read two 32-bit words
*(inPtr++) = usbRegs->FIFO0; // First 4 bytes
*inPtr = usbRegs->FIFO0; // Second 4 bytes

} else {
// Loop through the input buffer reading one byte at a time
for (count = 0; count < packet_size; count++) input[count] = *((unsigned char*)(&usbRegs->FIFO0));
}
// Format of SETUP Data for DEVICE DESCRIPTOR (Host Requesting Device's DEVICE DESCRIPTOR)
// | bmRequestType | bRequest | wValue (Type/Index) | wIndex | wLength |
// | 1000_0000 | GET_DESCRIPTOR=6 | Device=1 / Index=0 | 0 | Data Stage Length |
// byte0/1 byte2 byte3 byte4 byte5/6 byte7/8
// | 0x80 | 0x06 | 0x00 0x01 | 0x0000 | 0x0012 |
// Expanding on bmRequestType[bit7=DataDir=1(DevToHost), bits[6:5]=00=Standard, bits[4:0]=Recipient=0=Device]
//Check the request type
//Get the control transaction details (Parse SETUP Packet)
Req = *(((Uint16 *)&input)+0); // bRequest | bmRequestType
wValue = *(((Uint16 *)&input)+1); // wValue(Index) | wValue(Device)
wIndex = *(((Uint16 *)&input)+2); // wIndex(Language or Zero) = Zero
wLen = *(((Uint16 *)&input)+3); // wLength

// DECODE Packet
//GET DESCRIPTOR Req (DEVICE, CONFIGURATION, and STRING DESCRIPTORS) from Host (CATC)
// Fill up the Tx FIFO with the right DESCRIPTOR Data and make it ready to send when receiving IN Packet.
if(Req == 0x0680) {
//Device Descriptor Request
// Indicate that packet has been serviced. This will clear the RxPktRdy field.
CSL_FINS(usbRegs->TXCSR.PERI_CSR0,USB_OTG_PERI_CSR0_SERV_RXPKTRDY,1);
CSL_FINS(usbRegs->TXCSR.PERI_CSR0,USB_OTG_PERI_CSR0_DATAEND,1);
CSL_FINS(usbRegs->TXCSR.PERI_CSR0,USB_OTG_PERI_CSR0_FLUSHFIFO,1);
if(wValue == 0x0100) {
deviceDescPtr = (Uint32 *)deviceDesc;
for (count=0; count < 4; count++)
{
usbRegs->FIFO0 = *(deviceDescPtr++);
}
// Push the last two bytes individually
*((unsigned char*)(&usbRegs->FIFO0)) = deviceDesc[16];
*((unsigned char*)(&usbRegs->FIFO0)) = deviceDesc[17];
}

//Configuration Descriptor Request
if(wValue == 0x0200) {
if(wLen == 0x0009) quantity = 2; else quantity = 8;
cfgDescPtr = (Uint32 *)cfgDesc;
for (count = 0; count < quantity; count++) usbRegs->FIFO0 = *(cfgDescPtr++);

// Push one more byte if wLen is 9
if(wLen == 0x0009) *((unsigned char*)(&usbRegs->FIFO0)) = cfgDesc[8];
}

//For String Desc
if(wValue == 0x0300) {
strDescPtr = (Uint32 *)strDesc[0];
usbRegs->FIFO0 = *strDescPtr;
}
if(wValue == 0x0301) {
strDescPtr = (Uint32 *)strDesc[1];
for (count=0;count<9;count++) usbRegs->FIFO0 = *(strDescPtr++);
}
if(wValue == 0x0302) {
strDescPtr = (Uint32 *)strDesc[2];
for (count=0; count<6; count++) usbRegs->FIFO0 = *(strDescPtr++);
}
if(wValue == 0x0303) {
strDescPtr = (Uint32 *)strDesc[3];
for (count=0; count<4; count++) usbRegs->FIFO0 = *(strDescPtr++);
}

// Set DataEnd and TxPktRdy
usbRegs->TXCSR.PERI_CSR0 = 0x0A;
}

// Format of SETUP Data for SET ADDRESS (Host Assigning Address to Device)
// | bmRequestType | bRequest | wValue | wIndex | wLength |
// | 0000_0000 | SET_ADDRESS=5 | Dev Address | Always 0 | NONE |
// byte0/1 byte2 byte3/4 byte5/6 byte7/8
// | 0x00 | 0x05 | 0x00XX 0x0000 | 0x0000 |
//SET ADDRESS Req
if(Req == 0x0500) {
Addr = *(((Uint16*)&input) + 1);
usbRegs->TXCSR.PERI_CSR0 = 0x48; // Serviced RxPktRdy & Set DataEnd
semAddrReq=1;
}

//Set Configuration Req
if(Req == 0x0900) {
usbRegs->TXCSR.PERI_CSR0 = 0x48; // Serviced RxPktRdy & Set DataEnd
}
else {
//This condition is for Status Stage interrupt.
//Ignore it for any other request other than SET ADDRESS
if((Req == 0x0500) && (semAddrReq == 1)) {
usbRegs->FADDR = Addr;
}
}
}
}
}
}

  • Hi saeideh,

    Is there any restriction in running Linux on ARM core? If no, you can easily enable the Linux USB driver ( gadget ) feature while configuring the kernel for OMAPL137 and test it by connecting to a linux host machine and use the following linux command to get the Device/configuration/Interface and endpoint descriptor details.

    ( By using this command, you can compare the data you received through your own software and evaluate. A sample output is given below for your reference.)

    > lsusb -v 

    Device Descriptor:

      bLength                18

      bDescriptorType         1

      bcdUSB               2.00

      bDeviceClass            0 (Defined at Interface level)

      bDeviceSubClass         0

      bDeviceProtocol         0

      bMaxPacketSize0        64

      idVendor           0x1cbe Luminary Micro Inc.

      idProduct          0x0005

      bcdDevice            1.00

      iManufacturer           1 Texas Instruments

      iProduct                2 Mass Storage Device

      iSerial                 3 12345678

      bNumConfigurations      1

      Configuration Descriptor:

        bLength                 9

        bDescriptorType         2

        wTotalLength           32

        bNumInterfaces          1

        bConfigurationValue     1

        iConfiguration          0

        bmAttributes         0xc0

          Self Powered

        MaxPower              500mA

        Interface Descriptor:

          bLength                 9

          bDescriptorType         4

          bInterfaceNumber        0

          bAlternateSetting       0

          bNumEndpoints           2

          bInterfaceClass         8 Mass Storage

          bInterfaceSubClass      6 SCSI

          bInterfaceProtocol     80 Bulk-Only

          iInterface              0

          Endpoint Descriptor:

            bLength                 7

            bDescriptorType         5

            bEndpointAddress     0x81  EP 1 IN

            bmAttributes            2

              Transfer Type            Bulk

              Synch Type               None

              Usage Type               Data

            wMaxPacketSize     0x0200  1x 512 bytes

            bInterval               0

          Endpoint Descriptor:

            bLength                 7

            bDescriptorType         5

            bEndpointAddress     0x01  EP 1 OUT

            bmAttributes            2

              Transfer Type            Bulk

              Synch Type               None

              Usage Type               Data

            wMaxPacketSize     0x0200  1x 512 bytes

            bInterval               0

    Device Status:     0x0001

      Self Powered

     

    Regards,

    Shankari

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.
    --------------------------------------------------------------------------------------------------------

  • dear Shankari

    i don't access to linux.

    is there any way or problem for received interrupt or maybe for driver?