NetBurner 3.5.6
PDF Version
usb.h
1/*NB_REVISION*/
2
3/*NB_COPYRIGHT*/
4
5
6/******************************************************************************
7 * Welcome to the NetBurner USB framework. This header contains the primary *
8 * abstraction definitions used to define the various flavors of the USB *
9 * stack. The reasoning for the arrangement of stateful or logical data and *
10 * for the existence of certain methods may not be readily obvious without *
11 * some level of understanding of the various stateful mechanisms and *
12 * abstractions within the USB standard. *
13 * *
14 * Fundamentally, USB is a host initiated multi-device bus protocol that *
15 * provides a standardized mechanism for device discovery, recognition, *
16 * control, and communication. Within this context, devices are further *
17 * broken down into Interfaces and Endpoints. Endpoints represent a specific *
18 * function being exposed to the host. This could be as simple as reporting *
19 * the state of a single input or a debug serial stream or a complex as a *
20 * a multiplexed stream of multiple interleaved data streams. Additionally, *
21 * a given function for an endpoint may only need unidirectional *
22 * communications. As a result, endpoints generally are described by both *
23 * their logical number and the bus direction in which they transfer data. *
24 * *
25 * If Endpoints are the simplest functions or features of the device, an *
26 * Interface is a collection of functions that are combined to fulfill a *
27 * specific device role. Take for instance a modem: it would need endpoints *
28 * to transfer data from the Host to the Device, from the Device to the Host,*
29 * and some other number of endpoints to configure and control the modem, *
30 * as well as be notified of changes in the modem's operating state. All of *
31 * the endpoints necessary for the function role, would be collected into an *
32 * Interface. In the case where a device were to simultaneously fulfill *
33 * multiple rolls (or the same role in multiple instances), it would have *
34 * multiple Interfaces to serve them. *
35 * *
36 * As a final bit of abstraction, Devices may Configurations (and in most *
37 * cases must have at least one) that define a specific set of interfaces *
38 * that are active when selected. Configurations allow a multi-role device to *
39 * select what role it is to fulfill given a set of mutually exclusive *
40 * possibilities. (i.e. whether the device acts as a USB-to-Serial adapter *
41 * or as a USB-to-Ethernet adapter). *
42 * *
43 * Bus Transactions *
44 * ================ *
45 * As mentioned previously, all transactions on the bus are initiated by the *
46 * Host. There are three types of transactions that may take place on the *
47 * bus: SETUP, IN, or OUT. IN and OUT transactions are fairly self *
48 * explanatory and are named for their relation to the Host; IN transactions *
49 * transfer data from the Device INto the Host, whereas OUT transactions *
50 * transfer data OUT of the Host to the Device. These two transactions may *
51 * be use on any endpoint type, but are not normally present on Control *
52 * Endpoints. SETUP transactions on the other hand are _only_ allowed on *
53 * Control Endpoints, as they are used to transmit or coordinate for *
54 * transmitting a command to the device. A SETUP transaction includes a *
55 * single 8 byte data packet (generally referred to as a Setup Packet) that *
56 * describes the Control Request being made. The final target of the request *
57 * may be an Endpoint, Interface, or the main Device, but it is important *
58 * to note that it is _always_ sent to an Endpoint. *
59 * *
60 * Bus Transfers *
61 * ============= *
62 * If Bus Transactions define _how_ data moves across the bus, then Bus *
63 * Transfers define the _why_ (and partly the _when_). There are four *
64 * different types of Bus Transfers (which give rise to the four types of *
65 * Device Endpoint of the same names): Bulk, Interrupt, Isochronous, and *
66 * Control. Really, the thing to understand is that the first three describe *
67 * how/when to move arbitrary data across the bus. It is only Control *
68 * Transfers that present any major complexity to the USB driver *
69 * architecture. *
70 * *
71 * Control transfers begin with an initial Setup transaction in order for the *
72 * Device to understand what is to be done. After the Setup transaction *
73 * comes the Data phase of the transfer (if present). If either the Host or *
74 * Device needs to transfer additional Data to complete the control request, *
75 * there may be an IN or OUT transaction as required. Following the Data *
76 * phase, there is a Status stage, where the opposite side transmits a zero *
77 * length packet to indicate completion of the request; if the Data stage *
78 * was an OUT (or if no Data stage occurred) then the Status stage would *
79 * consist of an IN transaction and vice versa. *
80 * *
81 * *
82 * *
83 * *
84 * Device Initialization *
85 * ====================== *
86 * In this framework, there are three mail logical stages to establishing *
87 * complete device initialization and communications. First is the most *
88 * basic and obvious: all the relevant data structures for the device driver *
89 * must be instantiated. Generally, this will be done as static global *
90 * objects, constructed at application startup. When the Device is *
91 * initialized, the Default Control Endpoint is registered on the device as *
92 * well. Second, the logical device registered with the USB hardware *
93 * controller. Finally, the Host will begin Device Enumeration (aka, *
94 * discovery and recognition of a newly connected Device on the bus). During *
95 * Enumeration, the device may be configured, at which point the relevant *
96 * Interfaces will be registered on the Device object. Additionally, as part *
97 * of the Interface registration, the included Endpoints will be registered *
98 * as well. *
99 * *
100 * Control Processing *
101 * ================== *
102 * One of the key *
103 * *
104 * *
105 * *
106 * *
107 *****************************************************************************/
108
109
110#ifndef __NB_USB_H
111#define __NB_USB_H
112#ifdef SOMRT1061
113#include <predef.h>
114#include <buffers.h>
115#include <usb_lib_cfg.h>
116#include <usb_desc.h>
117#include <usb_msg.h>
118
119// Make a FOREACH macro
120#define _UFE_0(_UWHAT)
121#define _UFE_1(_UWHAT, prefix, langid, X) _UWHAT(prefix, langid, 1, X)
122#define _UFE_2(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 2, X)_UFE_1(_UWHAT, prefix, langid, __VA_ARGS__)
123#define _UFE_3(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 3, X)_UFE_2(_UWHAT, prefix, langid, __VA_ARGS__)
124#define _UFE_4(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 4, X)_UFE_3(_UWHAT, prefix, langid, __VA_ARGS__)
125#define _UFE_5(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 5, X)_UFE_4(_UWHAT, prefix, langid, __VA_ARGS__)
126#define _UFE_6(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 6, X)_UFE_5(_UWHAT, prefix, langid, __VA_ARGS__)
127#define _UFE_7(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 7, X)_UFE_6(_UWHAT, prefix, langid, __VA_ARGS__)
128#define _UFE_8(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 8, X)_UFE_7(_UWHAT, prefix, langid, __VA_ARGS__)
129#define _UFE_9(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 9, X)_UFE_8(_UWHAT, prefix, langid, __VA_ARGS__)
130#define _UFE_10(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 10, X)_UFE_9(_UWHAT, prefix, langid, __VA_ARGS__)
131#define _UFE_11(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 11, X)_UFE_10(_UWHAT, prefix, langid, __VA_ARGS__)
132#define _UFE_12(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 12, X)_UFE_11(_UWHAT, prefix, langid, __VA_ARGS__)
133#define _UFE_13(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 13, X)_UFE_12(_UWHAT, prefix, langid, __VA_ARGS__)
134#define _UFE_14(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 14, X)_UFE_13(_UWHAT, prefix, langid, __VA_ARGS__)
135#define _UFE_15(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 15, X)_UFE_14(_UWHAT, prefix, langid, __VA_ARGS__)
136#define _UFE_16(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 16, X)_UFE_15(_UWHAT, prefix, langid, __VA_ARGS__)
137#define _UFE_17(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 17, X)_UFE_16(_UWHAT, prefix, langid, __VA_ARGS__)
138#define _UFE_18(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 18, X)_UFE_17(_UWHAT, prefix, langid, __VA_ARGS__)
139#define _UFE_19(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 19, X)_UFE_18(_UWHAT, prefix, langid, __VA_ARGS__)
140#define _UFE_20(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 20, X)_UFE_19(_UWHAT, prefix, langid, __VA_ARGS__)
141#define _UFE_21(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 21, X)_UFE_20(_UWHAT, prefix, langid, __VA_ARGS__)
142#define _UFE_22(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 22, X)_UFE_21(_UWHAT, prefix, langid, __VA_ARGS__)
143#define _UFE_23(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 23, X)_UFE_22(_UWHAT, prefix, langid, __VA_ARGS__)
144#define _UFE_24(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 24, X)_UFE_23(_UWHAT, prefix, langid, __VA_ARGS__)
145#define _UFE_25(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 25, X)_UFE_24(_UWHAT, prefix, langid, __VA_ARGS__)
146#define _UFE_26(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 26, X)_UFE_25(_UWHAT, prefix, langid, __VA_ARGS__)
147#define _UFE_27(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 27, X)_UFE_26(_UWHAT, prefix, langid, __VA_ARGS__)
148#define _UFE_28(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 28, X)_UFE_27(_UWHAT, prefix, langid, __VA_ARGS__)
149#define _UFE_29(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 29, X)_UFE_28(_UWHAT, prefix, langid, __VA_ARGS__)
150#define _UFE_30(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 30, X)_UFE_29(_UWHAT, prefix, langid, __VA_ARGS__)
151#define _UFE_31(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 31, X)_UFE_30(_UWHAT, prefix, langid, __VA_ARGS__)
152//... repeat as needed
153
154#define _UGET_MACRO(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,NAME,...) NAME
155
156#define _UNARGS(...) _UGET_MACRO(_0,__VA_ARGS__,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
157#define _UFOR_EACH(action,prefix,langid,...) \
158 _UGET_MACRO(_0,__VA_ARGS__,_UFE_31,_UFE_30,_UFE_29,_UFE_28,_UFE_27,_UFE_26,_UFE_25,_UFE_24,_UFE_23,_UFE_22,_UFE_21,_UFE_20,_UFE_19,_UFE_18,_UFE_17,_UFE_16,_UFE_15,_UFE_14,_UFE_13,_UFE_12,_UFE_11,_UFE_10,_UFE_9,_UFE_8,_UFE_7,_UFE_6,_UFE_5,_UFE_4,_UFE_3,_UFE_2,_UFE_1,_UFE_0)(action,prefix,langid,__VA_ARGS__)
159#define _UVAL(prefix, langid, idx, val) val,
160
161
162// Example
163// Some actions
164#define QUALIFIER(X) X::
165#define OPEN_NS(X) namespace X {
166#define CLOSE_NS(X) }
167// Helper function
168#define QUALIFIED(NAME,...) _UFOR_EACH(QUALIFIER,__VA_ARGS__)NAME
169
170#define STRDESC16(prefix, langid, idx,s) \
171static const StrDesc prefix##_StrDesc_##langid##_##idx = {\
172 eStrEnc_t::eStrEnc_UTF16, ((sizeof(s)/sizeof(s [0]))-1)*sizeof(s [0]), s \
173};
174
175#define STRDESCLANGTBLREF_VAL(prefix, langid, idx,x) & prefix##_StrDesc_##langid##_##idx,
176
177#define STRDESC16LANGTBL(prefix, langid, ...) \
178 _UFOR_EACH(STRDESC16, prefix, langid, __VA_ARGS__)\
179static const StrDesc *prefix##_StrDescTbl_##langid[_UNARGS(__VA_ARGS__)] = {\
180 _UFOR_EACH(STRDESCLANGTBLREF_VAL, prefix, langid, __VA_ARGS__)\
181};
182
183#define STRDESCLANGID(prefix, langid, idx, x) eLangID_t:: x,
184#define STRDESCZERO(prefix, ...) \
185static const usb_desc_str_zero_t prefix##_StrDescZero = {\
186 2+(_UNARGS(__VA_ARGS__)*2),\
187 (uint8_t)eDesc_t::eDesc_Str,\
188 {_UFOR_EACH(STRDESCLANGID, 0, 0, __VA_ARGS__)}\
189};
190
191#define STRDESCTBLLEN(prefix, langzero, ...)\
192 sizeof(prefix##_StrDescTbl_##langzero)/sizeof(prefix##_StrDescTbl_##langzero [0])
193
194#define STRDESCTBLREF(prefix, langid, idx,x) prefix##_StrDescTbl_##x,
195#define STRDESCTBL(prefix, ...) \
196STRDESCZERO(prefix, __VA_ARGS__)\
197static const StrDescTbl prefix##_StrTbl = { \
198 & prefix##_StrDescZero,\
199 STRDESCTBLLEN(prefix,__VA_ARGS__),\
200 { _UFOR_EACH(STRDESCTBLREF, prefix, 0, __VA_ARGS__)}\
201};
202
203
204
205
206namespace nbrtos {
207namespace USB {
208
209enum eBusSpeed_t {
210 eBusSpeed_Low = 0,
211 eBusSpeed_Full = 1,
212 eBusSpeed_High = 2,
213 eBusSpeed_Super = 3,
214};
215
216enum class eCtlrEvt_t : uint8_t{
217 eCtlrEvt_Pkt = 0,
218 eCtlrEvt_Error = 1,
219 eCtlrEvt_PortChange = 2,
220 eCtlrEvt_FrameList = 3,
221 eCtlrEvt_SysError = 4,
222 eCtlrEvt_AsyncAdv = 5,
223 eCtlrEvt_ResetRxed = 6,
224 eCtlrEvt_SOF = 7,
225 eCtlrEvt_Suspended = 8,
226 eCtlrEvt_ULPI = 10,
227 eCtlrEvt_HostHalted = 12,
228 eCtlrEvt_Reclaim = 13,
229 eCtlrEvt_PeriodicSched = 14,
230 eCtlrEvt_AsyncSched = 15,
231 eCtlrEvt_NAK = 16,
232 eCtlrEvt_Timer0 = 24,
233 eCtlrEvt_Timer1 = 25,
234 eCtlrEvt_MAX_EVENT = eCtlrEvt_Timer1
235};
236
237enum eListSiz_t {
238 eListSiz_1 = 0,
239 eListSiz_2 = 1,
240 eListSiz_4 = 2,
241 eListSiz_8 = 3,
242 eListSiz_16 = 4,
243 eListSiz_32 = 5,
244 eListSiz_64 = 6,
245 eListSiz_128 = 7,
246 eListSiz_256 = 8,
247 eListSiz_512 = 9,
248 eListSiz_1024 = 10,
249 eListSiz_2048 = 11,
250 eListSiz_4096 = 12,
251 eListSiz_8192 = 13,
252 eListSiz_16384 = 14,
253 eListSiz_32768 = 15,
254};
255
256enum class eBusState_t : uint8_t {
257 eBusState_Disconnected = 0x0,
258 eBusState_Powered = 0x1,
259 eBusState_Attached = 0x2,
260 eBusState_Default = 0x3,
261 eBusState_Address = 0x4,
262 eBusState_Configured = 0x5,
263 eBusState_Susp_Power = 0x81,
264 eBusState_Susp_Attached= 0x82,
265 eBusState_Susp_Default = 0x83,
266 eBusState_Susp_Address = 0x84,
267 eBusState_Susp_Config = 0x85,
268};
269
270struct USB_Event_t {
271 uint8_t devAddr;
272 uint8_t epNum;
273 uint8_t ctlrID;
274 eCtlrEvt_t event;
275};
276
277#define USB_TRANSFER_CANCELED 0x8000
278
279// FIXME: Actually define bufPtr_t
280typedef void * bufPtr_t;
281class UHC;
282typedef int (*endpt_rx_cb_t) (uint8_t devAddr, uint8_t endptNum, bufPtr_t pbuf, uint16_t bufLen);
283typedef int (*evt_cb_t) (eCtlrEvt_t event);
284
285struct AllocPoolEl {
286 AllocPoolEl *pNext;
287};
288
289class BaseAllocPool {
290 AllocPoolEl *free_list;
291 bool bInited;
292public:
293 BaseAllocPool(): free_list(NULL), bInited(false) {}
294 void Init(void *pool, uint32_t poolSize, uint32_t elSize);
295 AllocPoolEl *Get();
296 void Free(AllocPoolEl *pAlloc);
297};
298
299template<class T, int n> class AllocPool {
300 T store[n];
301 BaseAllocPool pool;
302public:
303 AllocPool<T,n>() { pool.Init((void *)&store, sizeof(T)*n, sizeof(T)); }
304 inline T *Get() { return (T *)pool.Get(); }
305 void Free(T *t) { pool.Free((AllocPoolEl *)t); }
306};
307
308// Forward declarations
309// String descriptors are UTF-16 encoded
310struct StringDescriptorTmpl {
311 const char16_t *pData;
312 eLangID_t id_Lang;
313 uint8_t len;
314};
315
316#define StrDescTmplTbl(tblName) StringDescriptorTmpl tblName[] = {
317#define StrDescTmpl(value, langID) {value, langID, sizeof(value)-1}
318#define EndDescTmplTbl(tblName) {NULL, 0x0000, 0}};
319
320#define NamedStrDescTmpl(name, value, langID) StringDescriptorTmpl name = StrDescTmpl(value, langID);
321
322struct StringDescriptor {
323 enum eChainType_t {
324 eChain_None = 1,
325 eChain_TmplTbl = 2,
326 eChain_Linked = 3,
327 };
328 StringDescriptor *pNext;
329 union {
330 StringDescriptorTmpl *tmpl;
331 uint32_t skipCount;
332 };
333 eChainType_t chain;
334 StringDescriptor(StringDescriptorTmpl *tmplTbl, int tblLen);
335 StringDescriptor(const StringDescriptor &cpyFrom);
336
337 const char *c_str() const;
338};
339#define BasicStrDesc(descName, langID, value) \
340StrDescTmpl(descName##_Tmpl,langID, value) \
341StringDescriptor descName(descName##_Tmpl,1);
342
343typedef char16_t strDescChar_t;
344
345enum class eStrEnc_t : uint8_t {
346 eStrEnc_ASCII = 0,
347 eStrEnc_UTF8 = 1,
348 eStrEnc_UTF16 = 2,
349 eStrEnc_UTF32 = 3
350};
351
352struct StrDesc {
353 eStrEnc_t enc;
354 uint8_t len;
355 strDescChar_t val[];
356};
357typedef const StrDesc *pcStrDesc;
358
359struct StrDescTblBlock {
360 StrDescTblBlock *pNext;
361 uint16_t blockLen;
362 uint16_t descIdx[16];
363 StrDesc desc[];
364};
365
366struct StrDescTbl {
367 const usb_desc_str_zero_t *langTbl;
368 uint8_t descCount;
369 const StrDesc **tbl[];
370
371 pcStrDesc GetDesc(uint8_t descnum);
372// const pcStrDesc *tbl[];
373};
374
375class Ctlr;
376class Device;
377
378typedef int (*endPtCB_t) (Device *dev, uint8_t ep, PoolPtr pp, uint16_t bufLen);
379typedef int (*endPtSetupCB_t) (Device *dev, uint8_t ep, usb_setup_pkt_t msg);
380typedef int (*suspCB_t) (Device *dev, bool suspendState);
381
382struct EndPt_t {
383 endPtCB_t ProcessBuffer;
384 endPtSetupCB_t ProcessSetupPkt;
385 eEndPt_t type;
386 bool inUse;
387};
388
389
390class Device {
391 public:
392 // This class is a protection method for allowing access to specific
393 // methods without making the allowed classes able to access all private
394 // members.
395 class StallReqKey {
396 friend class Device;
397 StallReqKey() {}
398 };
399 class FlushReqKey {
400 friend class Device;
401 FlushReqKey() {}
402 };
403
404 protected:
405 Device *pNext;
406 Ctlr *parent;
407
408 const usb_cfg_t *cfg;
409 const usb_other_spd_t *spdCfg;
410// DeviceCfg *cfg[USB_MAX_CFG_PER_DEVICE];
411// DeviceIntf *intf[USB_MAX_INTF_PER_DEVICE];
412 EndPt_t *endpt[USB_MAX_ENDPTS_PER_DEVICE * 2];
413 const usb_cfg_t *pActiveCfg;
414 const StrDescTbl *strTbl;
415
416 usb_dev_t desc;
417 usb_dev_qual_t qual;
418
419 eBusState_t busState;
420 uint8_t txnState;
421 uint8_t txnSubState;
422 uint8_t addr;
423 uint8_t activeCfg;
424
425 uint8_t numEndpts;
426 protected:
427 int initInTransfer(uint8_t epnum, PoolPtr pp, bool irqOnComplete, bool dontblock = false);
428 int initOutTransfer(uint8_t epnum, bool irqOnComplete, bool dontblock = false);
429 int BeginTxn(uint8_t epnum, uint8_t state, uint8_t substate);
430 inline int SetTxnState(uint8_t state, uint8_t substate)
431 {
432 txnState = state;
433 txnSubState = substate;
434 return (((uint16_t)txnState) << 8) | txnSubState;
435 }
436
437 public:
438
439 Device(Ctlr *_parent, const usb_dev_t *_desc, const usb_cfg_t *_cfg, const StrDescTbl *_strTbl);
440 void SetOtherSpd(usb_dev_qual_t *oqual, usb_other_spd_t *ospdCfg);
441 void ClrOtherSpd();
442 void AssignCtlr(Ctlr *newParent);
443
444 void SwapSpeeds();
445
446 PoolPtr GetDesc(uint16_t wValue, uint16_t wIndex, uint16_t wLength);
447 const StrDesc *GetStr(uint16_t lang_id, uint8_t idx);
448 uint8_t GetNextEndPt(uint8_t curEndPt);
449 virtual uint16_t GetMaxPktSize(uint8_t epnum, eDir_t dir) = 0;
450// DeviceIntf *GetIntf(uint8_t ifnum);
451// DeviceEP *GetEndpt(uint8_t epnum);
452// DeviceCfg * GetConfiguration(uint8_t cfgnum);
453
454 virtual void Event_BusReset();
455 virtual void Event_Suspend();
456 virtual void Event_Resume();
457 virtual void Event_StartOfFrame();
458 virtual int Event_ControlMsg(bufPtr_t ctlMsg, uint8_t bufLen);
459 virtual int SetConfiguration(uint16_t wValue);
460 virtual int SetAltSetting(uint16_t wIndex, uint16_t wValue);
461 virtual int SetDevAddr(uint8_t devAddr, Device *dev);
462 virtual void StallEP(uint8_t epnum, eDir_t dir, Device::StallReqKey key);
463 virtual void FlushEP(uint8_t epnum, Device::FlushReqKey key);
464
465 virtual uint16_t GetStatus(eReqTarget_t target, uint16_t wIndex, int *err);
466 virtual uint8_t GetActiveConfig(int *err) = 0;
467 virtual uint8_t GetAltSetting(uint8_t intfNum, int *err) = 0;
468 uint8_t GetDevAddr();
469 uint8_t GetNumEPs();
470
471 eBusState_t GetUSBState();
472 void SetUSBState(eBusState_t newState);
473
474 void SetNext(Device *dev);
475 Device *GetNext();
476
477 virtual int ProcessBuffer(uint8_t epnum, PoolPtr pp, uint16_t bufLen);
478 virtual int DispatchSetupPkt(uint8_t epnum, usb_setup_pkt_t msg);
479 virtual int ProcessSetupPkt(uint8_t epnum, usb_setup_pkt_t msg);
480
481 virtual int TransmitBuffer(uint8_t epnum, PoolPtr pp);
482// virtual int SendZLP(uint8_t epnum);
483};
484
485// USB Controller
486// This is a *Hardware* abstraction. It shall have no knowledge or influence on
487// the logical operations of either a host or a device controller implementation.
488// It shall simply implement the required hardware methods to allow a device or
489// host to function through the abstracted hardware.
490class Ctlr {
491public:
492 class StallReqKey {
493 friend class Device;
494 StallReqKey() {}
495 };
496 class FlushReqKey {
497 friend class Device;
498 FlushReqKey() {}
499 };
500 class InTransferKey {
501 friend class Device;
502 InTransferKey() {}
503 };
504 class OutTransferKey {
505 friend class Device;
506 OutTransferKey() {}
507 };
508protected:
509 int maxEndpts;
510 int currEndpts;
511// eType_t;
512// eState_t state;
513 evt_cb_t EventCB[(uint8_t)eCtlrEvt_t::eCtlrEvt_MAX_EVENT];
514
515 uint8_t ctlrID;
516protected:
517 virtual int initInTransfer(uint8_t epnum, uint8_t* data, uint16_t length, bool irqOnComplete, bool dontblock = false) = 0;
518 virtual int initInTransfer(uint8_t epnum, PoolPtr pp, bool irqOnComplete, bool dontblock = false) = 0;
519 virtual int initOutTransfer(uint8_t epnum, bool irqOnComplete, bool dontblock = false) = 0;
520 virtual void StallEP(uint8_t devAddr, uint8_t epnum, eDir_t dir) = 0;
521 virtual void FlushEP(uint8_t devAddr, uint8_t epnum) = 0;
522public:
523 inline uint8_t getID() { return ctlrID; }
524 evt_cb_t RegisterEventHandler(eCtlrEvt_t event, evt_cb_t eventCB);
525 virtual void DoEvent(USB_Event_t event) = 0;
526 virtual int ProcessBuffer(uint8_t devAddr, uint8_t epnum, PoolPtr pp) = 0;
527 virtual int RegisterDevice(uint8_t devAddr, Device *dev) = 0;
528 virtual int RegisterEP(uint8_t devAddr, uint8_t epnum, eDir_t dir, eEndPt_t type,
529 uint16_t maxPktSize, endPtCB_t fnCB) = 0;
530 virtual int ReleaseEP(uint8_t devAddr, uint8_t epnum, eDir_t dir) = 0;
531
532 inline void StallEP(uint8_t devAddr, uint8_t epnum, eDir_t dir, Ctlr::StallReqKey key)
533 { StallEP(devAddr, epnum, dir); }
534 inline void FlushEP(uint8_t devAddr, uint8_t epnum, Ctlr::FlushReqKey key)
535 { FlushEP(devAddr, epnum); }
536 int initInTransfer(uint8_t epnum, PoolPtr pp, bool irqOnComplete, bool dontblock, InTransferKey key);
537 int initOutTransfer(uint8_t epnum, bool irqOnComplete, bool dontblock, OutTransferKey key);
538
539 virtual int sendControlPkt(uint8_t epnum, uint8_t *buf, uint16_t bufLen) = 0;
540 virtual int sendControlPkt(uint8_t epnum, PoolPtr pp) = 0;
541 virtual int TransmitBuffer(uint8_t devAddr, uint8_t ep, PoolPtr pp) = 0;
542 virtual int SendZLP(uint8_t devAddr, uint8_t epnum) = 0;
543
544 virtual int InAvail(uint8_t epnum) = 0;
545 virtual int OutAvail(uint8_t epnum) = 0;
546
547 int ConfigureUSBTimer(int timer, uint32_t uSecs, bool bRepeat);
548 int StopUSBTimer(int timer);
549 virtual int SetDevAddr(uint8_t devAddr, Device *dev) = 0;
550};
551
552inline int Device::initInTransfer(uint8_t epnum, PoolPtr pp, bool irqOnComplete, bool dontblock)
553{ return parent->initInTransfer(epnum, pp, irqOnComplete, dontblock, Ctlr::InTransferKey{});}
554
555inline int Device::initOutTransfer(uint8_t epnum, bool irqOnComplete, bool dontblock)
556{ return parent->initOutTransfer(epnum, irqOnComplete, dontblock, Ctlr::OutTransferKey{});}
557
558// USB Device Controller
559class UDC : public Ctlr {
560protected:
561 Device *dev;
562 EndPt_t endpt[USB_MAX_ENDPTS_PER_CTRLR*2];
563 suspCB_t suspCB;
564
565public:
566 virtual void Init(Device *Dev) = 0;
567
568 int RegisterDevice(uint8_t devAddr, Device *_dev);
569
570 virtual int RegisterEP(uint8_t devAddr, uint8_t epnum, eDir_t dir, eEndPt_t type,
571 uint16_t maxPktSize, endPtCB_t fnCB);
572 virtual int ReleaseEP(uint8_t devAddr, uint8_t epnum, eDir_t dir);
573
574 virtual void DoEvent(USB_Event_t event);
575
576 virtual int ProcessSetupPkt(uint8_t devAddr, uint8_t epnum, usb_setup_pkt_t msg);
577 virtual int ProcessBuffer(uint8_t devAddr, uint8_t epnum, PoolPtr pp);
578
579};
580
581// USB Host Controller
582class UHC : public Ctlr {
583
584public:
585 virtual void Init();
586 int SendToDevice(uint8_t devAddr, uint8_t endpt, void *buf, int datLen);
587 virtual int TransmitBuffer(uint8_t devAddr, uint8_t ep, PoolPtr pp);
588};
589
590class UOTGC : public UDC, public UHC {
591
592public:
593 virtual void Init();
594};
595
596}
597}
598#endif
599#endif /* ----- #ifndef __NB_USB_H ----- */
NetBurner Buffers API.
Main buffer structure for network and serial communication.
Definition buffers.h:90