/* Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com */
/* USB functions */

#include "Usb.h"

static byte usb_error = 0;
static byte usb_task_state;
DEV_RECORD devtable[ USB_NUMDEVICES + 1 ];
EP_RECORD dev0ep;           //Endpoint data structure used during enumeration for uninitialized device


/* constructor */

USB::USB () {
    usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;  //set up state machine
    init(); 
}
/* Initialize data structures */
void USB::init()
{
  byte i;
    for( i = 0; i < ( USB_NUMDEVICES + 1 ); i++ ) {
        devtable[ i ].epinfo = NULL;       //clear device table
        devtable[ i ].devclass = 0;
    }
    devtable[ 0 ].epinfo = &dev0ep; //set single ep for uninitialized device  
    // not necessary dev0ep.MaxPktSize = 8;          //minimum possible                        	
    dev0ep.sndToggle = bmSNDTOG0;   //set DATA0/1 toggles to 0
    dev0ep.rcvToggle = bmRCVTOG0;
}
byte USB::getUsbTaskState( void )
{
    return( usb_task_state );
}
void USB::setUsbTaskState( byte state )
{
    usb_task_state = state;
}     
EP_RECORD* USB::getDevTableEntry( byte addr, byte ep )
{
  EP_RECORD* ptr;
    ptr = devtable[ addr ].epinfo;
    ptr += ep;
    return( ptr );
}
/* set device table entry */
/* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */
void USB::setDevTableEntry( byte addr, EP_RECORD* eprecord_ptr )
{
    devtable[ addr ].epinfo = eprecord_ptr;
    //return();
}
/* Control transfer. Sets address, endpoint, fills control packet with necessary data, dispatches control packet, and initiates bulk IN transfer,   */
/* depending on request. Actual requests are defined as inlines                                                                                      */
/* return codes:                */
/* 00       =   success         */
/* 01-0f    =   non-zero HRSLT  */
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 )
{
 boolean direction = false;     //request direction, IN or OUT
 byte rcode;   
 SETUP_PKT setup_pkt;

  regWr( rPERADDR, addr );                    //set peripheral address
  if( bmReqType & 0x80 ) {
    direction = true;                       //determine request direction
  }
    /* fill in setup packet */
    setup_pkt.ReqType_u.bmRequestType = bmReqType;
    setup_pkt.bRequest = bRequest;
    setup_pkt.wVal_u.wValueLo = wValLo;
    setup_pkt.wVal_u.wValueHi = wValHi;
    setup_pkt.wIndex = wInd;
    setup_pkt.wLength = nbytes;
    bytesWr( rSUDFIFO, 8, ( char *)&setup_pkt );    //transfer to setup packet FIFO
    rcode = dispatchPkt( tokSETUP, ep, nak_limit );            //dispatch packet
    //Serial.println("Setup packet");   //DEBUG
    if( rcode ) {                                   //return HRSLT if not zero
        Serial.print("Setup packet error: ");
        Serial.print( rcode, HEX );                                          
        return( rcode );
    }
    //Serial.println( direction, HEX ); 
    if( dataptr != NULL ) {                         //data stage, if present
        rcode = ctrlData( addr, ep, nbytes, dataptr, direction );
    }
    if( rcode ) {   //return error
        Serial.print("Data packet error: ");
        Serial.print( rcode, HEX );                                          
        return( rcode );
    }
    rcode = ctrlStatus( ep, direction );                //status stage
    return( rcode );
}
/* Control transfer with status stage and no data stage */
/* Assumed peripheral address is already set */
byte USB::ctrlStatus( byte ep, boolean direction, unsigned int nak_limit )
{
  byte rcode;
    if( direction ) { //GET
        rcode = dispatchPkt( tokOUTHS, ep, nak_limit );
    }
    else {
        rcode = dispatchPkt( tokINHS, ep, nak_limit );
    }
    return( rcode );
}
/* Control transfer with data stage. Stages 2 and 3 of control transfer. Assumes preipheral address is set and setup packet has been sent */
byte USB::ctrlData( byte addr, byte ep, unsigned int nbytes, char* dataptr, boolean direction, unsigned int nak_limit )
{
 byte rcode;
  if( direction ) {                      //IN transfer
    devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1;
    rcode = inTransfer( addr, ep, nbytes, dataptr, nak_limit );
    return( rcode );
  }
  else {              //OUT transfer
    devtable[ addr ].epinfo[ ep ].sndToggle = bmSNDTOG1;
    rcode = outTransfer( addr, ep, nbytes, dataptr, nak_limit );
    return( rcode );
  }    
}
/* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
/* Keep sending INs and writes data to memory area pointed by 'data'                                                           */
/* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error,
            fe USB xfer timeout */
