• AVR Freaks

Helpful Replysetup transaction not working

Author
__John
Starting Member
  • Total Posts : 66
  • Reward points : 0
  • Joined: 2012/04/10 01:44:12
  • Location: England
  • Status: offline
2012/06/27 01:32:52 (permalink)
0

setup transaction not working

PIC18F4553
HiTech C
 
I start the setup process, at first evertything goes ok.
The host requests the device descriptor and I send the first 8 bytes ok, then when I send the second chunk of 8 bytes it hangs waiting for TRNIF to get set. What am I doing wrong?
 
Here is my code, it gets as far as "// HANGS HERE!!".
 
typedef struct BDn {
    unsigned char STAT;
    unsigned char CNT;
    unsigned char ADRL;
    unsigned char ADRH;
} BDn_type;
struct BDn BD0_OUT @ 0x0400;
struct BDn BD0_IN  @ 0x0404;
struct BDn BD1_OUT @ 0x0408;
struct BDn BD1_IN  @ 0x040C;
 
typedef struct setupPkg {
    unsigned char bmRequestType;
    unsigned char bRequest;
    unsigned char wValueL;
    unsigned char wValueH;
    unsigned char wIndexL;
    unsigned char wIndexH;
    unsigned char wLengthL;
    unsigned char wLengthH;
} setupPkg_type;
struct setupPkg hostSetupPkg @ 0x0410;
/*********************/
/* Device Descriptor */
/*********************/
typedef struct deviceDescriptor {
    unsigned char  bLength;            //size of descriptor in bytes        
    unsigned char  bDescriptorType;    //device descriptor code
    unsigned short bcdUSB;             //USB 2.0
    unsigned char  bDeviceClass;       //class code
    unsigned char  bDeviceSubClass;    //sub-class code
    unsigned char  bDeviceProtocol;    //protocol code
    unsigned char  bMaxPacketSize;     //Max packet size
    unsigned short idVendor;           //Vendor ID (lsb)
    unsigned short idProduct;          //Product ID (lsb)
    unsigned short bcdDevice;          //release ID (lsb)
    unsigned char  iManufacturer;      //Vendor string descriptors
    unsigned char  iProduct;           //Product string descriptors
    unsigned char  iSerialNumber;      //Serial string descriptors
    unsigned char  bNumConfigurations; //num configurations
} deviceDescriptor_type;
struct deviceDescriptor devDescr @ 0x0418;
 
unsigned char UOWN  = 0x80;
unsigned char DTS   = 0x40;
unsigned char DTSEN = 0x08;
unsigned char OUT_TOKEN   = 0x01;
unsigned char IN_TOKEN    = 0x09;
unsigned char SETUP_TOKEN = 0x0D;
unsigned char descriptorType_device = 0x01;
unsigned char descriptorType_config = 0x02;
unsigned char descriptorType_string = 0x03;

