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 #ifndef _usb_h_ 32 #define _usb_h_ 33 34 #include <Max3421e.h> 35 #include "ch9.h" 36 37 /* Common setup data constant combinations */ 38 #define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //get descriptor request type 39 #define bmREQ_SET USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //set request type for all but 'set feature' and 'set interface' 40 #define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE //get interface request type 41 /* HID requests */ 42 #define bmREQ_HIDOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE 43 #define bmREQ_HIDIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE 44 #define bmREQ_HIDREPORT USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_INTERFACE 45 46 #define USB_XFER_TIMEOUT 5000 //USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec 47 #define USB_NAK_LIMIT 32000 //NAK limit for a transfer. o meand NAKs are not counted 48 #define USB_RETRY_LIMIT 3 //retry limit for a transfer 49 #define USB_SETTLE_DELAY 200 //settle delay in milliseconds 50 #define USB_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code 51 52 #define USB_NUMDEVICES 2 //number of USB devices 53 54 /* USB state machine states */ 55 56 #define USB_STATE_MASK 0xf0 57 58 #define USB_STATE_DETACHED 0x10 59 #define USB_DETACHED_SUBSTATE_INITIALIZE 0x11 60 #define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE 0x12 61 #define USB_DETACHED_SUBSTATE_ILLEGAL 0x13 62 #define USB_ATTACHED_SUBSTATE_SETTLE 0x20 63 #define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30 64 #define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40 65 #define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50 66 #define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60 67 #define USB_STATE_ADDRESSING 0x70 68 #define USB_STATE_CONFIGURING 0x80 69 #define USB_STATE_RUNNING 0x90 70 #define USB_STATE_ERROR 0xa0 71 72 // byte usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE 73 74 /* USB Setup Packet Structure */ 75 typedef struct { 76 union { // offset description 77 byte bmRequestType; // 0 Bit-map of request type 78 struct { 79 byte recipient: 5; // Recipient of the request 80 byte type: 2; // Type of request 81 byte direction: 1; // Direction of data X-fer 82 }; 83 }ReqType_u; 84 byte bRequest; // 1 Request 85 union { 86 unsigned int wValue; // 2 Depends on bRequest 87 struct { 88 byte wValueLo; 89 byte wValueHi; 90 }; 91 }wVal_u; 92 unsigned int wIndex; // 4 Depends on bRequest 93 unsigned int wLength; // 6 Depends on bRequest 94 } SETUP_PKT, *PSETUP_PKT; 95 96 /* Endpoint information structure */ 97 /* bToggle of endpoint 0 initialized to 0xff */ 98 /* during enumeration bToggle is set to 00 */ 99 typedef struct { 100 byte epAddr; //copy from endpoint descriptor. Bit 7 indicates direction ( ignored for control endpoints ) 101 byte Attr; // Endpoint transfer type. 102 unsigned int MaxPktSize; // Maximum packet size. 103 byte Interval; // Polling interval in frames. 104 byte sndToggle; //last toggle value, bitmask for HCTL toggle bits 105 byte rcvToggle; //last toggle value, bitmask for HCTL toggle bits 106 /* not sure if both are necessary */ 107 } EP_RECORD; 108 /* device record structure */ 109 typedef struct { 110 EP_RECORD* epinfo; //device endpoint information 111 byte devclass; //device class 112 } DEV_RECORD; 113 114 115 116 class USB : public MAX3421E { 117 //data structures 118 /* device table. Filled during enumeration */ 119 /* index corresponds to device address */ 120 /* each entry contains pointer to endpoint structure */ 121 /* and device class to use in various places */ 122 //DEV_RECORD devtable[ USB_NUMDEVICES + 1 ]; 123 //EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device 124 125 //byte usb_task_state; 126 127 public: 128 USB( void ); 129 byte getUsbTaskState( void ); 130 void setUsbTaskState( byte state ); 131 EP_RECORD* getDevTableEntry( byte addr, byte ep ); 132 void setDevTableEntry( byte addr, EP_RECORD* eprecord_ptr ); 133 byte 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 = USB_NAK_LIMIT ); 134 /* Control requests */ 135 byte getDevDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 136 byte getConfDescr( byte addr, byte ep, unsigned int nbytes, byte conf, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 137 byte getStrDescr( byte addr, byte ep, unsigned int nbytes, byte index, unsigned int langid, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 138 byte setAddr( byte oldaddr, byte ep, byte newaddr, unsigned int nak_limit = USB_NAK_LIMIT ); 139 byte setConf( byte addr, byte ep, byte conf_value, unsigned int nak_limit = USB_NAK_LIMIT ); 140 /**/ 141 byte setProto( byte addr, byte ep, byte interface, byte protocol, unsigned int nak_limit = USB_NAK_LIMIT ); 142 byte getProto( byte addr, byte ep, byte interface, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 143 byte getReportDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 144 byte setReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 145 byte getReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 146 byte getIdle( byte addr, byte ep, byte interface, byte reportID, char* dataptr, unsigned int nak_limit = USB_NAK_LIMIT ); 147 byte setIdle( byte addr, byte ep, byte interface, byte reportID, byte duration, unsigned int nak_limit = USB_NAK_LIMIT ); 148 /**/ 149 byte ctrlData( byte addr, byte ep, unsigned int nbytes, char* dataptr, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT ); 150 byte ctrlStatus( byte ep, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT ); 151 byte inTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT ); 152 int newInTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT); 153 byte outTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit = USB_NAK_LIMIT ); 154 byte dispatchPkt( byte token, byte ep, unsigned int nak_limit = USB_NAK_LIMIT ); 155 void Task( void ); 156 private: 157 void init(); 158 }; 159 160 //get device descriptor 161 inline byte USB::getDevDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit ) { 162 return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr, nak_limit )); 163 } 164 //get configuration descriptor 165 inline byte USB::getConfDescr( byte addr, byte ep, unsigned int nbytes, byte conf, char* dataptr, unsigned int nak_limit ) { 166 return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr, nak_limit )); 167 } 168 //get string descriptor 169 inline byte USB::getStrDescr( byte addr, byte ep, unsigned int nbytes, byte index, unsigned int langid, char* dataptr, unsigned int nak_limit ) { 170 return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nbytes, dataptr, nak_limit )); 171 } 172 //set address 173 inline byte USB::setAddr( byte oldaddr, byte ep, byte newaddr, unsigned int nak_limit ) { 174 return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL, nak_limit )); 175 } 176 //set configuration 177 inline byte USB::setConf( byte addr, byte ep, byte conf_value, unsigned int nak_limit ) { 178 return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL, nak_limit )); 179 } 180 //class requests 181 inline byte USB::setProto( byte addr, byte ep, byte interface, byte protocol, unsigned int nak_limit ) { 182 return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, NULL, nak_limit )); 183 } 184 inline byte USB::getProto( byte addr, byte ep, byte interface, char* dataptr, unsigned int nak_limit ) { 185 return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr, nak_limit )); 186 } 187 //get HID report descriptor 188 inline byte USB::getReportDescr( byte addr, byte ep, unsigned int nbytes, char* dataptr, unsigned int nak_limit ) { 189 return( ctrlReq( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr, nak_limit )); 190 } 191 inline byte USB::setReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit ) { 192 return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit )); 193 } 194 inline byte USB::getReport( byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char* dataptr, unsigned int nak_limit ) { // ** RI 04/11/09 195 return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit )); 196 } 197 /* returns one byte of data in dataptr */ 198 inline byte USB::getIdle( byte addr, byte ep, byte interface, byte reportID, char* dataptr, unsigned int nak_limit ) { 199 return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr, nak_limit )); 200 } 201 inline byte USB::setIdle( byte addr, byte ep, byte interface, byte reportID, byte duration, unsigned int nak_limit ) { 202 return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL, nak_limit )); 203 } 204 #endif //_usb_h_ 205