mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
removed digitalRead from usbhost.h
This commit is contained in:
commit
d3a52a7616
6 changed files with 385 additions and 309 deletions
266
Usb.cpp
266
Usb.cpp
|
@ -169,7 +169,12 @@ uint8_t USB::inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t*
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
uint8_t pktsize;
|
uint8_t pktsize;
|
||||||
|
|
||||||
//Serial.println("iT");
|
Serial.print("iT");
|
||||||
|
|
||||||
|
Serial.print(" A:");
|
||||||
|
Serial.print(addr, HEX);
|
||||||
|
Serial.print(" E:");
|
||||||
|
Serial.print(ep, HEX);
|
||||||
|
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
||||||
|
|
||||||
|
@ -181,6 +186,26 @@ uint8_t USB::inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t*
|
||||||
|
|
||||||
EP_RECORD *pep = &p->epinfo[ep];
|
EP_RECORD *pep = &p->epinfo[ep];
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
regWr( rPERADDR, addr ); //set peripheral address
|
||||||
|
|
||||||
|
uint8_t mode = regRd( rMODE );
|
||||||
|
|
||||||
|
//if (p->lowspeed)
|
||||||
|
// regWr( rMODE, mode | bmHUBPRE ); //set HUBPRE = 1 for low speed devices
|
||||||
|
//else
|
||||||
|
// regWr( rMODE, mode & ~bmHUBPRE ); //set HUBPRE = 0 for full speed devices
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(" E:");
|
||||||
|
Serial.print(pep->epAddr, HEX);
|
||||||
|
Serial.print(" M:");
|
||||||
|
Serial.print(pep->MaxPktSize, HEX);
|
||||||
|
Serial.print(" T:");
|
||||||
|
Serial.println(pep->rcvToggle, HEX);
|
||||||
|
|
||||||
uint8_t maxpktsize = pep->MaxPktSize;
|
uint8_t maxpktsize = pep->MaxPktSize;
|
||||||
|
|
||||||
unsigned int xfrlen = 0;
|
unsigned int xfrlen = 0;
|
||||||
|
@ -237,6 +262,18 @@ uint8_t USB::outTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t
|
||||||
if (!p->epinfo)
|
if (!p->epinfo)
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
regWr( rPERADDR, addr ); //set peripheral address
|
||||||
|
|
||||||
|
//uint8_t mode = regRd( rMODE );
|
||||||
|
|
||||||
|
//if (p->lowspeed)
|
||||||
|
// regWr( rMODE, mode | bmHUBPRE ); //set HUBPRE = 1 for low speed devices
|
||||||
|
//else
|
||||||
|
// regWr( rMODE, mode & ~bmHUBPRE ); //set HUBPRE = 0 for full speed devices
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
uint8_t maxpktsize = pep->MaxPktSize;
|
uint8_t maxpktsize = pep->MaxPktSize;
|
||||||
|
|
||||||
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
|
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
|
||||||
|
@ -388,27 +425,34 @@ void USB::Task( void ) //USB state machine
|
||||||
case USB_DETACHED_SUBSTATE_INITIALIZE:
|
case USB_DETACHED_SUBSTATE_INITIALIZE:
|
||||||
Serial.println("INIT");
|
Serial.println("INIT");
|
||||||
init();
|
init();
|
||||||
|
for (uint8_t i=0; i<USB_NUMDEVICES; i++)
|
||||||
|
{
|
||||||
|
if (devConfig[i])
|
||||||
|
{
|
||||||
|
rcode = devConfig[i]->Release();
|
||||||
|
}
|
||||||
|
} //for
|
||||||
usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
|
usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
|
||||||
break;
|
break;
|
||||||
case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
|
case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
|
||||||
Serial.println("WFD");
|
//Serial.println("WFD");
|
||||||
break;
|
break;
|
||||||
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
|
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
|
||||||
Serial.println("ILL");
|
Serial.println("ILL");
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_SETTLE: //setlle time for just attached device
|
case USB_ATTACHED_SUBSTATE_SETTLE: //setlle time for just attached device
|
||||||
Serial.println("STL");
|
//Serial.println("STL");
|
||||||
if( delay < millis() ) {
|
if( delay < millis() ) {
|
||||||
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
|
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
|
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
|
||||||
Serial.println("RES");
|
//Serial.println("RES");
|
||||||
regWr( rHCTL, bmBUSRST ); //issue bus reset
|
regWr( rHCTL, bmBUSRST ); //issue bus reset
|
||||||
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
|
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
|
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
|
||||||
Serial.println("RCOMP");
|
//Serial.println("RCOMP");
|
||||||
if(( regRd( rHCTL ) & bmBUSRST ) == 0 )
|
if(( regRd( rHCTL ) & bmBUSRST ) == 0 )
|
||||||
{
|
{
|
||||||
tmpdata = regRd( rMODE ) | bmSOFKAENAB; //start SOF generation
|
tmpdata = regRd( rMODE ) | bmSOFKAENAB; //start SOF generation
|
||||||
|
@ -418,10 +462,11 @@ void USB::Task( void ) //USB state machine
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
|
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
|
||||||
Serial.println("WSOF");
|
//Serial.println("WSOF");
|
||||||
if( regRd( rHIRQ ) & bmFRAMEIRQ ) { //when first SOF received we can continue
|
if( regRd( rHIRQ ) & bmFRAMEIRQ ) { //when first SOF received we can continue
|
||||||
if( delay < millis() ) { //20ms passed
|
if( delay < millis() ) { //20ms passed
|
||||||
usb_task_state = USB_STATE_ADDRESSING;
|
usb_task_state = USB_STATE_CONFIGURING;
|
||||||
|
//usb_task_state = USB_STATE_ADDRESSING;
|
||||||
//usb_task_state = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE;
|
//usb_task_state = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,20 +474,20 @@ void USB::Task( void ) //USB state machine
|
||||||
case USB_STATE_ADDRESSING:
|
case USB_STATE_ADDRESSING:
|
||||||
Serial.println("ADR");
|
Serial.println("ADR");
|
||||||
|
|
||||||
rcode = Addressing(&tmpaddr);
|
//rcode = Addressing(0, 0, &tmpaddr);
|
||||||
|
|
||||||
if (rcode == hrSUCCESS)
|
//if (rcode == hrSUCCESS)
|
||||||
usb_task_state = USB_STATE_CONFIGURING;
|
// usb_task_state = USB_STATE_CONFIGURING;
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
usb_error = rcode;
|
// usb_error = rcode;
|
||||||
usb_task_state = USB_STATE_ERROR;
|
// usb_task_state = USB_STATE_ERROR;
|
||||||
}
|
//}
|
||||||
break;
|
break;
|
||||||
case USB_STATE_CONFIGURING:
|
case USB_STATE_CONFIGURING:
|
||||||
Serial.print("CNF");
|
Serial.print("CNF");
|
||||||
|
|
||||||
rcode = Configuring(tmpaddr);
|
rcode = Configuring(0, 0);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
{
|
{
|
||||||
|
@ -456,88 +501,74 @@ void USB::Task( void ) //USB state machine
|
||||||
usb_task_state = USB_STATE_RUNNING;
|
usb_task_state = USB_STATE_RUNNING;
|
||||||
break;
|
break;
|
||||||
case USB_STATE_RUNNING:
|
case USB_STATE_RUNNING:
|
||||||
Serial.println("RUN");
|
//Serial.println("RUN");
|
||||||
break;
|
break;
|
||||||
case USB_STATE_ERROR:
|
case USB_STATE_ERROR:
|
||||||
break;
|
break;
|
||||||
} // switch( usb_task_state )
|
} // switch( usb_task_state )
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t USB::Addressing(uint8_t *address)
|
uint8_t USB::DefaultAddressing()
|
||||||
{
|
{
|
||||||
uint8_t rcode = hrSUCCESS, buf[8];
|
uint8_t buf[12];
|
||||||
|
uint8_t rcode;
|
||||||
|
UsbDevice *p = NULL;
|
||||||
|
|
||||||
Serial.println("Adrsng");
|
Serial.println("Dfl");
|
||||||
|
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(0);
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p->epinfo)
|
if (!p->epinfo)
|
||||||
{
|
{
|
||||||
Serial.println("epinfo");
|
Serial.println("epinfo");
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
}
|
}
|
||||||
Serial.print("addr:");
|
|
||||||
Serial.println(p->address, HEX);
|
|
||||||
Serial.print("ep:");
|
|
||||||
Serial.println(p->epinfo->epAddr, HEX);
|
|
||||||
|
|
||||||
//p->epinfo->MaxPktSize = 8;
|
// Allocate new address according to device class
|
||||||
|
uint8_t bAddress = addrPool.AllocAddress(0, false, 0);
|
||||||
|
|
||||||
Serial.print("Max:");
|
if (!bAddress)
|
||||||
Serial.println(p->epinfo->MaxPktSize, HEX);
|
|
||||||
|
|
||||||
rcode = getDevDescr( 0, 0, 8, (uint8_t*)buf );
|
|
||||||
|
|
||||||
if( rcode == 0 )
|
|
||||||
{
|
|
||||||
Serial.println("OK!");
|
|
||||||
p->epinfo->MaxPktSize = ((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
|
||||||
p->devclass = ((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Serial.println("getDevDesc:");
|
|
||||||
return rcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t addr = addrPool.AllocAddress(0, (p->devclass == 0x09) ? true : false);
|
|
||||||
|
|
||||||
if (!addr)
|
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
Serial.print("Addr:");
|
// Assign new address to the device
|
||||||
Serial.println(addr,HEX);
|
rcode = setAddr( 0, 0, bAddress );
|
||||||
|
|
||||||
rcode = setAddr( 0, 0, addr );
|
if (rcode)
|
||||||
|
|
||||||
if (!rcode)
|
|
||||||
{
|
|
||||||
*address = addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
addrPool.FreeAddress(bAddress);
|
||||||
|
bAddress = 0;
|
||||||
Serial.print("setAddr:");
|
Serial.print("setAddr:");
|
||||||
Serial.println(rcode, HEX);
|
Serial.println(rcode, HEX);
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
return rcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USB::Configuring(uint8_t addr)
|
Serial.print("Addr:");
|
||||||
|
Serial.println(bAddress, HEX);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t USB::Configuring(uint8_t parent, uint8_t port)
|
||||||
{
|
{
|
||||||
static uint8_t dev_index = 0;
|
static uint8_t dev_index = 0;
|
||||||
uint8_t rcode = 0, buf[8];
|
uint8_t rcode = 0;
|
||||||
|
|
||||||
for (; devConfigIndex<USB_NUMDEVICES; devConfigIndex++)
|
for (; devConfigIndex<USB_NUMDEVICES; devConfigIndex++)
|
||||||
{
|
{
|
||||||
rcode = devConfig[devConfigIndex]->Init(addr);
|
if (!devConfig[devConfigIndex])
|
||||||
|
continue;
|
||||||
|
|
||||||
Serial.println(".");
|
rcode = devConfig[devConfigIndex]->Init(parent, port);
|
||||||
|
|
||||||
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED)
|
if (!rcode)
|
||||||
|
{
|
||||||
|
devConfigIndex = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE))
|
||||||
{
|
{
|
||||||
// in case of an error dev_index should be reset to 0
|
// in case of an error dev_index should be reset to 0
|
||||||
// in order to start from the very beginning the
|
// in order to start from the very beginning the
|
||||||
|
@ -550,7 +581,12 @@ uint8_t USB::Configuring(uint8_t addr)
|
||||||
}
|
}
|
||||||
// if we get here that means that the device class is not supported by any of registered classes
|
// if we get here that means that the device class is not supported by any of registered classes
|
||||||
devConfigIndex = 0;
|
devConfigIndex = 0;
|
||||||
return 0;
|
rcode = DefaultAddressing();
|
||||||
|
|
||||||
|
if (rcode)
|
||||||
|
Serial.println("Dfl fail");
|
||||||
|
|
||||||
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
//class UsbHub
|
//class UsbHub
|
||||||
|
@ -764,3 +800,105 @@ void USB::PrintHubStatus(/*USB *usbptr,*/ uint8_t addr)
|
||||||
Serial.println((buf[2] & bmHUB_STATUS_C_OVER_CURRENT) > 0, DEC);
|
Serial.println((buf[2] & bmHUB_STATUS_C_OVER_CURRENT) > 0, DEC);
|
||||||
Serial.println("");
|
Serial.println("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined( USB_METHODS_INLINE )
|
||||||
|
//get device descriptor
|
||||||
|
uint8_t USB::getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
//get configuration descriptor
|
||||||
|
uint8_t USB::getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
//get string descriptor
|
||||||
|
uint8_t USB::getStrDescr( uint8_t addr, uint8_t ep, unsigned int nuint8_ts, uint8_t index, unsigned int langid, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
//set address
|
||||||
|
uint8_t USB::setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL, nak_limit ));
|
||||||
|
}
|
||||||
|
//set configuration
|
||||||
|
uint8_t USB::setConf( uint8_t addr, uint8_t ep, uint8_t conf_value, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL, nak_limit ));
|
||||||
|
}
|
||||||
|
//class requests
|
||||||
|
uint8_t USB::setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, NULL, nak_limit ));
|
||||||
|
}
|
||||||
|
uint8_t USB::getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
//get HID report descriptor
|
||||||
|
uint8_t USB::getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
uint8_t USB::setReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
uint8_t USB::getReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, unsigned int nak_limit ) { // ** RI 04/11/09
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
/* returns one byte of data in dataptr */
|
||||||
|
uint8_t USB::getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
uint8_t USB::setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration, unsigned int nak_limit ) {
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL, nak_limit ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// uint8_t ctrlReq(
|
||||||
|
//uint8_t addr,
|
||||||
|
//uint8_t ep,
|
||||||
|
//uint8_t bmReqType,
|
||||||
|
//uint8_t bRequest,
|
||||||
|
//uint8_t wValLo,
|
||||||
|
//uint8_t wValHi,
|
||||||
|
//unsigned int wInd,
|
||||||
|
//unsigned int nbytes,
|
||||||
|
//uint8_t* dataptr,
|
||||||
|
//unsigned int nak_limit = USB_NAK_LIMIT );
|
||||||
|
|
||||||
|
// Clear Hub Feature
|
||||||
|
uint8_t USB::ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit )
|
||||||
|
{
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, NULL, nak_limit ));
|
||||||
|
}
|
||||||
|
// Clear Port Feature
|
||||||
|
uint8_t USB::ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel, unsigned int nak_limit )
|
||||||
|
{
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000|port)|(sel<<8)), 0, NULL, nak_limit ));
|
||||||
|
}
|
||||||
|
// Get Hub Descriptor
|
||||||
|
uint8_t USB::GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr, unsigned int nak_limit )
|
||||||
|
{
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
// Get Hub Status
|
||||||
|
uint8_t USB::GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
||||||
|
{
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
// Get Port Status
|
||||||
|
uint8_t USB::GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
||||||
|
{
|
||||||
|
//Serial.println(bmREQ_GET_PORT_STATUS, BIN);
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
// Set Hub Descriptor
|
||||||
|
uint8_t USB::SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
||||||
|
{
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, dataptr, nak_limit ));
|
||||||
|
}
|
||||||
|
// Set Hub Feature
|
||||||
|
uint8_t USB::SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit )
|
||||||
|
{
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, NULL, nak_limit ));
|
||||||
|
}
|
||||||
|
// Set Port Feature
|
||||||
|
uint8_t USB::SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel, unsigned int nak_limit )
|
||||||
|
{
|
||||||
|
return( ctrlReq( addr, ep, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000|sel)<<8)|port), 0, NULL, nak_limit ));
|
||||||
|
}
|
||||||
|
#endif // !defined(USB_METHODS_INLINE)
|
30
Usb.h
30
Usb.h
|
@ -2,6 +2,8 @@
|
||||||
#ifndef _usb_h_
|
#ifndef _usb_h_
|
||||||
#define _usb_h_
|
#define _usb_h_
|
||||||
|
|
||||||
|
#define USB_METHODS_INLINE
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "avrpins.h"
|
#include "avrpins.h"
|
||||||
#include "max3421e.h"
|
#include "max3421e.h"
|
||||||
|
@ -135,13 +137,22 @@
|
||||||
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL 0xD5
|
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL 0xD5
|
||||||
#define USB_ERROR_EPINFO_IS_NULL 0xD6
|
#define USB_ERROR_EPINFO_IS_NULL 0xD6
|
||||||
#define USB_ERROR_INVALID_ARGUMENT 0xD7
|
#define USB_ERROR_INVALID_ARGUMENT 0xD7
|
||||||
|
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD8
|
||||||
|
|
||||||
|
//class USBDeviceConfig
|
||||||
|
//{
|
||||||
|
//public:
|
||||||
|
// virtual uint8_t Init(uint8_t addr) = 0;
|
||||||
|
// virtual uint8_t Release(uint8_t addr) = 0;
|
||||||
|
// virtual uint8_t Poll() = 0;
|
||||||
|
//};
|
||||||
|
|
||||||
class USBDeviceConfig
|
class USBDeviceConfig
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual uint8_t Init(uint8_t addr) = 0;
|
virtual uint8_t Init(uint8_t parent, uint8_t port) = 0;
|
||||||
virtual uint8_t Release(uint8_t addr) = 0;
|
virtual uint8_t Release() = 0;
|
||||||
virtual uint8_t Poll() = 0;
|
virtual uint8_t Poll() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,6 +261,10 @@ class USB : public MAX3421E
|
||||||
public:
|
public:
|
||||||
USB( void );
|
USB( void );
|
||||||
|
|
||||||
|
AddressPool& GetAddressPool()
|
||||||
|
{
|
||||||
|
return (AddressPool&)addrPool;
|
||||||
|
};
|
||||||
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
|
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
|
||||||
{
|
{
|
||||||
for (uint8_t i=0; i<USB_NUMDEVICES; i++)
|
for (uint8_t i=0; i<USB_NUMDEVICES; i++)
|
||||||
|
@ -319,14 +334,15 @@ class USB : public MAX3421E
|
||||||
|
|
||||||
void Task( void );
|
void Task( void );
|
||||||
|
|
||||||
uint8_t Addressing(uint8_t *address);
|
uint8_t DefaultAddressing();
|
||||||
uint8_t Configuring(uint8_t addr);
|
|
||||||
|
uint8_t Configuring(uint8_t parent, uint8_t port);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(USB_METHODS_INLINE)
|
||||||
//get device descriptor
|
//get device descriptor
|
||||||
inline uint8_t USB::getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit ) {
|
inline uint8_t USB::getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr, nak_limit ));
|
||||||
|
@ -425,4 +441,6 @@ inline uint8_t USB::SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8
|
||||||
{
|
{
|
||||||
return( ctrlReq( addr, ep, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000|sel)<<8)|port), 0, NULL, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000|sel)<<8)|port), 0, NULL, nak_limit ));
|
||||||
}
|
}
|
||||||
|
#endif // defined(USB_METHODS_INLINE)
|
||||||
|
|
||||||
#endif //_usb_h_
|
#endif //_usb_h_
|
12
address.h
12
address.h
|
@ -50,14 +50,16 @@ struct UsbDevice
|
||||||
{
|
{
|
||||||
EP_RECORD *epinfo; // endpoint info pointer
|
EP_RECORD *epinfo; // endpoint info pointer
|
||||||
uint8_t address; // address
|
uint8_t address; // address
|
||||||
|
bool lowspeed; // indicates if a device is the low speed one
|
||||||
uint8_t devclass; // device class
|
uint8_t devclass; // device class
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddressPool
|
class AddressPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual uint8_t AllocAddress(UsbDeviceAddress parent, bool is_hub = false, uint8_t port = 0) = 0;
|
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) = 0;
|
||||||
virtual void FreeAddress(UsbDeviceAddress addr) = 0;
|
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) = 0;
|
||||||
|
virtual void FreeAddress(uint8_t addr) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
|
typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
|
||||||
|
@ -66,7 +68,7 @@ typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
|
||||||
#define ADDR_ERROR_INVALID_ADDRESS 0xFF
|
#define ADDR_ERROR_INVALID_ADDRESS 0xFF
|
||||||
|
|
||||||
template <const uint8_t MAX_DEVICES_ALLOWED>
|
template <const uint8_t MAX_DEVICES_ALLOWED>
|
||||||
class AddressPoolImpl
|
class AddressPoolImpl : public AddressPool
|
||||||
{
|
{
|
||||||
EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device
|
EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device
|
||||||
|
|
||||||
|
@ -79,7 +81,7 @@ class AddressPoolImpl
|
||||||
void InitEntry(uint8_t index)
|
void InitEntry(uint8_t index)
|
||||||
{
|
{
|
||||||
thePool[index].address = 0;
|
thePool[index].address = 0;
|
||||||
thePool[index].devclass = 0;
|
thePool[index].lowspeed = 0;
|
||||||
thePool[index].epinfo = &dev0ep;
|
thePool[index].epinfo = &dev0ep;
|
||||||
};
|
};
|
||||||
// Returns thePool index for a given address
|
// Returns thePool index for a given address
|
||||||
|
@ -146,7 +148,7 @@ public:
|
||||||
InitAllAddresses();
|
InitAllAddresses();
|
||||||
};
|
};
|
||||||
// Returns a pointer to a specified address entry
|
// Returns a pointer to a specified address entry
|
||||||
UsbDevice* GetUsbDevicePtr(uint8_t addr)
|
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr)
|
||||||
{
|
{
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return thePool;
|
return thePool;
|
||||||
|
|
37
usbhost.h
37
usbhost.h
|
@ -209,7 +209,7 @@ int8_t MAX3421e< SS, INTR >::Init()
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
void MAX3421e< SS, INTR >::busprobe()
|
void MAX3421e< SS, INTR >::busprobe()
|
||||||
{
|
{
|
||||||
byte bus_sample;
|
uint8_t bus_sample;
|
||||||
bus_sample = regRd( rHRSL ); //Get J,K status
|
bus_sample = regRd( rHRSL ); //Get J,K status
|
||||||
bus_sample &= ( bmJSTATUS|bmKSTATUS ); //zero the rest of the byte
|
bus_sample &= ( bmJSTATUS|bmKSTATUS ); //zero the rest of the byte
|
||||||
switch( bus_sample ) { //start full-speed or low-speed host
|
switch( bus_sample ) { //start full-speed or low-speed host
|
||||||
|
@ -249,14 +249,15 @@ uint8_t MAX3421e< SS, INTR >::Task( void )
|
||||||
uint8_t pinvalue;
|
uint8_t pinvalue;
|
||||||
//Serial.print("Vbus state: ");
|
//Serial.print("Vbus state: ");
|
||||||
//Serial.println( vbusState, HEX );
|
//Serial.println( vbusState, HEX );
|
||||||
pinvalue = digitalRead( MAX_INT );
|
pinvalue = INTR::Read();
|
||||||
|
//pinvalue = digitalRead( MAX_INT );
|
||||||
if( pinvalue == LOW ) {
|
if( pinvalue == LOW ) {
|
||||||
rcode = IntHandler();
|
rcode = IntHandler();
|
||||||
}
|
}
|
||||||
pinvalue = digitalRead( MAX_GPX );
|
// pinvalue = digitalRead( MAX_GPX );
|
||||||
if( pinvalue == LOW ) {
|
// if( pinvalue == LOW ) {
|
||||||
GpxHandler();
|
// GpxHandler();
|
||||||
}
|
// }
|
||||||
// usbSM(); //USB state machine
|
// usbSM(); //USB state machine
|
||||||
return( rcode );
|
return( rcode );
|
||||||
}
|
}
|
||||||
|
@ -277,17 +278,17 @@ uint8_t MAX3421e< SS, INTR >::IntHandler()
|
||||||
regWr( rHIRQ, HIRQ_sendback );
|
regWr( rHIRQ, HIRQ_sendback );
|
||||||
return( HIRQ_sendback );
|
return( HIRQ_sendback );
|
||||||
}
|
}
|
||||||
template< typename SS, typename INTR >
|
//template< typename SS, typename INTR >
|
||||||
uint8_t MAX3421e< SS, INTR >::GpxHandler()
|
//uint8_t MAX3421e< SS, INTR >::GpxHandler()
|
||||||
{
|
//{
|
||||||
uint8_t GPINIRQ = regRd( rGPINIRQ ); //read GPIN IRQ register
|
// uint8_t GPINIRQ = regRd( rGPINIRQ ); //read GPIN IRQ register
|
||||||
// if( GPINIRQ & bmGPINIRQ7 ) { //vbus overload
|
//// if( GPINIRQ & bmGPINIRQ7 ) { //vbus overload
|
||||||
// vbusPwr( OFF ); //attempt powercycle
|
//// vbusPwr( OFF ); //attempt powercycle
|
||||||
// delay( 1000 );
|
//// delay( 1000 );
|
||||||
// vbusPwr( ON );
|
//// vbusPwr( ON );
|
||||||
// regWr( rGPINIRQ, bmGPINIRQ7 );
|
//// regWr( rGPINIRQ, bmGPINIRQ7 );
|
||||||
// }
|
//// }
|
||||||
return( GPINIRQ );
|
// return( GPINIRQ );
|
||||||
}
|
//}
|
||||||
|
|
||||||
#endif //_USBHOST_H_
|
#endif //_USBHOST_H_
|
||||||
|
|
339
usbhub.cpp
339
usbhub.cpp
|
@ -5,47 +5,119 @@ USBHub::USBHub(USB *p) :
|
||||||
bAddress(0),
|
bAddress(0),
|
||||||
bNbrPorts(0),
|
bNbrPorts(0),
|
||||||
bInitState(0),
|
bInitState(0),
|
||||||
bPortResetCounter(1),
|
// bPortResetCounter(1),
|
||||||
qNextPollTime(0),
|
qNextPollTime(0),
|
||||||
bPollEnable(false)
|
bPollEnable(false)
|
||||||
{
|
{
|
||||||
epInfo[0].epAddr = 0;
|
epInfo[0].epAddr = 0;
|
||||||
epInfo[0].MaxPktSize = 8;
|
epInfo[0].MaxPktSize = 8;
|
||||||
epInfo[0].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
epInfo[0].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
||||||
epInfo[0].rcvToggle = bmRCVTOG0;
|
epInfo[0].rcvToggle = bmRCVTOG0;
|
||||||
|
|
||||||
epInfo[1].epAddr = 1;
|
epInfo[1].epAddr = 1;
|
||||||
epInfo[1].MaxPktSize = 1;
|
epInfo[1].MaxPktSize = 1;
|
||||||
epInfo[1].Interval = 0xff;
|
epInfo[1].Interval = 0xff;
|
||||||
epInfo[1].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
epInfo[1].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
||||||
epInfo[1].rcvToggle = bmRCVTOG0;
|
epInfo[1].rcvToggle = bmRCVTOG0;
|
||||||
|
|
||||||
if (pUsb)
|
if (pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t USBHub::Init(uint8_t addr)
|
uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
{
|
{
|
||||||
uint8_t buf[8];
|
uint8_t buf[32];
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
|
UsbDevice *p = NULL;
|
||||||
|
EP_RECORD *oldep_ptr = NULL;
|
||||||
|
uint8_t len = 0;
|
||||||
|
uint16_t cd_len = 0;
|
||||||
|
|
||||||
|
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||||
|
|
||||||
switch (bInitState)
|
switch (bInitState)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
Serial.println("Init");
|
Serial.println("Init");
|
||||||
|
|
||||||
bAddress = addr;
|
if (bAddress)
|
||||||
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
|
|
||||||
rcode = pUsb->getDevDescr( addr, 0, 8, (uint8_t*)buf );
|
// Get pointer to pseudo device with address 0 assigned
|
||||||
|
p = addrPool.GetUsbDevicePtr(0);
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
|
if (!p->epinfo)
|
||||||
|
{
|
||||||
|
Serial.println("epinfo");
|
||||||
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save old pointer to EP_RECORD of address 0
|
||||||
|
oldep_ptr = p->epinfo;
|
||||||
|
|
||||||
|
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
||||||
|
p->epinfo = epInfo;
|
||||||
|
|
||||||
|
// Get device descriptor
|
||||||
|
rcode = pUsb->getDevDescr( 0, 0, 8, (uint8_t*)buf );
|
||||||
|
|
||||||
|
if (!rcode)
|
||||||
|
len = (buf[0] > 32) ? 32 : buf[0];
|
||||||
|
|
||||||
|
if( rcode )
|
||||||
|
{
|
||||||
|
// Restore p->epinfo
|
||||||
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
|
Serial.println("getDevDesc:");
|
||||||
|
return rcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract device class from device descriptor
|
||||||
|
// If device class is not a hub return
|
||||||
|
if (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass != 0x09)
|
||||||
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
// Allocate new address according to device class
|
||||||
|
bAddress = addrPool.AllocAddress(parent, (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass == 0x09) ? true : false, port);
|
||||||
|
|
||||||
|
if (!bAddress)
|
||||||
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
|
// Extract Max Packet Size from the device descriptor
|
||||||
|
epInfo[0].MaxPktSize = ((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
||||||
|
|
||||||
|
// Assign new address to the device
|
||||||
|
rcode = pUsb->setAddr( 0, 0, bAddress );
|
||||||
|
|
||||||
|
if (rcode)
|
||||||
|
{
|
||||||
|
// Restore p->epinfo
|
||||||
|
p->epinfo = oldep_ptr;
|
||||||
|
addrPool.FreeAddress(bAddress);
|
||||||
|
bAddress = 0;
|
||||||
|
Serial.print("setAddr:");
|
||||||
|
Serial.println(rcode, HEX);
|
||||||
|
return rcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("Addr:");
|
||||||
|
Serial.println(bAddress, HEX);
|
||||||
|
|
||||||
|
// Restore p->epinfo
|
||||||
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
rcode = pUsb->getDevDescr( bAddress, 0, len, (uint8_t*)buf );
|
||||||
|
|
||||||
if(rcode)
|
if(rcode)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
// Return if the device is not a hub
|
// Assign epInfo to epinfo pointer
|
||||||
if (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass != 0x09)
|
rcode = pUsb->setDevTableEntry(bAddress, epInfo);
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
rcode = pUsb->setDevTableEntry(addr, epInfo);
|
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
@ -54,7 +126,7 @@ uint8_t USBHub::Init(uint8_t addr)
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// Get hub descriptor
|
// Get hub descriptor
|
||||||
rcode = pUsb->GetHubDescriptor(addr, 0, 0, 8, buf);
|
rcode = pUsb->GetHubDescriptor(bAddress, 0, 0, 8, buf);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailGetHubDescr;
|
goto FailGetHubDescr;
|
||||||
|
@ -66,16 +138,32 @@ uint8_t USBHub::Init(uint8_t addr)
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// Read configuration Descriptor in Order To Obtain Proper Configuration Value
|
// Read configuration Descriptor in Order To Obtain Proper Configuration Value
|
||||||
rcode = pUsb->getConfDescr(addr, 0, 8, 0, buf);
|
rcode = pUsb->getConfDescr(bAddress, 0, 8, 0, buf);
|
||||||
|
|
||||||
|
if (!rcode)
|
||||||
|
{
|
||||||
|
cd_len = ((USB_CONFIGURATION_DESCRIPTOR*)buf)->wTotalLength;
|
||||||
|
rcode = pUsb->getConfDescr(bAddress, 0, cd_len, 0, buf);
|
||||||
|
}
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
|
|
||||||
|
// The following code is of no practical use in real life applications.
|
||||||
|
// It only intended for the usb protocol sniffer to properly parse hub-class requests.
|
||||||
|
{
|
||||||
|
uint8_t buf2[24];
|
||||||
|
|
||||||
|
rcode = pUsb->getConfDescr(bAddress, 0, buf[0], 0, buf2);
|
||||||
|
|
||||||
|
if (rcode)
|
||||||
|
goto FailGetConfDescr;
|
||||||
|
}
|
||||||
|
|
||||||
Serial.print("Conf val:");
|
Serial.print("Conf val:");
|
||||||
Serial.println(buf[5], HEX);
|
Serial.println(buf[5], HEX);
|
||||||
|
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(addr, 0, buf[5]);
|
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
@ -87,49 +175,12 @@ uint8_t USBHub::Init(uint8_t addr)
|
||||||
case 3:
|
case 3:
|
||||||
// Power on all ports
|
// Power on all ports
|
||||||
for (uint8_t j=1; j<=bNbrPorts; j++)
|
for (uint8_t j=1; j<=bNbrPorts; j++)
|
||||||
pUsb->HubPortPowerOn(addr, j);
|
pUsb->HubPortPowerOn(bAddress, j);
|
||||||
|
|
||||||
Serial.println("Ports powered");
|
Serial.println("Ports powered");
|
||||||
|
|
||||||
bPollEnable = true;
|
bPollEnable = true;
|
||||||
bInitState = 0;
|
bInitState = 0;
|
||||||
// bInitState = 4;
|
|
||||||
|
|
||||||
//case 4:
|
|
||||||
// Serial.print("RC:");
|
|
||||||
// Serial.println(bPortResetCounter, DEC);
|
|
||||||
|
|
||||||
// for (; bPortResetCounter<=bNbrPorts; bPortResetCounter++)
|
|
||||||
// {
|
|
||||||
// HubEvent evt;
|
|
||||||
// rcode = pUsb->GetPortStatus(addr, 0, bPortResetCounter, 4, evt.evtBuff);
|
|
||||||
|
|
||||||
// if (rcode)
|
|
||||||
// goto FailGetPortStatus;
|
|
||||||
|
|
||||||
// Serial.print("RC:");
|
|
||||||
// Serial.println(bPortResetCounter, DEC);
|
|
||||||
// Serial.print("\tSt:");
|
|
||||||
// Serial.print(evt.bmStatus, BIN);
|
|
||||||
// Serial.print("\tCh:");
|
|
||||||
// Serial.println(evt.bmChange, BIN);
|
|
||||||
|
|
||||||
// // Initiate reset only if there is a device plugged into the port
|
|
||||||
// if (evt.bmStatus & bmHUB_PORT_STATUS_PORT_CONNECTION)
|
|
||||||
// {
|
|
||||||
// Serial.print("Con:");
|
|
||||||
// Serial.println(bPortResetCounter, DEC);
|
|
||||||
|
|
||||||
// pUsb->HubPortReset(addr, bPortResetCounter);
|
|
||||||
// bPollEnable = true;
|
|
||||||
//
|
|
||||||
// if (bPortResetCounter < bNbrPorts)
|
|
||||||
// bPortResetCounter ++;
|
|
||||||
|
|
||||||
// return USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE;
|
|
||||||
// }
|
|
||||||
// } // for
|
|
||||||
// bPortResetCounter = 1;
|
|
||||||
}
|
}
|
||||||
bInitState = 0;
|
bInitState = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -163,11 +214,13 @@ Fail:
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t USBHub::Release(uint8_t addr)
|
uint8_t USBHub::Release()
|
||||||
{
|
{
|
||||||
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
|
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
bNbrPorts = 0;
|
bNbrPorts = 0;
|
||||||
bPortResetCounter = 0;
|
// bPortResetCounter = 0;
|
||||||
qNextPollTime = 0;
|
qNextPollTime = 0;
|
||||||
bPollEnable = false;
|
bPollEnable = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -182,7 +235,8 @@ uint8_t USBHub::Poll()
|
||||||
|
|
||||||
if (qNextPollTime <= millis())
|
if (qNextPollTime <= millis())
|
||||||
{
|
{
|
||||||
Serial.println("Poll");
|
Serial.print("Poll:");
|
||||||
|
Serial.println(bAddress, HEX);
|
||||||
|
|
||||||
rcode = GetHubStatus(bAddress);
|
rcode = GetHubStatus(bAddress);
|
||||||
if (rcode)
|
if (rcode)
|
||||||
|
@ -190,7 +244,7 @@ uint8_t USBHub::Poll()
|
||||||
Serial.print("HubStatus:");
|
Serial.print("HubStatus:");
|
||||||
Serial.println(rcode,HEX);
|
Serial.println(rcode,HEX);
|
||||||
}
|
}
|
||||||
qNextPollTime = millis() + 10;
|
qNextPollTime = millis() + 100;
|
||||||
}
|
}
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
@ -273,10 +327,10 @@ void USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
|
||||||
//Serial.print("Con:");
|
//Serial.print("Con:");
|
||||||
//Serial.println(bmHUB_PORT_EVENT_CONNECT, HEX);
|
//Serial.println(bmHUB_PORT_EVENT_CONNECT, HEX);
|
||||||
|
|
||||||
Serial.print("Rc:");
|
//Serial.print("Rc:");
|
||||||
Serial.println(bmHUB_PORT_EVENT_RESET_COMPLETE, HEX);
|
//Serial.println(bmHUB_PORT_EVENT_RESET_COMPLETE, HEX);
|
||||||
|
|
||||||
PrintHubPortStatus(pUsb, addr, port);
|
PrintHubPortStatus(pUsb, addr, port, true);
|
||||||
|
|
||||||
switch (evt.bmEvent)
|
switch (evt.bmEvent)
|
||||||
{
|
{
|
||||||
|
@ -300,23 +354,17 @@ void USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
|
||||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_RESET | HUB_FEATURE_C_PORT_CONNECTION);
|
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_RESET | HUB_FEATURE_C_PORT_CONNECTION);
|
||||||
|
|
||||||
// Check if device is a low-speed device
|
// Check if device is a low-speed device
|
||||||
|
if (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
||||||
{
|
{
|
||||||
uint8_t new_addr;
|
UsbDevice *p = pUsb->GetAddressPool().GetUsbDevicePtr(addr);
|
||||||
|
|
||||||
delay(20);
|
if (p)
|
||||||
|
p->lowspeed = true;
|
||||||
// Begin addressing
|
|
||||||
pUsb->Addressing(&new_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//uint8_t new_addr = addrPool.AllocAddress(addr, true, port);
|
delay(50);
|
||||||
//rcode = pUsb->setAddr(0, 0, new_addr);
|
|
||||||
//if (rcode)
|
pUsb->Configuring(addr, port);
|
||||||
//{
|
|
||||||
// Serial.print("ERR:");
|
|
||||||
// Serial.println(rcode, HEX);
|
|
||||||
//}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Suspended or resuming state
|
// Suspended or resuming state
|
||||||
|
@ -335,7 +383,7 @@ void USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port)
|
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes)
|
||||||
{
|
{
|
||||||
uint8_t rcode = 0;
|
uint8_t rcode = 0;
|
||||||
HubEvent evt;
|
HubEvent evt;
|
||||||
|
@ -372,6 +420,9 @@ void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port)
|
||||||
Serial.print("INDICATOR:\t");
|
Serial.print("INDICATOR:\t");
|
||||||
Serial.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_INDICATOR) > 0, DEC);
|
Serial.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_INDICATOR) > 0, DEC);
|
||||||
|
|
||||||
|
if (!print_changes)
|
||||||
|
return;
|
||||||
|
|
||||||
Serial.println("\nChange");
|
Serial.println("\nChange");
|
||||||
Serial.print("CONNECTION:\t");
|
Serial.print("CONNECTION:\t");
|
||||||
Serial.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_CONNECTION) > 0, DEC);
|
Serial.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_CONNECTION) > 0, DEC);
|
||||||
|
@ -384,137 +435,3 @@ void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port)
|
||||||
Serial.print("RESET:\t\t");
|
Serial.print("RESET:\t\t");
|
||||||
Serial.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_RESET) > 0, DEC);
|
Serial.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_RESET) > 0, DEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
case USB_STATE_ADDRESSING:
|
|
||||||
Serial.println("ADRESSING");
|
|
||||||
{
|
|
||||||
UsbDevice *p = addrPool.GetUsbDevicePtr(0);
|
|
||||||
|
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
uint8_t addr = addrPool.AllocAddress(0, (p->devclass == 0x09) ? true : false);
|
|
||||||
|
|
||||||
if (addr)
|
|
||||||
{
|
|
||||||
Serial.print("Addr:");
|
|
||||||
Serial.println(addr,HEX);
|
|
||||||
|
|
||||||
UsbDevice *p0 = p;
|
|
||||||
|
|
||||||
rcode = setAddr( 0, 0, addr );
|
|
||||||
|
|
||||||
if (rcode)
|
|
||||||
{
|
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p = addrPool.GetUsbDevicePtr(addr);
|
|
||||||
|
|
||||||
usb_task_state = USB_STATE_CONFIGURING;
|
|
||||||
|
|
||||||
} // if (addr)
|
|
||||||
} // if (p)
|
|
||||||
}
|
|
||||||
// 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
|
|
||||||
// devtable[ i ].devclass = devtable[ 0 ].devclass;
|
|
||||||
|
|
||||||
// rcode = setAddr( 0, 0, i );
|
|
||||||
|
|
||||||
// if( rcode == 0 )
|
|
||||||
// {
|
|
||||||
// tmpaddr = i;
|
|
||||||
|
|
||||||
// if (devtable[i].devclass == USB_CLASS_HUB)
|
|
||||||
// {
|
|
||||||
// Serial.println("USB_CLASS_HUB");
|
|
||||||
|
|
||||||
// uint8_t buf[8];
|
|
||||||
|
|
||||||
// rcode = GetHubDescriptor(i, 0, 0, 8, buf);
|
|
||||||
|
|
||||||
// if (rcode == 0)
|
|
||||||
// {
|
|
||||||
// // Increment number of hubs found
|
|
||||||
// numHubs ++;
|
|
||||||
|
|
||||||
// // Insert hub address into a first available hub array entry
|
|
||||||
// for (uint8_t j=0; j<HUB_MAX_HUBS; j++)
|
|
||||||
// {
|
|
||||||
// if (hubs[j].bAddress == 0)
|
|
||||||
// {
|
|
||||||
// hubs[j].bAddress = i;
|
|
||||||
// hubs[j].bNbrPorts = ((HubDescriptor*)buf)->bNbrPorts;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// } // for
|
|
||||||
//
|
|
||||||
// } // if (rcode == 0)
|
|
||||||
// }
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// } // if( devtable[ i ].epinfo == NULL )
|
|
||||||
// } //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;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case USB_STATE_CONFIGURING:
|
|
||||||
Serial.print("CONFIGURING...");
|
|
||||||
|
|
||||||
//// Hub Configuration Code
|
|
||||||
//if (devtable[1].devclass == USB_CLASS_HUB)
|
|
||||||
//{
|
|
||||||
// Serial.println("HUB");
|
|
||||||
|
|
||||||
// // Read configuration Descriptor in Order To Obtain Proper Configuration Value
|
|
||||||
// uint8_t buf[8];
|
|
||||||
// rcode = getConfDescr(1, 0, 8, 0, buf);
|
|
||||||
|
|
||||||
// if (rcode)
|
|
||||||
// {
|
|
||||||
// Serial.print("getConfDescr:");
|
|
||||||
// Serial.println(rcode, HEX);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Serial.print("Conf val:");
|
|
||||||
// Serial.println(buf[5], HEX);
|
|
||||||
|
|
||||||
// // Set Configuration Value
|
|
||||||
// rcode = setConf(1, 0, buf[5]);
|
|
||||||
|
|
||||||
// if (rcode)
|
|
||||||
// {
|
|
||||||
// Serial.print("setConf:");
|
|
||||||
// Serial.println(rcode, HEX);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Serial.println("Hub configured");
|
|
||||||
|
|
||||||
// // Enter Port Configuring State
|
|
||||||
// usb_task_state = USB_STATE_HUB_PORT_POWERED_OFF;
|
|
||||||
// //usb_task_state = USB_STATE_HUB_PORT_DISABLED;
|
|
||||||
// break;
|
|
||||||
|
|
||||||
//} //if (devtable[i].devclass == USB_CLASS_HUB)
|
|
||||||
usb_task_state = USB_STATE_RUNNING;
|
|
||||||
Serial.println("Configured");
|
|
||||||
break;
|
|
||||||
#endif
|
|
8
usbhub.h
8
usbhub.h
|
@ -63,7 +63,7 @@ class USBHub : USBDeviceConfig
|
||||||
uint8_t bAddress; // address
|
uint8_t bAddress; // address
|
||||||
uint8_t bNbrPorts; // number of ports
|
uint8_t bNbrPorts; // number of ports
|
||||||
uint8_t bInitState; // initialization state variable
|
uint8_t bInitState; // initialization state variable
|
||||||
uint8_t bPortResetCounter; // number of ports reset
|
// uint8_t bPortResetCounter; // number of ports reset
|
||||||
uint32_t qNextPollTime; // next poll time
|
uint32_t qNextPollTime; // next poll time
|
||||||
bool bPollEnable; // poll enable flag
|
bool bPollEnable; // poll enable flag
|
||||||
|
|
||||||
|
@ -73,12 +73,12 @@ class USBHub : USBDeviceConfig
|
||||||
public:
|
public:
|
||||||
USBHub(USB *p);
|
USBHub(USB *p);
|
||||||
|
|
||||||
virtual uint8_t Init(uint8_t addr);
|
virtual uint8_t Init(uint8_t parent, uint8_t port);
|
||||||
virtual uint8_t Release(uint8_t addr);
|
virtual uint8_t Release();
|
||||||
virtual uint8_t Poll();
|
virtual uint8_t Poll();
|
||||||
};
|
};
|
||||||
|
|
||||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port);
|
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
|
Loading…
Reference in a new issue