1 | /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
---|
2 |
|
---|
3 | This software may be distributed and modified under the terms of the GNU
|
---|
4 | General Public License version 2 (GPL2) as published by the Free Software
|
---|
5 | Foundation and appearing in the file GPL2.TXT included in the packaging of
|
---|
6 | this file. Please note that GPL2 Section 2[b] requires that all works based
|
---|
7 | on this software must also be made publicly available under the terms of
|
---|
8 | the GPL2 ("Copyleft").
|
---|
9 |
|
---|
10 | Contact information
|
---|
11 | -------------------
|
---|
12 |
|
---|
13 | Circuits At Home, LTD
|
---|
14 | Web : http://www.circuitsathome.com
|
---|
15 | e-mail : support@circuitsathome.com
|
---|
16 | */
|
---|
17 | /* USB functions */
|
---|
18 |
|
---|
19 | #ifndef USB_H_INCLUDED
|
---|
20 | #define USB_H_INCLUDED
|
---|
21 |
|
---|
22 | //#define TRACE_USBHOST(x) x
|
---|
23 | #define TRACE_USBHOST(x)
|
---|
24 |
|
---|
25 | #include <stdint.h>
|
---|
26 | #include "usb_ch9.h"
|
---|
27 | #include "address.h"
|
---|
28 |
|
---|
29 | /* Common setup data constant combinations */
|
---|
30 | #define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE // Get descriptor request type
|
---|
31 | #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'
|
---|
32 | #define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE // Get interface request type
|
---|
33 |
|
---|
34 | // USB Device Classes
|
---|
35 | #define USB_CLASS_USE_CLASS_INFO 0x00 // Use Class Info in the Interface Descriptors
|
---|
36 | #define USB_CLASS_AUDIO 0x01 // Audio
|
---|
37 | #define USB_CLASS_COM_AND_CDC_CTRL 0x02 // Communications and CDC Control
|
---|
38 | #define USB_CLASS_HID 0x03 // HID
|
---|
39 | #define USB_CLASS_PHYSICAL 0x05 // Physical
|
---|
40 | #define USB_CLASS_IMAGE 0x06 // Image
|
---|
41 | #define USB_CLASS_PRINTER 0x07 // Printer
|
---|
42 | #define USB_CLASS_MASS_STORAGE 0x08 // Mass Storage
|
---|
43 | #define USB_CLASS_HUB 0x09 // Hub
|
---|
44 | #define USB_CLASS_CDC_DATA 0x0a // CDC-Data
|
---|
45 | #define USB_CLASS_SMART_CARD 0x0b // Smart-Card
|
---|
46 | #define USB_CLASS_CONTENT_SECURITY 0x0d // Content Security
|
---|
47 | #define USB_CLASS_VIDEO 0x0e // Video
|
---|
48 | #define USB_CLASS_PERSONAL_HEALTH 0x0f // Personal Healthcare
|
---|
49 | #define USB_CLASS_DIAGNOSTIC_DEVICE 0xdc // Diagnostic Device
|
---|
50 | #define USB_CLASS_WIRELESS_CTRL 0xe0 // Wireless Controller
|
---|
51 | #define USB_CLASS_MISC 0xef // Miscellaneous
|
---|
52 | #define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific
|
---|
53 | #define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific
|
---|
54 |
|
---|
55 | // Additional Error Codes
|
---|
56 | #define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1
|
---|
57 | #define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE 0xD2
|
---|
58 | #define USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS 0xD3
|
---|
59 | #define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL 0xD4
|
---|
60 | #define USB_ERROR_HUB_ADDRESS_OVERFLOW 0xD5
|
---|
61 | #define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL 0xD6
|
---|
62 | #define USB_ERROR_EPINFO_IS_NULL 0xD7
|
---|
63 | #define USB_ERROR_INVALID_ARGUMENT 0xD8
|
---|
64 | #define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9
|
---|
65 | #define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA
|
---|
66 | #define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB
|
---|
67 | #define USB_ERROR_TRANSFER_TIMEOUT 0xFF
|
---|
68 |
|
---|
69 | #define USB_XFER_TIMEOUT 5000 //USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
|
---|
70 | //#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. 0 means NAKs are not counted
|
---|
71 | #define USB_RETRY_LIMIT 3 //retry limit for a transfer
|
---|
72 | #define USB_SETTLE_DELAY 200 //settle delay in milliseconds
|
---|
73 |
|
---|
74 | #define USB_NUMDEVICES 16 //number of USB devices
|
---|
75 | //#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller
|
---|
76 | #define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms
|
---|
77 |
|
---|
78 | /* USB state machine states */
|
---|
79 | #define USB_STATE_MASK 0xf0
|
---|
80 |
|
---|
81 | #define USB_STATE_DETACHED 0x10
|
---|
82 | #define USB_DETACHED_SUBSTATE_INITIALIZE 0x11
|
---|
83 | #define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE 0x12
|
---|
84 | #define USB_DETACHED_SUBSTATE_ILLEGAL 0x13
|
---|
85 | #define USB_ATTACHED_SUBSTATE_SETTLE 0x20
|
---|
86 | #define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30
|
---|
87 | #define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40
|
---|
88 | #define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50
|
---|
89 | #define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60
|
---|
90 | #define USB_STATE_ADDRESSING 0x70
|
---|
91 | #define USB_STATE_CONFIGURING 0x80
|
---|
92 | #define USB_STATE_RUNNING 0x90
|
---|
93 | #define USB_STATE_ERROR 0xa0
|
---|
94 | #define USB_STATE_MASK 0xf0
|
---|
95 |
|
---|
96 | // USB Setup Packet Structure
|
---|
97 | typedef struct
|
---|
98 | {
|
---|
99 | union
|
---|
100 | { // offset description
|
---|
101 | uint8_t bmRequestType; // 0 Bit-map of request type
|
---|
102 | struct
|
---|
103 | {
|
---|
104 | uint8_t recipient: 5; // Recipient of the request
|
---|
105 | uint8_t type: 2; // Type of request
|
---|
106 | uint8_t direction: 1; // Direction of data X-fer
|
---|
107 | };
|
---|
108 | } ReqType_u;
|
---|
109 | uint8_t bRequest; // 1 Request
|
---|
110 | union
|
---|
111 | {
|
---|
112 | uint16_t wValue; // 2 Depends on bRequest
|
---|
113 | struct
|
---|
114 | {
|
---|
115 | uint8_t wValueLo;
|
---|
116 | uint8_t wValueHi;
|
---|
117 | };
|
---|
118 | } wVal_u;
|
---|
119 | uint16_t wIndex; // 4 Depends on bRequest
|
---|
120 | uint16_t wLength; // 6 Depends on bRequest
|
---|
121 | } SETUP_PKT, *PSETUP_PKT;
|
---|
122 |
|
---|
123 | /**
|
---|
124 | * \class USBReadParser
|
---|
125 | *
|
---|
126 | * \brief Base class used for USB descriptor parsing.
|
---|
127 | */
|
---|
128 | class USBReadParser
|
---|
129 | {
|
---|
130 | public:
|
---|
131 | virtual void Parse(const uint32_t len, const uint8_t *pbuf, const uint32_t &offset) = 0;
|
---|
132 | };
|
---|
133 |
|
---|
134 | /**
|
---|
135 | * \class USBDeviceConfig
|
---|
136 | *
|
---|
137 | * \brief Device configuration class used for managing device life cycle.
|
---|
138 | */
|
---|
139 | class USBDeviceConfig
|
---|
140 | {
|
---|
141 | public:
|
---|
142 | //! @brief Perform final enumeration stage.
|
---|
143 | virtual uint32_t Init(uint32_t parent, uint32_t port, uint32_t lowspeed) = 0;
|
---|
144 |
|
---|
145 | //! @brief Free USB allocated resources (pipes and address).
|
---|
146 | virtual uint32_t Release() = 0;
|
---|
147 |
|
---|
148 | //! @brief Poll USB device. Call is made for each connected USB device on USBHost.task() call.
|
---|
149 | virtual uint32_t Poll() = 0;
|
---|
150 |
|
---|
151 | //! @brief Retrieve USB device address.
|
---|
152 | virtual uint32_t GetAddress() = 0;
|
---|
153 | };
|
---|
154 |
|
---|
155 | /**
|
---|
156 | * \class USBHost
|
---|
157 | *
|
---|
158 | * \brief Main USB host class.
|
---|
159 | */
|
---|
160 | class USBHost
|
---|
161 | {
|
---|
162 | AddressPoolImpl<USB_NUMDEVICES> addrPool;
|
---|
163 | USBDeviceConfig* devConfig[USB_NUMDEVICES];
|
---|
164 | uint32_t devConfigIndex;
|
---|
165 | uint32_t bmHubPre;
|
---|
166 |
|
---|
167 | public:
|
---|
168 | USBHost(void);
|
---|
169 |
|
---|
170 | //void SetHubPreMask() { bmHubPre |= bmHUBPRE; };
|
---|
171 | //void ResetHubPreMask() { bmHubPre &= (~bmHUBPRE); };
|
---|
172 |
|
---|
173 | AddressPool& GetAddressPool()
|
---|
174 | {
|
---|
175 | return (AddressPool&)addrPool;
|
---|
176 | };
|
---|
177 |
|
---|
178 | uint32_t RegisterDeviceClass(USBDeviceConfig *pdev)
|
---|
179 | {
|
---|
180 | for (uint32_t i = 0; i < USB_NUMDEVICES; ++i)
|
---|
181 | {
|
---|
182 | if (!devConfig[i])
|
---|
183 | {
|
---|
184 | devConfig[i] = pdev;
|
---|
185 | return 0;
|
---|
186 | }
|
---|
187 | }
|
---|
188 | return USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS;
|
---|
189 | };
|
---|
190 |
|
---|
191 | void ForEachUsbDevice(UsbDeviceHandleFunc pfunc)
|
---|
192 | {
|
---|
193 | addrPool.ForEachUsbDevice(pfunc);
|
---|
194 | };
|
---|
195 |
|
---|
196 | uint32_t getUsbTaskState(void);
|
---|
197 | void setUsbTaskState(uint32_t state);
|
---|
198 |
|
---|
199 | EpInfo* getEpInfoEntry(uint32_t addr, uint32_t ep);
|
---|
200 | uint32_t setEpInfoEntry(uint32_t addr, uint32_t epcount, EpInfo* eprecord_ptr);
|
---|
201 |
|
---|
202 | /* Control requests */
|
---|
203 | uint32_t getDevDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* dataptr);
|
---|
204 | uint32_t getConfDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint32_t conf, uint8_t* dataptr);
|
---|
205 | uint32_t getConfDescr(uint32_t addr, uint32_t ep, uint32_t conf, USBReadParser *p);
|
---|
206 | uint32_t getStrDescr(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr);
|
---|
207 | uint32_t setAddr(uint32_t oldaddr, uint32_t ep, uint32_t newaddr);
|
---|
208 | uint32_t setConf(uint32_t addr, uint32_t ep, uint32_t conf_value);
|
---|
209 | uint32_t ctrlReq(uint32_t addr, uint32_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
|
---|
210 | uint16_t wInd, uint16_t total, uint32_t nbytes, uint8_t* dataptr, USBReadParser *p);
|
---|
211 |
|
---|
212 | /* Transfer requests */
|
---|
213 | uint32_t inTransfer(uint32_t addr, uint32_t ep, uint32_t *nbytesptr, uint8_t* data);
|
---|
214 | uint32_t outTransfer(uint32_t addr, uint32_t ep, uint32_t nbytes, uint8_t* data);
|
---|
215 | uint32_t dispatchPkt(uint32_t token, uint32_t ep, uint32_t nak_limit);
|
---|
216 |
|
---|
217 | void Task(void);
|
---|
218 |
|
---|
219 | uint32_t DefaultAddressing(uint32_t parent, uint32_t port, uint32_t lowspeed);
|
---|
220 | uint32_t Configuring(uint32_t parent, uint32_t port, uint32_t lowspeed);
|
---|
221 | uint32_t ReleaseDevice(uint32_t addr);
|
---|
222 |
|
---|
223 | private:
|
---|
224 | void init();
|
---|
225 | uint32_t setPipeAddress(uint32_t addr, uint32_t ep, EpInfo **ppep, uint32_t &nak_limit);
|
---|
226 | uint32_t OutTransfer(EpInfo *pep, uint32_t nak_limit, uint32_t nbytes, uint8_t *data);
|
---|
227 | uint32_t InTransfer(EpInfo *pep, uint32_t nak_limit, uint32_t *nbytesptr, uint8_t* data);
|
---|
228 | };
|
---|
229 |
|
---|
230 | #endif /* USB_H_INCLUDED */
|
---|