byte USB::inTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit )
{
 byte rcode;
 byte pktsize;
 byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize; 
 unsigned int xfrlen = 0;
    regWr( rHCTL, devtable[ addr ].epinfo[ ep ].rcvToggle );    //set toggle value
    while( 1 ) { // use a 'return' to exit this loop
        rcode = dispatchPkt( tokIN, ep, nak_limit );           //IN packet to EP-'endpoint'. Function takes care of NAKS.
        if( rcode ) {
            return( rcode );                            //should be 0, indicating ACK. Else return error code.
        }
        /* check for RCVDAVIRQ and generate error if not present */ 
        /* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
        if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) {
            return ( 0xf0 );                            //receive error
        }
        pktsize = regRd( rRCVBC );                      //number of received bytes
        data = bytesRd( rRCVFIFO, pktsize, data );
        regWr( rHIRQ, bmRCVDAVIRQ );                    // Clear the IRQ & free the buffer
        xfrlen += pktsize;                              // add this packet's byte count to total transfer length
        /* The transfer is complete under two conditions:           */
        /* 1. The device sent a short packet (L.T. maxPacketSize)   */
        /* 2. 'nbytes' have been transferred.                       */
        if (( pktsize < maxpktsize ) || (xfrlen >= nbytes )) {      // have we transferred 'nbytes' bytes?
            if( regRd( rHRSL ) & bmRCVTOGRD ) {                     //save toggle value
                devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1;
            }
            else {
                devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG0;
            }
            return( 0 );
        }
  }//while( 1 )
}

int USB::newInTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit )
{
 byte rcode;
 byte pktsize;
 byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize; 
 unsigned int xfrlen = 0;
    regWr( rHCTL, devtable[ addr ].epinfo[ ep ].rcvToggle );    //set toggle value
    while( 1 ) { // use a 'return' to exit this loop
        rcode = dispatchPkt( tokIN, ep, nak_limit );           //IN packet to EP-'endpoint'. Function takes care of NAKS.
        if( rcode ) {
		return -1;                            //should be 0, indicating ACK. Else return error code.
        }
        /* check for RCVDAVIRQ and generate error if not present */ 
        /* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
        if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) {
            return -1;                            //receive error
        }
        pktsize = regRd( rRCVBC );                      //number of received bytes
        data = bytesRd( rRCVFIFO, pktsize, data );
        regWr( rHIRQ, bmRCVDAVIRQ );                    // Clear the IRQ & free the buffer
        xfrlen += pktsize;                              // add this packet's byte count to total transfer length
        /* The transfer is complete under two conditions:           */
        /* 1. The device sent a short packet (L.T. maxPacketSize)   */
        /* 2. 'nbytes' have been transferred.                       */
        if (( pktsize < maxpktsize ) || (xfrlen >= nbytes )) {      // have we transferred 'nbytes' bytes?
            if( regRd( rHRSL ) & bmRCVTOGRD ) {                     //save toggle value
                devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1;
            }
            else {
                devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG0;
            }
            return xfrlen;
        }
  }//while( 1 )
}

