NetBurner 3.5.8
PDF Version
MIMXRT11xx/include/usb.h
1/**************************************************************************/
31
32#ifndef __NB_USB_H
33#define __NB_USB_H
34#ifdef SOMRT1061
35#include <predef.h>
36#include <buffers.h>
37#include <usb_lib_cfg.h>
38#include <usb_desc.h>
39#include <usb_msg.h>
40
41// Make a FOREACH macro
42#define _UFE_0(_UWHAT)
43#define _UFE_1(_UWHAT, prefix, langid, X) _UWHAT(prefix, langid, 1, X)
44#define _UFE_2(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 2, X)_UFE_1(_UWHAT, prefix, langid, __VA_ARGS__)
45#define _UFE_3(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 3, X)_UFE_2(_UWHAT, prefix, langid, __VA_ARGS__)
46#define _UFE_4(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 4, X)_UFE_3(_UWHAT, prefix, langid, __VA_ARGS__)
47#define _UFE_5(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 5, X)_UFE_4(_UWHAT, prefix, langid, __VA_ARGS__)
48#define _UFE_6(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 6, X)_UFE_5(_UWHAT, prefix, langid, __VA_ARGS__)
49#define _UFE_7(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 7, X)_UFE_6(_UWHAT, prefix, langid, __VA_ARGS__)
50#define _UFE_8(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 8, X)_UFE_7(_UWHAT, prefix, langid, __VA_ARGS__)
51#define _UFE_9(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 9, X)_UFE_8(_UWHAT, prefix, langid, __VA_ARGS__)
52#define _UFE_10(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 10, X)_UFE_9(_UWHAT, prefix, langid, __VA_ARGS__)
53#define _UFE_11(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 11, X)_UFE_10(_UWHAT, prefix, langid, __VA_ARGS__)
54#define _UFE_12(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 12, X)_UFE_11(_UWHAT, prefix, langid, __VA_ARGS__)
55#define _UFE_13(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 13, X)_UFE_12(_UWHAT, prefix, langid, __VA_ARGS__)
56#define _UFE_14(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 14, X)_UFE_13(_UWHAT, prefix, langid, __VA_ARGS__)
57#define _UFE_15(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 15, X)_UFE_14(_UWHAT, prefix, langid, __VA_ARGS__)
58#define _UFE_16(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 16, X)_UFE_15(_UWHAT, prefix, langid, __VA_ARGS__)
59#define _UFE_17(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 17, X)_UFE_16(_UWHAT, prefix, langid, __VA_ARGS__)
60#define _UFE_18(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 18, X)_UFE_17(_UWHAT, prefix, langid, __VA_ARGS__)
61#define _UFE_19(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 19, X)_UFE_18(_UWHAT, prefix, langid, __VA_ARGS__)
62#define _UFE_20(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 20, X)_UFE_19(_UWHAT, prefix, langid, __VA_ARGS__)
63#define _UFE_21(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 21, X)_UFE_20(_UWHAT, prefix, langid, __VA_ARGS__)
64#define _UFE_22(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 22, X)_UFE_21(_UWHAT, prefix, langid, __VA_ARGS__)
65#define _UFE_23(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 23, X)_UFE_22(_UWHAT, prefix, langid, __VA_ARGS__)
66#define _UFE_24(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 24, X)_UFE_23(_UWHAT, prefix, langid, __VA_ARGS__)
67#define _UFE_25(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 25, X)_UFE_24(_UWHAT, prefix, langid, __VA_ARGS__)
68#define _UFE_26(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 26, X)_UFE_25(_UWHAT, prefix, langid, __VA_ARGS__)
69#define _UFE_27(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 27, X)_UFE_26(_UWHAT, prefix, langid, __VA_ARGS__)
70#define _UFE_28(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 28, X)_UFE_27(_UWHAT, prefix, langid, __VA_ARGS__)
71#define _UFE_29(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 29, X)_UFE_28(_UWHAT, prefix, langid, __VA_ARGS__)
72#define _UFE_30(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 30, X)_UFE_29(_UWHAT, prefix, langid, __VA_ARGS__)
73#define _UFE_31(_UWHAT, prefix, langid, X, ...) _UWHAT(prefix, langid, 31, X)_UFE_30(_UWHAT, prefix, langid, __VA_ARGS__)
74//... repeat as needed
75
76#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
77
78#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)
79#define _UFOR_EACH(action,prefix,langid,...) \
80 _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__)
81#define _UVAL(prefix, langid, idx, val) val,
82
83
84// Example
85// Some actions
86#define QUALIFIER(X) X::
87#define OPEN_NS(X) namespace X {
88#define CLOSE_NS(X) }
89// Helper function
90#define QUALIFIED(NAME,...) _UFOR_EACH(QUALIFIER,__VA_ARGS__)NAME
91
92#define STRDESC16(prefix, langid, idx,s) \
93static const StrDesc prefix##_StrDesc_##langid##_##idx = {\
94 eStrEnc_t::eStrEnc_UTF16, ((sizeof(s)/sizeof(s [0]))-1)*sizeof(s [0]), s \
95};
96
97#define STRDESCLANGTBLREF_VAL(prefix, langid, idx,x) & prefix##_StrDesc_##langid##_##idx,
98
99#define STRDESC16LANGTBL(prefix, langid, ...) \
100 _UFOR_EACH(STRDESC16, prefix, langid, __VA_ARGS__)\
101static const StrDesc *prefix##_StrDescTbl_##langid[_UNARGS(__VA_ARGS__)] = {\
102 _UFOR_EACH(STRDESCLANGTBLREF_VAL, prefix, langid, __VA_ARGS__)\
103};
104
105#define STRDESCLANGID(prefix, langid, idx, x) eLangID_t:: x,
106#define STRDESCZERO(prefix, ...) \
107static const usb_desc_str_zero_t prefix##_StrDescZero = {\
108 2+(_UNARGS(__VA_ARGS__)*2),\
109 (uint8_t)eDesc_t::eDesc_Str,\
110 {_UFOR_EACH(STRDESCLANGID, 0, 0, __VA_ARGS__)}\
111};
112
113#define STRDESCTBLLEN(prefix, langzero, ...)\
114 sizeof(prefix##_StrDescTbl_##langzero)/sizeof(prefix##_StrDescTbl_##langzero [0])
115
116#define STRDESCTBLREF(prefix, langid, idx,x) prefix##_StrDescTbl_##x,
117#define STRDESCTBL(prefix, ...) \
118STRDESCZERO(prefix, __VA_ARGS__)\
119static const StrDescTbl prefix##_StrTbl = { \
120 & prefix##_StrDescZero,\
121 STRDESCTBLLEN(prefix,__VA_ARGS__),\
122 { _UFOR_EACH(STRDESCTBLREF, prefix, 0, __VA_ARGS__)}\
123};
124
125
126
127
128namespace nbrtos {
129namespace USB {
130
131enum eBusSpeed_t {
132 eBusSpeed_Low = 0,
133 eBusSpeed_Full = 1,
134 eBusSpeed_High = 2,
135 eBusSpeed_Super = 3,
136};
137
138enum class eCtlrEvt_t : uint8_t{
139 eCtlrEvt_Pkt = 0,
140 eCtlrEvt_Error = 1,
141 eCtlrEvt_PortChange = 2,
142 eCtlrEvt_FrameList = 3,
143 eCtlrEvt_SysError = 4,
144 eCtlrEvt_AsyncAdv = 5,
145 eCtlrEvt_ResetRxed = 6,
146 eCtlrEvt_SOF = 7,
147 eCtlrEvt_Suspended = 8,
148 eCtlrEvt_ULPI = 10,
149 eCtlrEvt_HostHalted = 12,
150 eCtlrEvt_Reclaim = 13,
151 eCtlrEvt_PeriodicSched = 14,
152 eCtlrEvt_AsyncSched = 15,
153 eCtlrEvt_NAK = 16,
154 eCtlrEvt_Timer0 = 24,
155 eCtlrEvt_Timer1 = 25,
156 eCtlrEvt_MAX_EVENT = eCtlrEvt_Timer1
157};
158
159enum eListSiz_t {
160 eListSiz_1 = 0,
161 eListSiz_2 = 1,
162 eListSiz_4 = 2,
163 eListSiz_8 = 3,
164 eListSiz_16 = 4,
165 eListSiz_32 = 5,
166 eListSiz_64 = 6,
167 eListSiz_128 = 7,
168 eListSiz_256 = 8,
169 eListSiz_512 = 9,
170 eListSiz_1024 = 10,
171 eListSiz_2048 = 11,
172 eListSiz_4096 = 12,
173 eListSiz_8192 = 13,
174 eListSiz_16384 = 14,
175 eListSiz_32768 = 15,
176};
177
178enum class eBusState_t : uint8_t {
179 eBusState_Disconnected = 0x0,
180 eBusState_Powered = 0x1,
181 eBusState_Attached = 0x2,
182 eBusState_Default = 0x3,
183 eBusState_Address = 0x4,
184 eBusState_Configured = 0x5,
185 eBusState_Susp_Power = 0x81,
186 eBusState_Susp_Attached= 0x82,
187 eBusState_Susp_Default = 0x83,
188 eBusState_Susp_Address = 0x84,
189 eBusState_Susp_Config = 0x85,
190};
191
192enum class eTxnState_t : uint8_t {
193 eTxnState_Setup = 0x00;
194};
195
196struct USB_Event_t {
197 uint8_t devAddr;
198 uint8_t epNum;
199 uint8_t ctlrID;
200 eCtlrEvt_t event;
201};
202
203#define USB_TRANSFER_CANCELED 0x8000
204
205// FIXME: Actually define bufPtr_t
206typedef void * bufPtr_t;
207class UHC;
208typedef int (*endpt_rx_cb_t) (uint8_t devAddr, uint8_t endptNum, bufPtr_t pbuf, uint16_t bufLen);
209typedef int (*evt_cb_t) (eCtlrEvt_t event);
210
211struct AllocPoolEl {
212 AllocPoolEl *pNext;
213};
214
215class BaseAllocPool {
216 AllocPoolEl *free_list;
217 bool bInited;
218 public:
219 BaseAllocPool(): free_list(NULL), bInited(false) {}
220 void Init(void *pool, uint32_t poolSize, uint32_t elSize);
221 AllocPoolEl *Get();
222 void Free(AllocPoolEl *pAlloc);
223};
224
225template<class T, int n> class AllocPool {
226 T store[n];
227 BaseAllocPool pool;
228 public:
229 AllocPool<T,n>() { pool.Init((void *)&store, sizeof(T)*n, sizeof(T)); }
230 inline T *Get() { return (T *)pool.Get(); }
231 void Free(T *t) { pool.Free((AllocPoolEl *)t); }
232};
233
234// Forward declarations
235// String descriptors are UTF-16 encoded
236struct StringDescriptorTmpl {
237 const char16_t *pData;
238 eLangID_t id_Lang;
239 uint8_t len;
240};
241
242#define StrDescTmplTbl(tblName) StringDescriptorTmpl tblName[] = {
243#define StrDescTmpl(value, langID) {value, langID, sizeof(value)-1}
244#define EndDescTmplTbl(tblName) {NULL, 0x0000, 0}};
245
246#define NamedStrDescTmpl(name, value, langID) StringDescriptorTmpl name = StrDescTmpl(value, langID);
247
248struct StringDescriptor {
249 enum eChainType_t {
250 eChain_None = 1,
251 eChain_TmplTbl = 2,
252 eChain_Linked = 3,
253 };
254 StringDescriptor *pNext;
255 union {
256 StringDescriptorTmpl *tmpl;
257 uint32_t skipCount;
258 };
259 eChainType_t chain;
260 StringDescriptor(StringDescriptorTmpl *tmplTbl, int tblLen);
261 StringDescriptor(const StringDescriptor &cpyFrom);
262
263 const char *c_str() const;
264};
265#define BasicStrDesc(descName, langID, value) \
266 StrDescTmpl(descName##_Tmpl,langID, value) \
267 StringDescriptor descName(descName##_Tmpl,1);
268
269typedef char16_t strDescChar_t;
270
271enum class eStrEnc_t : uint8_t {
272 eStrEnc_ASCII = 0,
273 eStrEnc_UTF8 = 1,
274 eStrEnc_UTF16 = 2,
275 eStrEnc_UTF32 = 3
276};
277
278struct StrDesc {
279 eStrEnc_t enc;
280 uint8_t len;
281 union {
282 char val8[];
283 char16_t val16[];
284 char32_t val32[];
285 strDescChar_t val[];
286 };
287};
288typedef const StrDesc *pcStrDesc;
289
290struct StrDescTbl {
291 const usb_desc_str_zero_t *langTbl;
292 uint8_t descCount;
293 const pcStrDesc *tbl[];
294};
295
296class Ctlr;
297class DeviceEP;
298class DeviceIntf;
299
300class Device {
301 public:
302 // This class is a protection method for allowing access to specific
303 // methods without making the allowed classes able to access all private
304 // members.
305 class StallReqKey {
306 friend class DeviceEP;
307 friend class DeviceIntf;
308 StallReqKey();
309 };
310 class FlushReqKey {
311 friend class DeviceEP;
312 friend class DeviceIntf;
313 FlushReqKey();
314 };
315
316 protected:
317 Device *pNext;
318 Ctlr *parent;
319 DeviceIntf *intf[USB_MAX_INTF_PER_DEVICE];
320 DeviceEP *endpt[USB_MAX_ENDPTS_PER_DEVICE * 2];
321 const usb_cfg_t *cfg;
322 const usb_other_spd_t *spdCfg;
323 const StrDescTbl *strTbl;
324
325 usb_dev_t desc;
326 usb_dev_qual_t qual;
327
328 eBusState_t busState;
329 uint8_t txnState;
330 uint8_t txnSubState;
331 uint8_t addr;
332 uint8_t activeCfg;
333
334 uint8_t numEndpts;
335 protected:
336
337 public:
338
339 Device(Ctlr *_parent, const usb_dev_t *_desc, const usb_cfg_t *_cfg, const StrDescTbl *_strTbl);
340 void SetOtherSpd(usb_dev_qual_t *oqual, usb_other_spd_t *ospdCfg);
341 void ClrOtherSpd();
342 void AssignCtlr(Ctlr *newParent);
343
344 void SwapSpeeds();
345
346 PoolPtr GetDesc(uint16_t wValue, uint16_t wIndex, uint16_t wLength);
347 const StrDesc *GetStr(uint16_t lang_id, uint8_t idx);
348 uint8_t GetNextEndPt(uint8_t curEndPt);
349 virtual uint16_t GetMaxPktSize(uint8_t epnum, eDir_t dir) = 0;
350
351 virtual void Event_BusReset();
352 virtual void Event_Suspend();
353 virtual void Event_Resume();
354 virtual void Event_StartOfFrame();
355 virtual int Event_ControlMsg(bufPtr_t ctlMsg, uint8_t bufLen);
356 virtual int SetConfiguration(uint16_t wValue);
357 virtual int SetAltSetting(uint16_t wIndex, uint16_t wValue);
358 virtual int SetDevAddr(uint8_t devAddr, Device *dev);
359 virtual void StallEP(uint8_t epnum, eDir_t dir, Dev::StallReqKey key);
360 virtual void FlushEP(uint8_t epnum, Dev::FlushReqKey key);
361
362 virtual uint16_t GetStatus(eReqTarget_t target, uint16_t wIndex, int *err);
363 virtual uint8_t GetActiveConfig(int *err) = 0;
364 virtual uint8_t GetAltSetting(uint8_t intfNum, int *err) = 0;
365 uint8_t GetDevAddr();
366 uint8_t GetNumEPs();
367
368 eBusState_t GetUSBState();
369 void SetUSBState(eBusState_t newState);
370
371 void SetNext(Device *dev);
372 Device *GetNext();
373
374 virtual int ProcessBuffer(uint8_t epnum, PoolPtr pp, uint16_t bufLen);
375 virtual int ProcessSetupPkt(uint8_t epnum, usb_setup_pkt_t msg);
376
377 virtual int TransmitBuffer(uint8_t epnum, PoolPtr pp);
378 virtual int SendZLP(uint8_t epnum
379};
380
381typedef int (*endPtCB_t) (Device *dev, uint8_t ep, PoolPtr pp, uint16_t bufLen);
382typedef int (*suspCB_t) (Device *dev, bool suspendState);
383
384class DeviceEP;
385
386class DeviceIntf {
387 Device *pDev;
388 DeviceIntf *pNext;
389 DeviceEP *endpt[USB_MAX_ENDPTS_PER_INTF];
390
391 uint8_t intfnum;
392 uint8_t txnState;
393 uint8_t txnSubState;
394public:
395 bool IsDestIntf(uint8_t epnum);
396 virtual int ProcessSetupPkt(uint8_t epnum, usb_setup_pkt_t msg);
397 virtual int ProcessBuffer(uint8_t epnum, PoolPtr pp, uint16_t bufLen);
398};
399
400class DeviceEP {
401 uint8_t epnum;
402 Device *pDev;
403 uint8_t txnState;
404 uint8_t txnSubState;
405
406 uint8_t SetEPNum(uint8_t newepNum);
407public:
408 DeviceEP(uint8_t epnum);
409 inline uint8_t GetEPNum() { return epnum; }
410 virtual int ProcessSetupPkt(usb_setup_pkt_t msg);
411 virtual int ProcessBuffer(PoolPtr pp, uint16_t bufLen);
412};
413
414struct EndPt_t {
415 endPtCB_t fnCB;
416 eEndPt_t type;
417 bool inUse;
418};
419
420// USB Controller
421// This is a *Hardware* abstraction. It shall have no knowledge or influence on
422// the logical operations of either a host or a device controller implementation.
423// It shall simply implement the required hardware methods to allow a device or
424// host to function through the abstracted hardware.
425class Ctlr {
426 public StallReqKey {
427 friend class Device;
428 friend class DeviceEP;
429 StallReqKey() {}
430 };
431 class FlushReqKey {
432 friend class DeviceEP;
433 friend class DeviceIntf;
434 FlushReqKey();
435 };
436 friend void UserMain(void *pd);
437protected:
438 int maxEndpts;
439 int currEndpts;
440// eType_t;
441// eState_t state;
442 evt_cb_t EventCB[(uint8_t)eCtlrEvt_t::eCtlrEvt_MAX_EVENT];
443
444 uint8_t ctlrID;
445protected:
446 virtual int initInTransfer(uint8_t epnum, uint8_t* data, uint16_t length, bool irqOnComplete, bool dontblock = false) = 0;
447 virtual int initInTransfer(uint8_t epnum, PoolPtr pp, bool irqOnComplete, bool dontblock = false) = 0;
448 virtual int initOutTransfer(uint8_t epnum, bool irqOnComplete, bool dontblock = false) = 0;
449
450public:
451 inline uint8_t getID() { return ctlrID; }
452 evt_cb_t RegisterEventHandler(eCtlrEvt_t event, evt_cb_t eventCB) = 0;
453 virtual void DoEvent(USB_Event_t event) = 0;
454 virtual int ProcessBuffer(uint8_t devAddr, uint8_t epnum, PoolPtr pp) = 0;
455 virtual int RegisterDevice(uint8_t devAddr, Device *dev) = 0;
456 virtual int RegisterEP(uint8_t devAddr, uint8_t epnum, eDir_t dir, eEndPt_t type,
457 uint16_t maxPktSize, endPtCB_t fnCB) = 0;
458 virtual int ReleaseEP(uint8_t devAddr, uint8_t epnum, eDir_t dir) = 0;
459
460 virtual void StallEP(uint8_t devAddr, uint8_t epnum, Ctlr::StallReqKey key) = 0;
461 virtual void FlushEP(uint8_t devAddr, uint8_t epnum, Ctlr::FlushReqKey key) = 0;
462
463 virtual int TransmitBuffer(uint8_t devAddr, uint8_t ep, PoolPtr pp) = 0;
464 virtual int SendZLP(uint8_t devAddr, uint8_t epnum) = 0;
465
466 int ConfigureUSBTimer(int timer, uint32_t uSecs, bool bRepeat) = 0;
467 int StopUSBTimer(int timer) = 0;
468 virtual int SetDevAddr(uint8_t devAddr, Device *dev) = 0;
469};
470
471// USB Device Controller
472class UDC : public Ctlr {
473protected:
474 Device *dev;
475 EndPt_t endpt[USB_MAX_ENDPTS_PER_CTRLR*2];
476 suspCB_t suspCB;
477
478public:
479 virtual void Init(Device *Dev) = 0;
480 virtual int ProcessSetupPkt(uint8_t devAddr, uint8_t epnum, usb_setup_pkt_t msg) = 0;
481};
482
483// USB Host Controller
484class UHC : public Ctlr {
485
486public:
487 virtual void Init();
488 int SendToDevice(uint8_t devAddr, uint8_t endpt, void *buf, int datLen);
489 virtual int TransmitBuffer(uint8_t devAddr, uint8_t ep, PoolPtr pp);
490};
491
492class UOTGC : public UDC, public UHC {
493
494public:
495 virtual void Init();
496};
497
498}
499}
500#endif
501#endif /* ----- #ifndef __NB_USB_H ----- */
Definition MIMXRT10xx/include/usb.h:206