115#include <usb_lib_cfg.h>
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__)
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
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,
164#define QUALIFIER(X) X::
165#define OPEN_NS(X) namespace X {
168#define QUALIFIED(NAME,...) _UFOR_EACH(QUALIFIER,__VA_ARGS__)NAME
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 \
175#define STRDESCLANGTBLREF_VAL(prefix, langid, idx,x) & prefix##_StrDesc_##langid##_##idx,
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__)\
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__)}\
191#define STRDESCTBLLEN(prefix, langzero, ...)\
192 sizeof(prefix##_StrDescTbl_##langzero)/sizeof(prefix##_StrDescTbl_##langzero [0])
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__)}\
216enum class eCtlrEvt_t : uint8_t{
219 eCtlrEvt_PortChange = 2,
220 eCtlrEvt_FrameList = 3,
221 eCtlrEvt_SysError = 4,
222 eCtlrEvt_AsyncAdv = 5,
223 eCtlrEvt_ResetRxed = 6,
225 eCtlrEvt_Suspended = 8,
227 eCtlrEvt_HostHalted = 12,
228 eCtlrEvt_Reclaim = 13,
229 eCtlrEvt_PeriodicSched = 14,
230 eCtlrEvt_AsyncSched = 15,
232 eCtlrEvt_Timer0 = 24,
233 eCtlrEvt_Timer1 = 25,
234 eCtlrEvt_MAX_EVENT = eCtlrEvt_Timer1
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,
277#define USB_TRANSFER_CANCELED 0x8000
280typedef void * bufPtr_t;
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);
290 AllocPoolEl *free_list;
293 BaseAllocPool(): free_list(NULL), bInited(false) {}
294 void Init(
void *pool, uint32_t poolSize, uint32_t elSize);
296 void Free(AllocPoolEl *pAlloc);
299template<
class T,
int n>
class AllocPool {
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); }
310struct StringDescriptorTmpl {
311 const char16_t *pData;
316#define StrDescTmplTbl(tblName) StringDescriptorTmpl tblName[] = {
317#define StrDescTmpl(value, langID) {value, langID, sizeof(value)-1}
318#define EndDescTmplTbl(tblName) {NULL, 0x0000, 0}};
320#define NamedStrDescTmpl(name, value, langID) StringDescriptorTmpl name = StrDescTmpl(value, langID);
322struct StringDescriptor {
328 StringDescriptor *pNext;
330 StringDescriptorTmpl *tmpl;
334 StringDescriptor(StringDescriptorTmpl *tmplTbl,
int tblLen);
335 StringDescriptor(
const StringDescriptor &cpyFrom);
337 const char *c_str()
const;
339#define BasicStrDesc(descName, langID, value) \
340StrDescTmpl(descName##_Tmpl,langID, value) \
341StringDescriptor descName(descName##_Tmpl,1);
343typedef char16_t strDescChar_t;
345enum class eStrEnc_t : uint8_t {
357typedef const StrDesc *pcStrDesc;
359struct StrDescTblBlock {
360 StrDescTblBlock *pNext;
362 uint16_t descIdx[16];
367 const usb_desc_str_zero_t *langTbl;
369 const StrDesc **tbl[];
371 pcStrDesc GetDesc(uint8_t descnum);
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);
383 endPtCB_t ProcessBuffer;
384 endPtSetupCB_t ProcessSetupPkt;
408 const usb_cfg_t *cfg;
409 const usb_other_spd_t *spdCfg;
412 EndPt_t *endpt[USB_MAX_ENDPTS_PER_DEVICE * 2];
413 const usb_cfg_t *pActiveCfg;
414 const StrDescTbl *strTbl;
419 eBusState_t busState;
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)
433 txnSubState = substate;
434 return (((uint16_t)txnState) << 8) | txnSubState;
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);
442 void AssignCtlr(Ctlr *newParent);
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;
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);
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();
471 eBusState_t GetUSBState();
472 void SetUSBState(eBusState_t newState);
474 void SetNext(Device *dev);
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);
481 virtual int TransmitBuffer(uint8_t epnum,
PoolPtr pp);
500 class InTransferKey {
504 class OutTransferKey {
513 evt_cb_t EventCB[(uint8_t)eCtlrEvt_t::eCtlrEvt_MAX_EVENT];
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;
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;
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);
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;
544 virtual int InAvail(uint8_t epnum) = 0;
545 virtual int OutAvail(uint8_t epnum) = 0;
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;
552inline int Device::initInTransfer(uint8_t epnum,
PoolPtr pp,
bool irqOnComplete,
bool dontblock)
553{
return parent->initInTransfer(epnum, pp, irqOnComplete, dontblock, Ctlr::InTransferKey{});}
555inline int Device::initOutTransfer(uint8_t epnum,
bool irqOnComplete,
bool dontblock)
556{
return parent->initOutTransfer(epnum, irqOnComplete, dontblock, Ctlr::OutTransferKey{});}
559class UDC :
public Ctlr {
562 EndPt_t endpt[USB_MAX_ENDPTS_PER_CTRLR*2];
566 virtual void Init(Device *Dev) = 0;
568 int RegisterDevice(uint8_t devAddr, Device *_dev);
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);
574 virtual void DoEvent(USB_Event_t event);
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);
582class UHC :
public Ctlr {
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);
590class UOTGC :
public UDC,
public UHC {
Main buffer structure for network and serial communication.
Definition buffers.h:90