本文整理汇总了C++中regRd函数的典型用法代码示例。如果您正苦于以下问题:C++ regRd函数的具体用法?C++ regRd怎么用?C++ regRd使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了regRd函数的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: regRd
/* probe bus to determine device presense and speed and switch host to this speed */
void MAX3421E::busprobe( void )
{
byte bus_sample;
bus_sample = regRd( rHRSL ); //Get J,K status
bus_sample &= ( bmJSTATUS|bmKSTATUS ); //zero the rest of the byte
switch( bus_sample ) { //start full-speed or low-speed host
case( bmJSTATUS ):
if(( regRd( rMODE ) & bmLOWSPEED ) == 0 ) {
regWr( rMODE, MODE_FS_HOST ); //start full-speed host
vbusState = FSHOST;
}
else {
regWr( rMODE, MODE_LS_HOST); //start low-speed host
vbusState = LSHOST;
}
break;
case( bmKSTATUS ):
if(( regRd( rMODE ) & bmLOWSPEED ) == 0 ) {
regWr( rMODE, MODE_LS_HOST ); //start low-speed host
vbusState = LSHOST;
}
else {
regWr( rMODE, MODE_FS_HOST ); //start full-speed host
vbusState = FSHOST;
}
break;
case( bmSE1 ): //illegal state
vbusState = MAXSE1;
break;
case( bmSE0 ): //disconnected state
regWr( rMODE, bmDPPULLDN|bmDMPULLDN|bmHOST|bmSEPIRQ);
vbusState = MAXSE0;
break;
}//end switch( bus_sample )
}
示例2: regWr
/* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error,
fe USB xfer timeout */
byte USB::inTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit )
{
byte rcode;
byte pktsize;
byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize;
unsigned int xfrlen = 0;
regWr( rHCTL, devtable[ addr ].epinfo[ ep ].rcvToggle ); //set toggle value
while( 1 ) { // use a 'return' to exit this loop
rcode = dispatchPkt( tokIN, ep, nak_limit ); //IN packet to EP-'endpoint'. Function takes care of NAKS.
if( rcode ) {
return( rcode ); //should be 0, indicating ACK. Else return error code.
}
/* check for RCVDAVIRQ and generate error if not present */
/* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) {
return ( 0xf0 ); //receive error
}
pktsize = regRd( rRCVBC ); //number of received bytes
data = bytesRd( rRCVFIFO, pktsize, data );
regWr( rHIRQ, bmRCVDAVIRQ ); // Clear the IRQ & free the buffer
xfrlen += pktsize; // add this packet's byte count to total transfer length
/* The transfer is complete under two conditions: */
/* 1. The device sent a short packet (L.T. maxPacketSize) */
/* 2. 'nbytes' have been transferred. */
if (( pktsize < maxpktsize ) || (xfrlen >= nbytes )) { // have we transferred 'nbytes' bytes?
if( regRd( rHRSL ) & bmRCVTOGRD ) { //save toggle value
devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG1;
}
else {
devtable[ addr ].epinfo[ ep ].rcvToggle = bmRCVTOG0;
}
return( 0 );
}
}//while( 1 )
}
示例3: millis
/* major part of this function borrowed from code shared by Richard Ibbotson */
byte USB::outTransfer( byte addr, byte ep, unsigned int nbytes, char* data, unsigned int nak_limit )
{
byte rcode, retry_count;
char* data_p = data; //local copy of the data pointer
unsigned int bytes_tosend, nak_count;
unsigned int bytes_left = nbytes;
byte maxpktsize = devtable[ addr ].epinfo[ ep ].MaxPktSize;
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
if (!maxpktsize) { //todo: move this check close to epinfo init. Make it 1< pktsize <64
return 0xFE;
}
regWr( rHCTL, devtable[ addr ].epinfo[ ep ].sndToggle ); //set toggle value
while( bytes_left ) {
retry_count = 0;
nak_count = 0;
bytes_tosend = ( bytes_left >= maxpktsize ) ? maxpktsize : bytes_left;
bytesWr( rSNDFIFO, bytes_tosend, data_p ); //filling output FIFO
regWr( rSNDBC, bytes_tosend ); //set number of bytes
regWr( rHXFR, ( tokOUT | ep )); //dispatch packet
while(!(regRd( rHIRQ ) & bmHXFRDNIRQ )); //wait for the completion IRQ
regWr( rHIRQ, bmHXFRDNIRQ ); //clear IRQ
rcode = ( regRd( rHRSL ) & 0x0f );
while( rcode && ( timeout > millis())) {
switch( rcode ) {
case hrNAK:
nak_count++;
if( nak_limit && ( nak_count == USB_NAK_LIMIT )) {
return( rcode); //return NAK
}
break;
case hrTIMEOUT:
retry_count++;
if( retry_count == USB_RETRY_LIMIT ) {
return( rcode ); //return TIMEOUT
}
break;
default:
return( rcode );
}//switch( rcode...
/* process NAK according to Host out NAK bug */
regWr( rSNDBC, 0 );
regWr( rSNDFIFO, *data_p );
regWr( rSNDBC, bytes_tosend );
regWr( rHXFR, ( tokOUT | ep )); //dispatch packet
while(!(regRd( rHIRQ ) & bmHXFRDNIRQ )); //wait for the completion IRQ
regWr( rHIRQ, bmHXFRDNIRQ ); //clear IRQ
rcode = ( regRd( rHRSL ) & 0x0f );
}//while( rcode && ....
bytes_left -= bytes_tosend;
data_p += bytes_tosend;
}//while( bytes_left...
devtable[ addr ].epinfo[ ep ].sndToggle = ( regRd( rHRSL ) & bmSNDTOGRD ) ? bmSNDTOG1 : bmSNDTOG0; //update toggle
return( rcode ); //should be 0 in all cases
}
示例4: regWr
uint8_t UsbHost_::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data)
{
uint8_t rcode = 0;
uint8_t pktsize;
uint16_t nbytes = *nbytesptr;
uint8_t maxpktsize = pep->maxPktSize;
*nbytesptr = 0;
regWr( rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0 ); //set toggle value
while( 1 ) // use a 'return' to exit this loop
{
rcode = dispatchPkt( tokIN, pep->epAddr, nak_limit ); //IN packet to EP-'endpoint'. Function takes care of NAKS.
if( rcode ) {
#if 0
if ((rcode != 0x04) && (rcode != 0x0d)) {
USBTRACE2("\ndispatchPkt error: ", rcode);
}
#endif
return( rcode ); //should be 0, indicating ACK. Else return error code.
}
/* check for RCVDAVIRQ and generate error if not present */
/* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 )
return ( 0xf0 ); //receive error
pktsize = regRd( rRCVBC ); //number of received bytes
assert(pktsize <= nbytes);
int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
if (mem_left < 0)
mem_left = 0;
data = bytesRd( rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data );
regWr( rHIRQ, bmRCVDAVIRQ ); // Clear the IRQ & free the buffer
*nbytesptr += pktsize; // add this packet's byte count to total transfer length
/* The transfer is complete under two conditions: */
/* 1. The device sent a short packet (L.T. maxPacketSize) */
/* 2. 'nbytes' have been transferred. */
if (( pktsize < maxpktsize ) || (*nbytesptr >= nbytes )) // have we transferred 'nbytes' bytes?
{
// Save toggle value
pep->bmRcvToggle = (( regRd( rHRSL ) & bmRCVTOGRD )) ? 1 : 0;
return( 0 );
} // if
} //while( 1 )
}
示例5: while
/* return codes 0x00-0x0F are HRSLT( 0x00 being success ), 0xFF means timeout */
uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
uint8_t tmpdata;
uint8_t rcode = hrSUCCESS;
uint8_t retry_count = 0;
uint16_t nak_count = 0;
while ((int32_t)((uint32_t)millis() - timeout) < 0L) {
#if defined(ESP8266) || defined(ESP32)
yield(); // needed in order to reset the watchdog timer on the ESP8266
#endif
regWr(rHXFR, (token | ep)); //launch the transfer
rcode = USB_ERROR_TRANSFER_TIMEOUT;
while ((int32_t)((uint32_t)millis() - timeout) < 0L) { //wait for transfer completion
#if defined(ESP8266) || defined(ESP32)
yield(); // needed to reset the watchdog timer on the ESP8266
#endif
tmpdata = regRd(rHIRQ);
if (tmpdata & bmHXFRDNIRQ) {
regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
rcode = 0x00;
break;
}
} // while millis() < timeout
//if (rcode != 0x00) //exit if timeout
// return ( rcode);
rcode = (regRd(rHRSL) & 0x0F); //analyze transfer result
switch (rcode) {
case hrNAK:
nak_count++;
if (nak_limit && (nak_count == nak_limit))
return (rcode);
break;
case hrTIMEOUT:
retry_count++;
if (retry_count == USB_RETRY_LIMIT)
return (rcode);
break;
default:
return (rcode);
}
} // while timeout > millis()
return rcode;
}
示例6: millis
/* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */
uint8_t UsbHost_::dispatchPkt( uint8_t token, uint8_t ep, uint16_t nak_limit )
{
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
uint8_t tmpdata;
uint8_t rcode;
uint8_t retry_count = 0;
uint16_t nak_count = 0;
while( timeout > millis() )
{
regWr( rHXFR, ( token|ep )); //launch the transfer
rcode = USB_ERROR_TRANSFER_TIMEOUT;
while( millis() < timeout ) //wait for transfer completion
{
tmpdata = regRd( rHIRQ );
if( tmpdata & bmHXFRDNIRQ )
{
regWr( rHIRQ, bmHXFRDNIRQ ); //clear the interrupt
rcode = 0x00;
break;
}//if( tmpdata & bmHXFRDNIRQ
}//while ( millis() < timeout
if( rcode != 0x00 ) //exit if timeout
return( rcode );
rcode = ( regRd( rHRSL ) & 0x0f ); //analyze transfer result
switch( rcode )
{
case hrNAK:
nak_count ++;
if( nak_limit && ( nak_count == nak_limit ))
return( rcode );
break;
case hrTIMEOUT:
retry_count ++;
if( retry_count == USB_RETRY_LIMIT )
return( rcode );
break;
default:
return( rcode );
}//switch( rcode
}//while( timeout > millis()
return( rcode );
}
示例7: USBTRACE2
uint8_t UsbHost_::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_limit)
{
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
if (!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo)
return USB_ERROR_EPINFO_IS_NULL;
*ppep = getEpInfoEntry(addr, ep);
if (!*ppep)
return USB_ERROR_EP_NOT_FOUND_IN_TBL;
nak_limit = (0x0001UL << ( ( (*ppep)->bmNakPower > USB_NAK_MAX_POWER ) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower) );
nak_limit--;
/*
USBTRACE2("\r\nAddress: ", addr);
USBTRACE2(" EP: ", ep);
USBTRACE2(" NAK Power: ",(*ppep)->bmNakPower);
USBTRACE2(" NAK Limit: ", nak_limit);
USBTRACE("\r\n");
*/
regWr( rPERADDR, addr ); //set peripheral address
uint8_t mode = regRd( rMODE );
// Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise
regWr( rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED));
return 0;
}
示例8: regWr
/* reset MAX3421E using chip reset bit. SPI configuration is not affected */
boolean MAX3421E::reset()
{
unsigned short tmp = 0;
regWr( rUSBCTL, bmCHIPRES ); //Chip reset. This stops the oscillator
regWr( rUSBCTL, 0x00 ); //Remove the reset
while(!(regRd( rUSBIRQ ) & bmOSCOKIRQ )) { //wait until the PLL is stable
tmp++; //timeout after 256 attempts
if( tmp == 0 ) {
return( false );
}
}
return( true );
}
示例9: regWr
uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data) {
uint8_t rcode = 0;
uint8_t pktsize;
uint16_t nbytes = *nbytesptr;
//printf("Requesting %i bytes ", nbytes);
uint8_t maxpktsize = pep->maxPktSize;
*nbytesptr = 0;
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
// use a 'break' to exit this loop
while(1) {
rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS.
if(rcode == hrTOGERR) {
// yes, we flip it wrong here so that next time it is actually correct!
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
continue;
}
if(rcode) {
//printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
break; //should be 0, indicating ACK. Else return error code.
}
/* check for RCVDAVIRQ and generate error if not present */
/* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */
if((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
//printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
rcode = 0xf0; //receive error
break;
}
pktsize = regRd(rRCVBC); //number of received bytes
//printf("Got %i bytes \r\n", pktsize);
// This would be OK, but...
//assert(pktsize <= nbytes);
if(pktsize > nbytes) {
// This can happen. Use of assert on Arduino locks up the Arduino.
// So I will trim the value, and hope for the best.
//printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize);
pktsize = nbytes;
}
int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
if(mem_left < 0)
mem_left = 0;
data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data);
regWr(rHIRQ, bmRCVDAVIRQ); // Clear the IRQ & free the buffer
*nbytesptr += pktsize; // add this packet's byte count to total transfer length
/* The transfer is complete under two conditions: */
/* 1. The device sent a short packet (L.T. maxPacketSize) */
/* 2. 'nbytes' have been transferred. */
if((pktsize < maxpktsize) || (*nbytesptr >= nbytes)) // have we transferred 'nbytes' bytes?
{
// Save toggle value
pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0;
//printf("\r\n");
rcode = 0;
break;
} // if
} //while( 1 )
return ( rcode);
}
示例10: getVbusState
/* USB main task. Performs enumeration/cleanup */
void USB::Task( void ) //USB state machine
{
byte i;
byte rcode;
static byte tmpaddr;
byte tmpdata;
static unsigned long delay = 0;
USB_DEVICE_DESCRIPTOR buf;
tmpdata = getVbusState();
/* modify USB task state if Vbus changed */
switch( tmpdata ) {
case SE1: //illegal state
usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
break;
case SE0: //disconnected
if(( usb_task_state & USB_STATE_MASK ) != USB_STATE_DETACHED ) {
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
}
break;
case FSHOST: //attached
case LSHOST:
if(( usb_task_state & USB_STATE_MASK ) == USB_STATE_DETACHED ) {
delay = millis() + USB_SETTLE_DELAY;
usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
}
break;
}// switch( tmpdata
//Serial.print("USB task state: ");
//Serial.println( usb_task_state, HEX );
switch( usb_task_state ) {
case USB_DETACHED_SUBSTATE_INITIALIZE:
init();
usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
break;
case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
break;
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
break;
case USB_ATTACHED_SUBSTATE_SETTLE: //setlle time for just attached device
if( delay < millis() ) {
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
}
break;
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
regWr( rHCTL, bmBUSRST ); //issue bus reset
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
break;
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
if(( regRd( rHCTL ) & bmBUSRST ) == 0 ) {
tmpdata = regRd( rMODE ) | bmSOFKAENAB; //start SOF generation
regWr( rMODE, tmpdata );
// regWr( rMODE, bmSOFKAENAB );
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
delay = millis() + 20; //20ms wait after reset per USB spec
}
break;
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
if( regRd( rHIRQ ) & bmFRAMEIRQ ) { //when first SOF received we can continue
if( delay < millis() ) { //20ms passed
usb_task_state = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE;
}
}
break;
case USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE:
// toggle( BPNT_0 );
devtable[ 0 ].epinfo->MaxPktSize = 8; //set max.packet size to min.allowed
rcode = getDevDescr( 0, 0, 8, ( char* )&buf );
if( rcode == 0 ) {
devtable[ 0 ].epinfo->MaxPktSize = buf.bMaxPacketSize0;
usb_task_state = USB_STATE_ADDRESSING;
}
else {
usb_error = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE;
usb_task_state = USB_STATE_ERROR;
}
break;
case USB_STATE_ADDRESSING:
for( i = 1; i < USB_NUMDEVICES; i++ ) {
if( devtable[ i ].epinfo == NULL ) {
devtable[ i ].epinfo = devtable[ 0 ].epinfo; //set correct MaxPktSize
//temporary record
//until plugged with real device endpoint structure
rcode = setAddr( 0, 0, i );
if( rcode == 0 ) {
tmpaddr = i;
usb_task_state = USB_STATE_CONFIGURING;
}
else {
usb_error = USB_STATE_ADDRESSING; //set address error
usb_task_state = USB_STATE_ERROR;
}
break; //break if address assigned or error occured during address assignment attempt
}
}//for( i = 1; i < USB_NUMDEVICES; i++
if( usb_task_state == USB_STATE_ADDRESSING ) { //no vacant place in devtable
usb_error = 0xfe;
usb_task_state = USB_STATE_ERROR;
}
//.........这里部分代码省略.........
示例11: SetAddress
/* 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
}
示例12: getVbusState
/* USB main task. Performs enumeration/cleanup */
void USB::Task(void) //USB state machine
{
uint8_t rcode;
uint8_t tmpdata;
static unsigned long delay = 0;
//USB_DEVICE_DESCRIPTOR buf;
bool lowspeed = false;
MAX3421E::Task();
tmpdata = getVbusState();
/* modify USB task state if Vbus changed */
switch(tmpdata) {
case SE1: //illegal state
usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
lowspeed = false;
break;
case SE0: //disconnected
if((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
lowspeed = false;
break;
case LSHOST:
lowspeed = true;
//intentional fallthrough
case FSHOST: //attached
if((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
delay = millis() + USB_SETTLE_DELAY;
usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
}
break;
}// switch( tmpdata
for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
if(devConfig[i])
rcode = devConfig[i]->Poll();
switch(usb_task_state) {
case USB_DETACHED_SUBSTATE_INITIALIZE:
init();
for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
if(devConfig[i])
rcode = devConfig[i]->Release();
usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
break;
case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
break;
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
break;
case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
if(delay < millis())
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
else break; // don't fall through
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
regWr(rHCTL, bmBUSRST); //issue bus reset
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
break;
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
if((regRd(rHCTL) & bmBUSRST) == 0) {
tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
regWr(rMODE, tmpdata);
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
//delay = millis() + 20; //20ms wait after reset per USB spec
}
break;
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
if(regRd(rHIRQ) & bmFRAMEIRQ) {
//when first SOF received _and_ 20ms has passed we can continue
/*
if (delay < millis()) //20ms passed
usb_task_state = USB_STATE_CONFIGURING;
*/
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET;
delay = millis() + 20;
}
break;
case USB_ATTACHED_SUBSTATE_WAIT_RESET:
if(delay < millis()) usb_task_state = USB_STATE_CONFIGURING;
else break; // don't fall through
case USB_STATE_CONFIGURING:
//Serial.print("\r\nConf.LS: ");
//Serial.println(lowspeed, HEX);
rcode = Configuring(0, 0, lowspeed);
if(rcode) {
if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
usb_error = rcode;
usb_task_state = USB_STATE_ERROR;
}
} else
usb_task_state = USB_STATE_RUNNING;
break;
case USB_STATE_RUNNING:
//.........这里部分代码省略.........
示例13: millis
uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data) {
uint8_t rcode = hrSUCCESS, retry_count;
uint8_t *data_p = data; //local copy of the data pointer
uint16_t bytes_tosend, nak_count;
uint16_t bytes_left = nbytes;
uint8_t maxpktsize = pep->maxPktSize;
if(maxpktsize < 1 || maxpktsize > 64)
return USB_ERROR_INVALID_MAX_PKT_SIZE;
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
while(bytes_left) {
retry_count = 0;
nak_count = 0;
bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO
regWr(rSNDBC, bytes_tosend); //set number of bytes
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
rcode = (regRd(rHRSL) & 0x0f);
while(rcode && (timeout > millis())) {
switch(rcode) {
case hrNAK:
nak_count++;
if(nak_limit && (nak_count == nak_limit))
goto breakout;
//return ( rcode);
break;
case hrTIMEOUT:
retry_count++;
if(retry_count == USB_RETRY_LIMIT)
goto breakout;
//return ( rcode);
break;
case hrTOGERR:
// yes, we flip it wrong here so that next time it is actually correct!
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
break;
default:
goto breakout;
}//switch( rcode
/* process NAK according to Host out NAK bug */
regWr(rSNDBC, 0);
regWr(rSNDFIFO, *data_p);
regWr(rSNDBC, bytes_tosend);
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
rcode = (regRd(rHRSL) & 0x0f);
}//while( rcode && ....
bytes_left -= bytes_tosend;
data_p += bytes_tosend;
}//while( bytes_left...
breakout:
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle
return ( rcode); //should be 0 in all cases
}