/* OUT transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
/* Handles NAK bug per Maxim Application Note 4000 for single buffer transfer   */
/* rcode 0 if no errors. rcode 01-0f is relayed from HRSL                       */
/* major part of this function borrowed from code shared by Richard Ibbotson    */
byte USB::outTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit )
{
 byte rcode, retry_count;
 char* data_p = data;   //local copy of the data pointer
 unsigned int bytes_tosend, nak_count;
 unsigned int bytes_left = nbytes;
 byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize; 
 unsigned long timeout = millis() + USB_XFER_TIMEOUT;
 
  if (!maxpktsize) { //todo: move this check close to epinfo init. Make it 1< pktsize <64
    return 0xFE;
  }
 
  regWr( rHCTL, devtable[ addr ].epinfo[ ep ].sndToggle );    //set toggle value
  while( bytes_left ) {
    retry_count = 0;
    nak_count = 0;
    bytes_tosend = ( bytes_left >= maxpktsize ) ? maxpktsize : bytes_left;
    bytesWr( rSNDFIFO, bytes_tosend, data_p );      //filling output FIFO
    regWr( rSNDBC, bytes_tosend );                  //set number of bytes    
    regWr( rHXFR, ( tokOUT | ep ));                 //dispatch packet
    while(!(regRd( rHIRQ ) & bmHXFRDNIRQ ));        //wait for the completion IRQ
    regWr( rHIRQ, bmHXFRDNIRQ );                    //clear IRQ
    rcode = ( regRd( rHRSL ) & 0x0f );
    while( rcode && ( timeout > millis())) {
      switch( rcode ) {
        case hrNAK:
          nak_count++;
          if( nak_limit && ( nak_count == USB_NAK_LIMIT )) {
            return( rcode);                                   //return NAK
          }
          break;
        case hrTIMEOUT:
          retry_count++;
          if( retry_count == USB_RETRY_LIMIT ) {
            return( rcode );    //return TIMEOUT
          }
          break;
        default:  
          return( rcode );
      }//switch( rcode...
      /* process NAK according to Host out NAK bug */
      regWr( rSNDBC, 0 );
      regWr( rSNDFIFO, *data_p );
      regWr( rSNDBC, bytes_tosend );
      regWr( rHXFR, ( tokOUT | ep ));                 //dispatch packet
      while(!(regRd( rHIRQ ) & bmHXFRDNIRQ ));        //wait for the completion IRQ
      regWr( rHIRQ, bmHXFRDNIRQ );                    //clear IRQ
      rcode = ( regRd( rHRSL ) & 0x0f );
    }//while( rcode && ....
    bytes_left -= bytes_tosend;
    data_p += bytes_tosend;
  }//while( bytes_left...
  devtable[ addr ].epinfo[ ep ].sndToggle = ( regRd( rHRSL ) & bmSNDTOGRD ) ? bmSNDTOG1 : bmSNDTOG0;  //update toggle
  return( rcode );    //should be 0 in all cases
}
/* dispatch usb packet. Assumes peripheral address is set and relevant buffer is loaded/empty       */
/* If NAK, tries to re-send up to nak_limit times                                                   */
/* If nak_limit == 0, do not count NAKs, exit after timeout                                         */
/* If bus timeout, re-sends up to USB_RETRY_LIMIT times                                             */
/* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout                       */
byte USB::dispatchPkt( byte token, byte ep, unsigned int nak_limit )
{
 unsigned long timeout = millis() + USB_XFER_TIMEOUT;
 byte tmpdata;   
 byte rcode;
 unsigned int nak_count = 0;
 char retry_count = 0;

  while( timeout > millis() ) {
    regWr( rHXFR, ( token|ep ));            //launch the transfer
    rcode = 0xff;   
    while( millis() < timeout ) {           //wait for transfer completion
      tmpdata = regRd( rHIRQ );
      if( tmpdata & bmHXFRDNIRQ ) {
        regWr( rHIRQ, bmHXFRDNIRQ );    //clear the interrupt
        rcode = 0x00;
        break;
      }//if( tmpdata & bmHXFRDNIRQ
    }//while ( millis() < timeout
    if( rcode != 0x00 ) {                //exit if timeout
      return( rcode );
    }
    rcode = ( regRd( rHRSL ) & 0x0f );  //analyze transfer result
    switch( rcode ) {
      case hrNAK:
        nak_count ++;
        if( nak_limit && ( nak_count == nak_limit )) {
          return( rcode );
        }
        break;
      case hrTIMEOUT:
        retry_count ++;
        if( retry_count == USB_RETRY_LIMIT ) {
          return( rcode );
        }
        break;
      default:
        return( rcode );
    }//switch( rcode
  }//while( timeout > millis() 
  return( rcode );
}
/* USB main task. Performs enumeration/cleanup */
void USB::Task( void )      //USB state machine
{
  byte i;   
  byte rcode;
  static byte tmpaddr; 
  byte tmpdata;
  static unsigned long delay = 0;
  USB_DEVICE_DESCRIPTOR buf;
    tmpdata = getVbusState();
    /* modify USB task state if Vbus changed */

    switch( tmpdata ) {
        case SE1:   //illegal state
            usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
            break;
        case SE0:   //disconnected
            if(( usb_task_state & USB_STATE_MASK ) != USB_STATE_DETACHED ) {
                usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
            }
            break;
        case FSHOST:    //attached
        case LSHOST:
            if(( usb_task_state & USB_STATE_MASK ) == USB_STATE_DETACHED ) {
                delay = millis() + USB_SETTLE_DELAY;
                usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
            }
            break;
        }// switch( tmpdata
    //Serial.print("USB task state: ");
    //Serial.println( usb_task_state, HEX );
    switch( usb_task_state ) {
        case USB_DETACHED_SUBSTATE_INITIALIZE:
            init();
            usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
            break;
        case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE:     //just sit here
            break;
        case USB_DETACHED_SUBSTATE_ILLEGAL:             //just sit here
            break;
        case USB_ATTACHED_SUBSTATE_SETTLE:              //setlle time for just attached device                  
            if( delay < millis() ) {
                usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
            }
            break;
        case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
            regWr( rHCTL, bmBUSRST );                   //issue bus reset
            usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
            break;
        case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
            if(( regRd( rHCTL ) & bmBUSRST ) == 0 ) {
                tmpdata = regRd( rMODE ) | bmSOFKAENAB;                 //start SOF generation
                regWr( rMODE, tmpdata );
//                  regWr( rMODE, bmSOFKAENAB );
                usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
                delay = millis() + 20; //20ms wait after reset per USB spec
            }
            break;
        case USB_ATTACHED_SUBSTATE_WAIT_SOF:  //todo: change check order
            if( regRd( rHIRQ ) & bmFRAMEIRQ ) {                         //when first SOF received we can continue
              if( delay < millis() ) {                                    //20ms passed
                usb_task_state = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE;
              }
            }
            break;
        case USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE:
            // toggle( BPNT_0 );
            devtable[ 0 ].epinfo->MaxPktSize = 8;   //set max.packet size to min.allowed
            rcode = getDevDescr( 0, 0, 8, ( char* )&buf );
            if( rcode == 0 ) {
                devtable[ 0 ].epinfo->MaxPktSize = buf.bMaxPacketSize0;
                usb_task_state = USB_STATE_ADDRESSING;
            }
            else {
                usb_error = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE;
                usb_task_state = USB_STATE_ERROR;
            }
            break;
        case USB_STATE_ADDRESSING:
            for( i = 1; i < USB_NUMDEVICES; i++ ) {
                if( devtable[ i ].epinfo == NULL ) {
                    devtable[ i ].epinfo = devtable[ 0 ].epinfo;        //set correct MaxPktSize
                                                                        //temporary record
                                                                        //until plugged with real device endpoint structure
                    rcode = setAddr( 0, 0, i );
                    if( rcode == 0 ) {
                        tmpaddr = i;
                        usb_task_state = USB_STATE_CONFIGURING;
                    }
                    else {
                        usb_error = USB_STATE_ADDRESSING;          //set address error
                        usb_task_state = USB_STATE_ERROR;
                    }
                    break;  //break if address assigned or error occured during address assignment attempt                      
                }
            }//for( i = 1; i < USB_NUMDEVICES; i++
            if( usb_task_state == USB_STATE_ADDRESSING ) {     //no vacant place in devtable
                usb_error = 0xfe;
                usb_task_state = USB_STATE_ERROR;
            }
            break;
        case USB_STATE_CONFIGURING:
            break;
        case USB_STATE_RUNNING:
            break;
        case USB_STATE_ERROR:
            break;
    }// switch( usb_task_state
}    
  