Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

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