void InitUSB()
{
    unsigned char pid;
    unsigned char descriptorType;
    unsigned char addrWillBe = 0;
 initDescriptors();
    UCON = 0;
    // PING-POING disabled
    UCFGbits.UPP = 0;
    // Eye-pattern test disabled
    UCFGbits.UTEYE = 0;
    // On-chip pull-up enabled
    UCFGbits.UPUEN = 1;
    UCFGbits.FSEN = 1; // 0 = Low speed device, 1 = High speed device
    // Enable USB
    UCONbits.USBEN = 1;
 UIE = 0;
    UIEbits.TRNIE = 1;
    UIR = 0;
    UEIE = 0;
    UEIR = 0;
    UADDR = 0x00;
    UEP0bits.EPOUTEN = 1;  //Enable OUT on ep0
    UEP0bits.EPINEN = 1;   //Enable IN on ep0
    UEP0bits.EPCONDIS = 0; //Allow SETUP transactions on ep0
    UEP0bits.EPHSHK = 1;   //Enable handshaking on ep0
    UEP1bits.EPOUTEN1 = 1;  //Enable OUT on ep1
    UEP1bits.EPINEN1 = 1;   //Enable IN on ep1
    // Enable SETUP packet transfers
    UCONbits.PKTDIS = 0;
    /**********************/
    /* SETUP Token DATA 0 */
    /**********************/
    BD0_OUT.CNT = 8;
    BD0_OUT.ADRH = HIBYTE(&hostSetupPkg);
    BD0_OUT.ADRL = LOBYTE(&hostSetupPkg);
    BD0_OUT.STAT = UOWN | DTSEN;
    while(!UIRbits.TRNIF){}
    UIRbits.TRNIF = 0;
    pid = (BD0_OUT.STAT & 0x3C) >> 2;
    if ( pid != SETUP_TOKEN )
 {
  Error("");
 }
    if ( hostSetupPkg.bmRequestType != 0x80 ) //Just to double check things are
 {
  Error("");
 }
    if ( hostSetupPkg.bRequest      != 0x06 ) //happening the way we expect.
 {
  Error("");
 }
    descriptorType = hostSetupPkg.wValueH;
    if ( descriptorType != descriptorType_device )
 {
  Error("");
 }
    UCONbits.PKTDIS = 0;
    UIRbits.TRNIF = 0;
   
      /*******************/
    /* IN Token DATA 1 */
    /*******************/
    BD0_IN.CNT  = 8;
    BD0_IN.ADRH = HIBYTE(&devDescr);
    BD0_IN.ADRL = LOBYTE(&devDescr);
    BD0_IN.STAT = UOWN | DTS | DTSEN;
    while(!UIRbits.TRNIF){}
    UIRbits.TRNIF = 0;
    pid = (BD0_IN.STAT & 0x3C) >> 2;
    if (pid != IN_TOKEN)
 {
  Error("");
 }
    /*******************/
    /* IN Token DATA 0 */
    /*******************/
 
    BD0_IN.CNT  = 8;
    BD0_IN.ADRH = HIBYTE((&devDescr)+8);
    BD0_IN.ADRL = LOBYTE((&devDescr)+8);
    BD0_IN.STAT = UOWN | DTSEN;
    while(!UIRbits.TRNIF){}   // HANGS HERE!!
    UIRbits.TRNIF = 0;
    pid = (BD0_IN.STAT & 0x3C) >> 2;
    if (pid != IN_TOKEN)
 {
  Error("");
 }
 // more code follows...
 
#1
bytencoder
Super Member
  • Total Posts : 363
  • Reward points : 0
  • Joined: 2009/06/25 12:30:07
  • Location: 0
  • Status: offline
Re:setup transaction not working 2012/06/27 05:28:17 (permalink) ☄ Helpful
0
1) Windows is a bit flawed/out-of-spec regarding the control transfer of the initial GET_DESCRIPTOR request; although it request a wLength of 64 (0x40) bytes, after the first IN transaction it does not start subsequent transactions to get the rest of the data (how it actually asked...), and terminates the transfer by a successful status stage (sends a ZLP OUT packet).
2) As a general rule, always re-arm EP0-OUT after a SETUP/OUT transaction ...
#2
__John
Starting Member
  • Total Posts : 66
  • Reward points : 0
  • Joined: 2012/04/10 01:44:12
  • Location: England
  • Status: offline
Re:setup transaction not working 2012/06/27 05:50:07 (permalink)
0
If windows is terminating the transfer after the first IN transaction, how do I send the device descriptor?
Do I need to set up an out trasaction to read the ZLP OUT packet?
 
Also, how do I re-arm EP0-OUT, do I need to set CNT, ADRL and ADRH ready for the next OUT transaction or somthing else?
 
Many thanks.
 
#3
bytencoder
Super Member
  • Total Posts : 363
  • Reward points : 0
  • Joined: 2009/06/25 12:30:07
  • Location: 0
  • Status: offline
Re:setup transaction not working 2012/06/27 06:26:55 (permalink)
0
__John
If windows is terminating the transfer after the first IN transaction, how do I send the device descriptor?

It will ask for it again after BUS-RESET and  SET_ADDRESS (this time Windows will play correctly)
 
__John
Do I need to set up an out trasaction to read the ZLP OUT packet?

Yes.
 
__John
Also, how do I re-arm EP0-OUT, do I need to set CNT, ADRL and ADRH ready for the next OUT transaction or somthing else?

