Home | History | Annotate | Download | only in USB_Host_Shield
      1 /*
      2  * Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com
      3  * MAX3421E USB host controller support
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. Neither the name of the authors nor the names of its contributors
     14  *    may be used to endorse or promote products derived from this software
     15  *    without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 /* USB functions */
     31 
     32 #include "Usb.h"
     33 
     34 static byte usb_error = 0;
     35 static byte usb_task_state;
     36 DEV_RECORD devtable[ USB_NUMDEVICES + 1 ];
     37 EP_RECORD dev0ep;           //Endpoint data structure used during enumeration for uninitialized device
     38 
     39 
     40 /* constructor */
     41 
     42 USB::USB () {
     43     usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;  //set up state machine
     44     init();
     45 }
     46 /* Initialize data structures */
     47 void USB::init()
     48 {
     49   byte i;
     50     for( i = 0; i < ( USB_NUMDEVICES + 1 ); i++ ) {
     51         devtable[ i ].epinfo = NULL;       //clear device table
     52         devtable[ i ].devclass = 0;
     53     }
     54     devtable[ 0 ].epinfo = &dev0ep; //set single ep for uninitialized device
     55     // not necessary dev0ep.MaxPktSize = 8;          //minimum possible
     56     dev0ep.sndToggle = bmSNDTOG0;   //set DATA0/1 toggles to 0
     57     dev0ep.rcvToggle = bmRCVTOG0;
     58 }
     59 byte USB::getUsbTaskState( void )
     60 {
     61     return( usb_task_state );
     62 }
     63 void USB::setUsbTaskState( byte state )
     64 {
     65     usb_task_state = state;
     66 }
     67 EP_RECORD* USB::getDevTableEntry( byte addr, byte ep )
     68 {
     69   EP_RECORD* ptr;
     70     ptr = devtable[ addr ].epinfo;
     71     ptr += ep;
     72     return( ptr );
     73 }
     74 /* set device table entry */
     75 /* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */
     76 void USB::setDevTableEntry( byte addr, EP_RECORD* eprecord_ptr )
     77 {
     78     devtable[ addr ].epinfo = eprecord_ptr;
     79     //return();
     80 }
     81 /* Control transfer. Sets address, endpoint, fills control packet with necessary data, dispatches control packet, and initiates bulk IN transfer,   */
     82 /* depending on request. Actual requests are defined as inlines                                                                                      */
     83 /* return codes:                */
     84 /* 00       =   success         */
     85 /* 01-0f    =   non-zero HRSLT  */
     86 byte USB::ctrlReq( byte addr, byte ep, byte bmReqType, byte bRequest, byte wValLo, byte wValHi, unsigned int wInd, unsigned int nbytes, char* dataptr, unsigned int nak_limit )
     87 {
     88  boolean direction = false;     //request direction, IN or OUT
     89  byte rcode;
     90  SETUP_PKT setup_pkt;
     91 
     92   regWr( rPERADDR, addr );                    //set peripheral address
     93   if( bmReqType & 0x80 ) {
     94     direction = true;                       //determine request direction
     95   }
     96     /* fill in setup packet */
     97     setup_pkt.ReqType_u.bmRequestType = bmReqType;
     98     setup_pkt.bRequest = bRequest;
     99     setup_pkt.wVal_u.wValueLo = wValLo;
    100     setup_pkt.wVal_u.wValueHi = wValHi;
    101     setup_pkt.wIndex = wInd;
    102     setup_pkt.wLength = nbytes;
    103     bytesWr( rSUDFIFO, 8, ( char *)&setup_pkt );    //transfer to setup packet FIFO
    104     rcode = dispatchPkt( tokSETUP, ep, nak_limit );            //dispatch packet
    105     //Serial.println("Setup packet");   //DEBUG
    106     if( rcode ) {                                   //return HRSLT if not zero
    107         Serial.print("Setup packet error: ");
    108         Serial.print( rcode, HEX );
    109         return( rcode );
    110     }
    111     //Serial.println( direction, HEX );
    112     if( dataptr != NULL ) {                         //data stage, if present
    113         rcode = ctrlData( addr, ep, nbytes, dataptr, direction );
    114     }
    115     if( rcode ) {   //return error
    116         Serial.print("Data packet error: ");
    117         Serial.print( rcode, HEX );
    118         return( rcode );
    119     }
    120     rcode = ctrlStatus( ep, direction );                //status stage
    121     return( rcode );
    122 }
    123 /* Control transfer with status stage and no data stage */
    124 /* Assumed peripheral address is already set */
    125 byte USB::ctrlStatus( byte ep, boolean direction, unsigned int nak_limit )
    126 {
    127   byte rcode;
    128     if( direction ) { //GET
    129         rcode = dispatchPkt( tokOUTHS, ep, nak_limit );
    130     }
    131     else {
    132         rcode = dispatchPkt( tokINHS, ep, nak_limit );
    133     }
    134     return( rcode );
    135 }
    136 /* Control transfer with data stage. Stages 2 and 3 of control transfer. Assumes preipheral address is set and setup packet has been sent */
    137 byte USB::ctrlData( byte addr, byte ep, unsigned int nbytes, char* dataptr, boolean direction, unsigned int nak_limit )
    138 {
    139  byte rcode;
    140   if( direction ) {                      //IN transfer
    141     devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1;
    142     rcode = inTransfer( addr, ep, nbytes, dataptr, nak_limit );
    143     return( rcode );
    144   }
    145   else {              //OUT transfer
    146     devtable[ addr ].epinfo[ ep ].sndToggle = bmSNDTOG1;
    147     rcode = outTransfer( addr, ep, nbytes, dataptr, nak_limit );
    148     return( rcode );
    149   }
    150 }
    151 /* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
    152 /* Keep sending INs and writes data to memory area pointed by 'data'                                                           */
    153 /* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error,
    154             fe USB xfer timeout */
    155 byte USB::inTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit )
    156 {
    157  byte rcode;
    158  byte pktsize;
    159  byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize;
    160  unsigned int xfrlen = 0;
    161     regWr( rHCTL, devtable[ addr ].epinfo[ ep ].rcvToggle );    //set toggle value
    162     while( 1 ) { // use a 'return' to exit this loop
    163         rcode = dispatchPkt( tokIN, ep, nak_limit );           //IN packet to EP-'endpoint'. Function takes care of NAKS.
    164         if( rcode ) {
    165             return( rcode );                            //should be 0, indicating ACK. Else return error code.
    166         }
    167         /* check for RCVDAVIRQ and generate error if not present */
    168         /* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
    169         if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) {
    170             return ( 0xf0 );                            //receive error
    171         }
    172         pktsize = regRd( rRCVBC );                      //number of received bytes
    173         data = bytesRd( rRCVFIFO, pktsize, data );
    174         regWr( rHIRQ, bmRCVDAVIRQ );                    // Clear the IRQ & free the buffer
    175         xfrlen += pktsize;                              // add this packet's byte count to total transfer length
    176         /* The transfer is complete under two conditions:           */
    177         /* 1. The device sent a short packet (L.T. maxPacketSize)   */
    178         /* 2. 'nbytes' have been transferred.                       */
    179         if (( pktsize < maxpktsize ) || (xfrlen >= nbytes )) {      // have we transferred 'nbytes' bytes?
    180             if( regRd( rHRSL ) & bmRCVTOGRD ) {                     //save toggle value
    181                 devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1;
    182             }
    183             else {
    184                 devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG0;
    185             }
    186             return( 0 );
    187         }
    188   }//while( 1 )
    189 }
    190 
    191 int USB::newInTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit )
    192 {
    193  byte rcode;
    194  byte pktsize;
    195  byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize;
    196  unsigned int xfrlen = 0;
    197     regWr( rHCTL, devtable[ addr ].epinfo[ ep ].rcvToggle );    //set toggle value
    198     while( 1 ) { // use a 'return' to exit this loop
    199         rcode = dispatchPkt( tokIN, ep, nak_limit );           //IN packet to EP-'endpoint'. Function takes care of NAKS.
    200         if( rcode ) {
    201 		return -1;                            //should be 0, indicating ACK. Else return error code.
    202         }
    203         /* check for RCVDAVIRQ and generate error if not present */
    204         /* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
    205         if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) {
    206             return -1;                            //receive error
    207         }
    208         pktsize = regRd( rRCVBC );                      //number of received bytes
    209         data = bytesRd( rRCVFIFO, pktsize, data );
    210         regWr( rHIRQ, bmRCVDAVIRQ );                    // Clear the IRQ & free the buffer
    211         xfrlen += pktsize;                              // add this packet's byte count to total transfer length
    212         /* The transfer is complete under two conditions:           */
    213         /* 1. The device sent a short packet (L.T. maxPacketSize)   */
    214         /* 2. 'nbytes' have been transferred.                       */
    215         if (( pktsize < maxpktsize ) || (xfrlen >= nbytes )) {      // have we transferred 'nbytes' bytes?
    216             if( regRd( rHRSL ) & bmRCVTOGRD ) {                     //save toggle value
    217                 devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1;
    218             }
    219             else {
    220                 devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG0;
    221             }
    222             return xfrlen;
    223         }
    224   }//while( 1 )
    225 }
    226 
    227 /* OUT transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
    228 /* Handles NAK bug per Maxim Application Note 4000 for single buffer transfer   */
    229 /* rcode 0 if no errors. rcode 01-0f is relayed from HRSL                       */
    230 /* major part of this function borrowed from code shared by Richard Ibbotson    */
    231 byte USB::outTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit )
    232 {
    233  byte rcode, retry_count;
    234  char* data_p = data;   //local copy of the data pointer
    235  unsigned int bytes_tosend, nak_count;
    236  unsigned int bytes_left = nbytes;
    237  byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize;
    238  unsigned long timeout = millis() + USB_XFER_TIMEOUT;
    239 
    240   if (!maxpktsize) { //todo: move this check close to epinfo init. Make it 1< pktsize <64
    241     return 0xFE;
    242   }
    243 
    244   regWr( rHCTL, devtable[ addr ].epinfo[ ep ].sndToggle );    //set toggle value
    245   while( bytes_left ) {
    246     retry_count = 0;
    247     nak_count = 0;
    248     bytes_tosend = ( bytes_left >= maxpktsize ) ? maxpktsize : bytes_left;
    249     bytesWr( rSNDFIFO, bytes_tosend, data_p );      //filling output FIFO
    250     regWr( rSNDBC, bytes_tosend );                  //set number of bytes
    251     regWr( rHXFR, ( tokOUT | ep ));                 //dispatch packet
    252     while(!(regRd( rHIRQ ) & bmHXFRDNIRQ ));        //wait for the completion IRQ
    253     regWr( rHIRQ, bmHXFRDNIRQ );                    //clear IRQ
    254     rcode = ( regRd( rHRSL ) & 0x0f );
    255     while( rcode && ( timeout > millis())) {
    256       switch( rcode ) {
    257         case hrNAK:
    258           nak_count++;
    259           if( nak_limit && ( nak_count == USB_NAK_LIMIT )) {
    260             return( rcode);                                   //return NAK
    261           }
    262           break;
    263         case hrTIMEOUT:
    264           retry_count++;
    265           if( retry_count == USB_RETRY_LIMIT ) {
    266             return( rcode );    //return TIMEOUT
    267           }
    268           break;
    269         default:
    270           return( rcode );
    271       }//switch( rcode...
    272       /* process NAK according to Host out NAK bug */
    273       regWr( rSNDBC, 0 );
    274       regWr( rSNDFIFO, *data_p );
    275       regWr( rSNDBC, bytes_tosend );
    276       regWr( rHXFR, ( tokOUT | ep ));                 //dispatch packet
    277       while(!(regRd( rHIRQ ) & bmHXFRDNIRQ ));        //wait for the completion IRQ
    278       regWr( rHIRQ, bmHXFRDNIRQ );                    //clear IRQ
    279       rcode = ( regRd( rHRSL ) & 0x0f );
    280     }//while( rcode && ....
    281     bytes_left -= bytes_tosend;
    282     data_p += bytes_tosend;
    283   }//while( bytes_left...
    284   devtable[ addr ].epinfo[ ep ].sndToggle = ( regRd( rHRSL ) & bmSNDTOGRD ) ? bmSNDTOG1 : bmSNDTOG0;  //update toggle
    285   return( rcode );    //should be 0 in all cases
    286 }
    287 /* dispatch usb packet. Assumes peripheral address is set and relevant buffer is loaded/empty       */
    288 /* If NAK, tries to re-send up to nak_limit times                                                   */
    289 /* If nak_limit == 0, do not count NAKs, exit after timeout                                         */
    290 /* If bus timeout, re-sends up to USB_RETRY_LIMIT times                                             */
    291 /* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout                       */
    292 byte USB::dispatchPkt( byte token, byte ep, unsigned int nak_limit )
    293 {
    294  unsigned long timeout = millis() + USB_XFER_TIMEOUT;
    295  byte tmpdata;
    296  byte rcode;
    297  unsigned int nak_count = 0;
    298  char retry_count = 0;
    299 
    300   while( timeout > millis() ) {
    301     regWr( rHXFR, ( token|ep ));            //launch the transfer
    302     rcode = 0xff;
    303     while( millis() < timeout ) {           //wait for transfer completion
    304       tmpdata = regRd( rHIRQ );
    305       if( tmpdata & bmHXFRDNIRQ ) {
    306         regWr( rHIRQ, bmHXFRDNIRQ );    //clear the interrupt
    307         rcode = 0x00;
    308         break;
    309       }//if( tmpdata & bmHXFRDNIRQ
    310     }//while ( millis() < timeout
    311     if( rcode != 0x00 ) {                //exit if timeout
    312       return( rcode );
    313     }
    314     rcode = ( regRd( rHRSL ) & 0x0f );  //analyze transfer result
    315     switch( rcode ) {
    316       case hrNAK:
    317         nak_count ++;
    318         if( nak_limit && ( nak_count == nak_limit )) {
    319           return( rcode );
    320         }
    321         break;
    322       case hrTIMEOUT:
    323         retry_count ++;
    324         if( retry_count == USB_RETRY_LIMIT ) {
    325           return( rcode );
    326         }
    327         break;
    328       default:
    329         return( rcode );
    330     }//switch( rcode
    331   }//while( timeout > millis()
    332   return( rcode );
    333 }
    334 /* USB main task. Performs enumeration/cleanup */
    335 void USB::Task( void )      //USB state machine
    336 {
    337   byte i;
    338   byte rcode;
    339   static byte tmpaddr;
    340   byte tmpdata;
    341   static unsigned long delay = 0;
    342   USB_DEVICE_DESCRIPTOR buf;
    343     tmpdata = getVbusState();
    344     /* modify USB task state if Vbus changed */
    345 
    346     switch( tmpdata ) {
    347         case SE1:   //illegal state
    348             usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
    349             break;
    350         case SE0:   //disconnected
    351             if(( usb_task_state & USB_STATE_MASK ) != USB_STATE_DETACHED ) {
    352                 usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
    353             }
    354             break;
    355         case FSHOST:    //attached
    356         case LSHOST:
    357             if(( usb_task_state & USB_STATE_MASK ) == USB_STATE_DETACHED ) {
    358                 delay = millis() + USB_SETTLE_DELAY;
    359                 usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
    360             }
    361             break;
    362         }// switch( tmpdata
    363     //Serial.print("USB task state: ");
    364     //Serial.println( usb_task_state, HEX );
    365     switch( usb_task_state ) {
    366         case USB_DETACHED_SUBSTATE_INITIALIZE:
    367             init();
    368             usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
    369             break;
    370         case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE:     //just sit here
    371             break;
    372         case USB_DETACHED_SUBSTATE_ILLEGAL:             //just sit here
    373             break;
    374         case USB_ATTACHED_SUBSTATE_SETTLE:              //setlle time for just attached device
    375             if( delay < millis() ) {
    376                 usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
    377             }
    378             break;
    379         case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
    380             regWr( rHCTL, bmBUSRST );                   //issue bus reset
    381             usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
    382             break;
    383         case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
    384             if(( regRd( rHCTL ) & bmBUSRST ) == 0 ) {
    385                 tmpdata = regRd( rMODE ) | bmSOFKAENAB;                 //start SOF generation
    386                 regWr( rMODE, tmpdata );
    387 //                  regWr( rMODE, bmSOFKAENAB );
    388                 usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
    389                 delay = millis() + 20; //20ms wait after reset per USB spec
    390             }
    391             break;
    392         case USB_ATTACHED_SUBSTATE_WAIT_SOF:  //todo: change check order
    393             if( regRd( rHIRQ ) & bmFRAMEIRQ ) {                         //when first SOF received we can continue
    394               if( delay < millis() ) {                                    //20ms passed
    395                 usb_task_state = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE;
    396               }
    397             }
    398             break;
    399         case USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE:
    400             // toggle( BPNT_0 );
    401             devtable[ 0 ].epinfo->MaxPktSize = 8;   //set max.packet size to min.allowed
    402             rcode = getDevDescr( 0, 0, 8, ( char* )&buf );
    403             if( rcode == 0 ) {
    404                 devtable[ 0 ].epinfo->MaxPktSize = buf.bMaxPacketSize0;
    405                 usb_task_state = USB_STATE_ADDRESSING;
    406             }
    407             else {
    408                 usb_error = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE;
    409                 usb_task_state = USB_STATE_ERROR;
    410             }
    411             break;
    412         case USB_STATE_ADDRESSING:
    413             for( i = 1; i < USB_NUMDEVICES; i++ ) {
    414                 if( devtable[ i ].epinfo == NULL ) {
    415                     devtable[ i ].epinfo = devtable[ 0 ].epinfo;        //set correct MaxPktSize
    416                                                                         //temporary record
    417                                                                         //until plugged with real device endpoint structure
    418                     rcode = setAddr( 0, 0, i );
    419                     if( rcode == 0 ) {
    420                         tmpaddr = i;
    421                         usb_task_state = USB_STATE_CONFIGURING;
    422                     }
    423                     else {
    424                         usb_error = USB_STATE_ADDRESSING;          //set address error
    425                         usb_task_state = USB_STATE_ERROR;
    426                     }
    427                     break;  //break if address assigned or error occured during address assignment attempt
    428                 }
    429             }//for( i = 1; i < USB_NUMDEVICES; i++
    430             if( usb_task_state == USB_STATE_ADDRESSING ) {     //no vacant place in devtable
    431                 usb_error = 0xfe;
    432                 usb_task_state = USB_STATE_ERROR;
    433             }
    434             break;
    435         case USB_STATE_CONFIGURING:
    436             break;
    437         case USB_STATE_RUNNING:
    438             break;
    439         case USB_STATE_ERROR:
    440             break;
    441     }// switch( usb_task_state
    442 }
    443 
    444