/* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error, fe USB xfer timeout */ uint8_t UsbHost_::inTransfer( uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data) { EpInfo *pep = NULL; uint16_t nak_limit = 0; uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit); if (rcode) return rcode; return InTransfer(pep, nak_limit, nbytesptr, data); }
/* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error, fe USB xfer timeout */ uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data) { EpInfo *pep = NULL; uint16_t nak_limit = 0; uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit); if (rcode) { //printf("SetAddress Failed"); return rcode; } return InTransfer(pep, nak_limit, nbytesptr, data); }
/* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error, fe USB xfer timeout */ uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) { EpInfo *pep = NULL; uint16_t nak_limit = 0; uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit); if (rcode) { USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81); USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81); USBTRACE3("(USB::InTransfer) ep requested ", ep, 0x81); return rcode; } return InTransfer(pep, nak_limit, nbytesptr, data, bInterval); }
/* 01-0f = non-zero HRSLT */ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) { bool direction = false; //request direction, IN or OUT uint8_t rcode; SETUP_PKT setup_pkt; EpInfo *pep = NULL; uint16_t nak_limit = 0; rcode = SetAddress(addr, ep, &pep, nak_limit); if(rcode) return rcode; direction = ((bmReqType & 0x80) > 0); /* fill in setup packet */ setup_pkt.ReqType_u.bmRequestType = bmReqType; setup_pkt.bRequest = bRequest; setup_pkt.wVal_u.wValueLo = wValLo; setup_pkt.wVal_u.wValueHi = wValHi; setup_pkt.wIndex = wInd; setup_pkt.wLength = total; bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet if(rcode) //return HRSLT if not zero return ( rcode); if(dataptr != NULL) //data stage, if present { if(direction) //IN transfer { uint16_t left = total; pep->bmRcvToggle = 1; //bmRCVTOG1; while(left) { // Bytes read into buffer uint16_t read = nbytes; //uint16_t read = (left<nbytes) ? left : nbytes; rcode = InTransfer(pep, nak_limit, &read, dataptr); if(rcode == hrTOGERR) { // yes, we flip it wrong here so that next time it is actually correct! pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1; continue; } if(rcode) return rcode; // Invoke callback function if inTransfer completed successfully and callback function pointer is specified if(!rcode && p) ((USBReadParser*)p)->Parse(read, dataptr, total - left); left -= read; if(read < nbytes) break; } } else //OUT transfer { pep->bmSndToggle = 1; //bmSNDTOG1; rcode = OutTransfer(pep, nak_limit, nbytes, dataptr); } if(rcode) //return error return ( rcode); } // Status stage return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); //GET if direction }
/* 01-0f = non-zero HRSLT */ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) { bool direction = false; //request direction, IN or OUT uint8_t rcode; SETUP_PKT setup_pkt; USB_OTG_CORE_HANDLE *pdev = coreConfig; URB_STATE URB_Status = URB_IDLE; EpInfo *pep = NULL; uint16_t nak_limit = 0; /* the address are set by HC functions as 0*/ rcode = SetAddress(addr, ep, &pep, nak_limit); if (rcode) return rcode; direction = ((bmReqType & 0x80) > 0); /* fill in setup packet */ setup_pkt.ReqType_u.bmRequestType = bmReqType; setup_pkt.bRequest = bRequest; setup_pkt.wVal_u.wValueLo = wValLo; setup_pkt.wVal_u.wValueHi = wValHi; setup_pkt.wIndex = wInd; setup_pkt.wLength = total; // bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO // *pep points to EP0 (HC0-out, HC1-in) if(addr != 0) { // in case hid->setAddr() called, we should reset or reuse hid's addr. suck.. if(pdev->host.hc[pep->hcNumOut].dev_addr != addr) pdev->host.hc[pep->hcNumOut].dev_addr = addr; //USBH_Modify_Channel (pdev, pep->hcNumOut, addr, 0, 0, 0, 0); if(pdev->host.hc[pep->hcNumIn].dev_addr != addr) pdev->host.hc[pep->hcNumIn].dev_addr = addr; //USBH_Modify_Channel (pdev, pep->hcNumIn, addr, 0, 0, 0, 0); } rcode = dispatchPkt(tokSETUP, ep, nak_limit, (uint8_t *)&setup_pkt, sizeof(setup_pkt), pep->hcNumOut); //dispatch packet if (rcode) //return HRSLT if not zero return ( rcode); if (dataptr != NULL) //data stage, if present { if (direction) //IN transfer { uint16_t left = total; #if 1 //pep->bmRcvToggle = 1; //bmRCVTOG1; pdev->host.hc[pep->hcNumIn].toggle_in = 0x1; pep->bmRcvToggle = pdev->host.hc[pep->hcNumIn].toggle_in; uint16_t read = total; //nbytes; rcode = InTransfer(pep, nak_limit, &read, dataptr); // Invoke callback function if inTransfer completed successfully and callback function pointer is specified if (!rcode && p) ((USBReadParser*)p)->Parse(read, dataptr, total - left); #else while (left) { // Bytes read into buffer uint16_t read = nbytes; //uint16_t read = (left<nbytes) ? left : nbytes; pdev->host.hc[pep->hcNumIn].toggle_in = 0x1; rcode = InTransfer(pep, nak_limit, &read, dataptr); /* if (rcode == hrTOGERR) { // yes, we flip it wrong here so that next time it is actually correct! pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1; continue; } */ if (rcode) return rcode; // Invoke callback function if inTransfer completed successfully and callback function pointer is specified if (!rcode && p) ((USBReadParser*)p)->Parse(read, dataptr, total - left); left -= read; if (read < nbytes) break; } #endif } else //OUT transfer { //pep->bmSndToggle = 1; //bmSNDTOG1; pdev->host.hc[pep->hcNumOut].toggle_out = 0x1; pep->bmSndToggle = pdev->host.hc[pep->hcNumOut].toggle_out; rcode = OutTransfer(pep, nak_limit, nbytes, dataptr); } if (rcode) //return error return ( rcode); } // Status stage return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit, NULL, 0, (direction) ? pep->hcNumOut : pep->hcNumIn); //GET if direction }