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 {