Ofcourse, always arm with valid CNT, ADDR, as if there is a SETUP transaction you will get the data there !
#4
__John
Starting Member
  • Total Posts : 66
  • Reward points : 0
  • Joined: 2012/04/10 01:44:12
  • Location: England
  • Status: offline
Re:setup transaction not working 2012/06/27 06:55:08 (permalink)
0
Thanks bytencoder,
 
I can see now that I am getting a SET_ADDRESS from the host, it sort of makes sense,
as the first time you send the device descriptor is a bit of a wast of time because you send
it again when you have the address. It would be nice if MS would stick to known standards though.
 
 
#5
bytencoder
Super Member
  • Total Posts : 363
  • Reward points : 0
  • Joined: 2009/06/25 12:30:07
  • Location: 0
  • Status: offline
Re:setup transaction not working 2012/06/27 07:24:31 (permalink)
0
__John
..as the first time you send the device descriptor is a bit of a wast of time because you send
it again when you have the address. It would be nice if MS would stick to known standards though. ...

No, this is according to the specs. The first time the device descriptor is requested, an USB host is actually only interested to know the maximum packet size for endpoint 0, and this information is in the first 8 bytes at offset 7 (bMaxPacketSize0).
 
MS is not correct because it should have either set the wLength to 8 or queue IN transactions until it gets what it requested (64bytes) or a short-packet (more-likely for a standard Device desc)...
#6
__John
Starting Member
  • Total Posts : 66
  • Reward points : 0
  • Joined: 2012/04/10 01:44:12
  • Location: England
  • Status: offline
Re:setup transaction not working 2012/06/28 05:42:48 (permalink)
0
Thanks bytencoder.
post edited by __John - 2012/06/28 05:53:27
#7
__John
Starting Member
  • Total Posts : 66
  • Reward points : 0
  • Joined: 2012/04/10 01:44:12
  • Location: England
  • Status: offline
Re:setup transaction not working 2012/06/28 08:11:28 (permalink)
0
So, when I get a request for the device descriptor, how do I know whether to send all of the descriptor or just the first 8 bytes?
 
 
[edit]
 
I thik I have it. When it want the first 8 bytes it askes for 64 bytes.
When it want all of the descriptor it askes for the correct amount i.e. 18 bytes.
#8
Pacer
Super Member
  • Total Posts : 1171
  • Reward points : 0
  • Joined: 2004/12/01 09:29:20
  • Status: offline
Re:setup transaction not working 2012/06/29 05:10:37 (permalink)
0
As a device you do exactly what you are asked to do by the host.

After receiving a Get Device Descriptor SETUP, you wait for an IN, and send a packet with the lowest of:

- number of bytes requested and not sent so far
- max packet size, endpoint 0
- number of bytes in the descriptor not sent so far

If you receive another IN, you do the same but starting at the first unsent descriptor byte.

If on the other hand you receive a SETUP, or a bus reset, then the previous SETUP is now dealt with and can be forgotten.
#9
__John
Starting Member
  • Total Posts : 66
  • Reward points : 0
  • Joined: 2012/04/10 01:44:12
  • Location: England
  • Status: offline
Re:setup transaction not working 2012/06/29 08:01:49 (permalink)
0
Does anyone have example code for implementing USB on PIC18F4550?
Or is there a good book that includes such examples?
 
 
#10
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
Re:setup transaction not working 2012/06/29 13:24:22 (permalink)
0
You mean, apart from Microchip Application Code? (Libraries)

GENOVA :D :D ! GODO
#11
__John
Starting Member
  • Total Posts : 66
  • Reward points : 0
  • Joined: 2012/04/10 01:44:12
  • Location: England
  • Status: offline
Re:setup transaction not working 2012/07/02 00:59:36 (permalink)
0
Yes, I mean appart from library code. Examples dont need to be for PIC18F4550 but easly portable would be good.
#12
JorgeF
Super Member
  • Total Posts : 3340
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re:setup transaction not working 2012/07/02 03:23:03 (permalink)
0
Hi
 
You may find something interesting here http://embeddedadventures.blogspot.pt/
 
 
Best regards
Jorge
 
#13
Jump to:
© 2019 APG vNext Commercial Version 4.5