Enumeracia PIC
[pic18F] Send a stall packet - USB ennumerationHi everyone,My device is a pic18f4550 on an easypic 5. I would like to send a stall packet to the Host (Windows 7) because I have receive a setup token for "Device Qualifier Descriptor" So I have to respond with a request error (I think it is a stall packet... but I am not sure) Tha last setup transaction is received by the part of my code : /**********************/ /* SETUP Token DATA 0 */ /**********************/ BD0_OUT.CNT = 8; // size BD0_OUT.ADRH = 0x05; // adresse of Endpoint 0 descriptor BD0_OUT.ADRL = 0x28; BD0_OUT.STAT = UOWN | DTSEN; // flags while(!UIRbits.TRNIF){} // while transaction is not complete UIRbits.TRNIF = 0; // transaction complete pid = (BD0_OUT.STAT & 0x3C) >> 2; // is it a setup token ? if (pid!=SETUP_TOKEN)printError(38); To reply I use a similar structure : /*******************/ /* IN Token DATA 1 */ /*******************/ BD0_IN.CNT = 0x09; BD0_IN.ADRH = 0x05; //address BD0_IN.ADRL = 0x42; BD0_IN.STAT = UOWN | DTS | DTSEN;But I don't know how to send a stall packet to the host (or a request error)... Sorry, if it is not cleared... Thanks you :) 10 Replies Related Threads |
The short and sweet answer is that yes a request error means you send a stall in reply and to do this you set the BSTALL bit in BD0_IN.STAT for the STATUS stage reply.
BD0_IN.STAT = UOWN | DTS | DTSEN | BSTALL; On a different note, this is unlikely to be correct: BD0_IN.CNT = 0x09; Should be 0x0 for a STATUS stage reply and not more than 0x08 if you have defined the EP0 endpoint size as 8. However the last bit is just an assumption that you have set EP0 MAXPACKETSIZE to 8. If not disregard the last bit. |
Hi !
I always do it but it does not work :( unsigned char UOWN = 0x80; unsigned char DTS = 0x40; unsigned char DTSEN = 0x08; unsigned char BSTALL = 0x04; /**********************/ /* SETUP Token DATA 0 */ /**********************/ BD0_OUT.CNT = 8; BD0_OUT.ADRH = 0x05; BD0_OUT.ADRL = 0x28; BD0_OUT.STAT = UOWN | DTSEN; while(!UIRbits.TRNIF){} UIRbits.TRNIF = 0; pid = (BD0_OUT.STAT & 0x3C) >> 2; if (pid!=SETUP_TOKEN)printError(38); printDataSetup(9); // SETUP #9 (see screenshot) /**********************/ /* REPLY WITH STALL */ /**********************/ BD0_IN.CNT = 0x00; BD0_IN.STAT = UOWN | DTS | DTSEN | BSTALL; while(!UIRbits.TRNIF){} lcd_puts("I AM HERE");I never have "I AM HERE" on my LCD screen. So I'am blocked in the loop while(!UIRbits.TRNIF){} You can see my USB 2.0 ennumeration, I am blocked in the STEP #9 with the SETUP token : 80 06 00 06 00 00 0A 00 I have also set bMaxPacketSize of device descriptor to 0x40 (64 bytes). What is the problem ? I feel hopeless :( Thank you :) post edited by fdiedler - Sunday, October 28, 2012 10:31 PM
|
Honestly at this point I would have to advise you to grab one of the numerous USB stacks written for the PIC18 and copy the procedures.There is no shortages of them out there and examples written in C, assy, basic and Jal.
A USB stack has to be written to respond to the host in the way the host expects and not what "aught to be happening next." This means you have to have a RESET handler, chapter9 (Standard requests) handler, an IN handler and a OUT handler for EP0 at a very minimum. I cannot see these in your code. Doing things like this below, is not something I have ever seen on any working USB stack that I can recall and it is just not a workable way to implement USB. while(!UIRbits.TRNIF){} UIRbits.TRNIF = 0;You need to respond to the host and the host may at anytime decide to issue a bus reset or a new setup packet etc. One very likely reason why your code hangs is because the USB FIFO buffer is full. However it is not possible to tell for certain on the code you have posted. There just is not enough code there to get usb working in any sort of reliable way. |
I don't want to use the Microchip USB stack because I do not use C18 compiler but Hi-tech compiler and I want to learn about USB enumeration.
I have downloaded the entire Specification of USB 2.0, so I can create a "minimal" stack from scratch for Hi-tech compiler (if you know a code example of a stack for Pic18F and Hi-tech compiler, it would be nice :)) You can download all my code here : http://www.tutoworld.com/temp/usb_stack.zip This code works because Windows 7 pop-up for a new device :) (but does not find any driver, that is normal, I do not have created it). But I am blocked for sending a stall packet to the host, because I do not need to repond to 80 06 00 06 00 00 0A 00 SETUP token... After doing that, the host should sent a SET_CONFIGURATION token and it will be done ! ^^ Currently, the code performs these steps : 1) SETUP token 8006000100004000 => get device descriptor 2) SETUP token 0005020000000000 => set adresse (0x02 in my case) 3) Reset on the bus 4) SETUP token 8006000100001200 => get device descriptor again 5) SETUP token 800600020000FF00 => get configuration descriptor 6) SETUP token 8006000200001900 => get all config (endpoints, interfaces, configuration) 7) SETUP token 800600030000FF00 => get string descriptor 8) SETUP token 800602030904FF00 => get string descriptor with lang ID = English (0x0409) 9) SETUP token 8006000600000A00 => What is it ?? :( I think, I should respond a Stall request... Please help me, I am near to goal... Thanks a lot :) post edited by fdiedler - Monday, October 29, 2012 0:32 PM
|
So I'am blocked in the loop while(!UIRbits.TRNIF){}Yeah, STALLed transaction doesn't set TRNIF (Transfer completion interrupt), because just a successful transaction raises TRNIF. I believe your PIC has put STALL handshake to the IN transaction. And then, the host should put next SETUP, which also recovers error at EP0. But your firmware doesn't prepare BD0_OUT for this SETUP. The SETUP (and retries) is not ACKed by the PIC SIE. At this point, the enumeration goes out of the track. Before setting STALL to BD0_IN, arm BD0_OUT for the next SETUP. And then, your firmware may wait for the completion of the next SETUP with "while(!UIRbits.TRNIF){}" I am near to goal...If your goal would be enumeration just on your Windows version, maybe so. The enumeration sequence differs, depending on OS and its version. As newfound said, don't expect "what aught to come next". Every time when a bus event (like bus reset) or a request comes, process it as defined on the USB spec. Tsuneo |
Hi,
chinzeiAhh ok, but still does not work. The code always hangs in the infinite loop while(!UIRbits.TRNIF){} Here is my code : /**********************/ /* GET WEIRD REQUEST 80 06 00 06 ... /**********************/ /* SETUP Token DATA 0 */ /**********************/ BD0_OUT.CNT = 8; BD0_OUT.ADRH = 0x05; // adress of Setup Token BD0_OUT.ADRL = 0x28; BD0_OUT.STAT = UOWN | DTSEN; while(!UIRbits.TRNIF){} // <---- this loop is OK, I got the setup token :) UIRbits.TRNIF = 0; // transaction complete pid = (BD0_OUT.STAT & 0x3C) >> 2; if (pid!=SETUP_TOKEN)printError(38); printDataSetup(9); // SETUP #9 (see previous screenshot) /***********************/ /* ARM FROM NEXT SETUP */ /***********************/ BD0_OUT.CNT = 8; BD0_OUT.STAT = UOWN | DTSEN; // 0x88 /**********************/ /* REPLY WITH STALL */ /**********************/ BD0_IN.CNT = 0x00; BD0_IN.STAT = UOWN | DTS | DTSEN | BSTALL; // 0xCC while(!UIRbits.TRNIF){} // <---------- infinite loop here, the code hangs UIRbits.TRNIF = 0; lcd_puts("I AM HERE");Is there something wrong ? When UIRbits.STALLIF flag is raised ? chinzeiIf your goal would be enumeration just on your Windows version, maybe so.You are right, my goal is only to do an enumeration on my version of Windows, just to begin ;) chinzeiThe enumeration sequence differs, depending on OS and its version.Yeah, I just want to finish with my "awful" code just for test and then I will try to implement a process for all SETUP request according USB spec. Thanks (and sorry for my bad English) post edited by fdiedler - Monday, October 29, 2012 11:13 AM
|
When UIRbits.STALLIF flag is raised ?Didn't you get STALLIF? Ah, clear UCON.PKTDIS bit, too, before (or after) putting STALL to the IN endpoint. PKTDIS is set by the USB engine (SIE), when it has received a SETUP transaction. While PKTDIS is set to '1', all endpoints are NAKing, regardless of its Buffer Descriptor setting. Even BSTALL bit on the BD STAT is ignored. Firmware is expected to clear PKTDIS, to go ahead. For the next SETUP transaction, you've set up BD0_OUT.CNT and BD0_OUT.STAT, but leave BD0_OUT.ADRH/ADRL untouched. I remember, the SIE usually increments the BD address registers. Set the BD address registers, too. Tsuneo |
Unfortunatly, it still does not work...
I am sorry, I forgot to mention that I have already cleared the UCON.bits.PKTDIS bit in my previous post (I try before and after sending STALL packet, no results). That is weired because I got the STALL flag... UCONbits.PKTDIS = 0; /***********************/ /* ARM FROM NEXT SETUP */ /***********************/ BD0_OUT.CNT = 8; BD0_OUT.ADRH = 0x05; // adress of Setup Token BD0_OUT.ADRL = 0x28; BD0_OUT.STAT = UOWN | DTSEN; // 0x88 /**********************/ /* REPLY WITH STALL */ /**********************/ BD0_IN.CNT = 0x00; BD0_IN.STAT = UOWN | DTS | DTSEN | BSTALL; // 0xCC // wait for stall condition while(!UIRbits.STALLIF){} lcd_putch('*'); // <----- it is OK here // be ready for next setup transaction BD0_OUT.CNT = 8; BD0_OUT.ADRH = 0x05; // adress of Setup Token BD0_OUT.ADRL = 0x28; BD0_OUT.STAT = UOWN | DTSEN; UEP0bits.EPSTALL = 0; UIRbits.STALLIF = 0; while(!UIRbits.TRNIF){} // <------ hangs here... UIRbits.TRNIF = 0; lcd_puts("I AM HERE");I have seen another code on the Web : BD0_OUT.STAT = 0x80 | 0x04; BD0_IN.STAT = 0x80 | 0x04;He sets both EP0 (IN and OUT) with a STALL but still does not work. What is the matter ? :( Thanks |
Maybe, before this code block, your firmware has decoded Get_Descriptor( Device_Qualifier ) request.
UCONbits.PKTDIS = 0; /***********************/ /* ARM FROM NEXT SETUP */ /***********************/ BD0_OUT.CNT = 8; BD0_OUT.ADRH = 0x05; // adress of Setup Token BD0_OUT.ADRL = 0x28; BD0_OUT.STAT = UOWN | DTSEN; // 0x88 /**********************/ /* REPLY WITH STALL */ /**********************/ BD0_IN.CNT = 0x00; BD0_IN.STAT = UOWN | DTS | DTSEN | BSTALL; // 0xCC // wait for stall condition while(!UIRbits.STALLIF){} lcd_putch('*'); // <----- it is OK hereUp to this block, your code seems fine. But just after this block, your code arms BD0_OUT again. It doesn't need, as the BD0_OUT has been already armed by above code. I have suspicion that this extra process would even disturb the SIE to receive SETUP. Delete this code block, just after above block. // be ready for next setup transaction BD0_OUT.CNT = 8; BD0_OUT.ADRH = 0x05; // adress of Setup Token BD0_OUT.ADRL = 0x28; BD0_OUT.STAT = UOWN | DTSEN; Tsuneo |
Still not...
Maybe, before this code block, your firmware has decoded Get_Descriptor( Device_Qualifier ) request.No, it only get the SETUP Device_Qualifier request with : /**********************/ /* GET WEIRD REQUEST 80 06 00 06 ... /**********************/ /* SETUP Token DATA 0 */ /**********************/ BD0_OUT.CNT = 8; BD0_OUT.ADRH = 0x05; // adress of Setup Token BD0_OUT.ADRL = 0x28; BD0_OUT.STAT = UOWN | DTSEN; while(!UIRbits.TRNIF){} UIRbits.TRNIF = 0; // transaction complete pid = (BD0_OUT.STAT & 0x3C) >> 2; if (pid!=SETUP_TOKEN)printError(38); printDataSetup(9); // SETUP #9 (see screenshot) UCONbits.PKTDIS = 0; ...... ...... I try to answer to the Get_Descriptor( Device_Qualifier => 8006000600000A00) SETUP query with a dumb IN packet : But after that, I receive nothing from host... (no next SETUP transaction) post edited by fdiedler - Monday, October 29, 2012 6:55 PM
|