removed digitalRead from usbhost.h

This commit is contained in:
Oleg Mazurov 2011-03-05 00:33:02 -07:00
commit d3a52a7616
6 changed files with 385 additions and 309 deletions

264
Usb.cpp
View file

@ -169,7 +169,12 @@ uint8_t USB::inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t*
uint8_t rcode;
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);
@ -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];
////////////////////////////////////////////////////////////////////////////////////////
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;
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)
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;
unsigned long timeout = millis() + USB_XFER_TIMEOUT;
@ -388,27 +425,34 @@ void USB::Task( void ) //USB state machine
case USB_DETACHED_SUBSTATE_INITIALIZE:
Serial.println("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;
break;
case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
Serial.println("WFD");
//Serial.println("WFD");
break;
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
Serial.println("ILL");
break;
case USB_ATTACHED_SUBSTATE_SETTLE: //setlle time for just attached device
Serial.println("STL");
//Serial.println("STL");
if( delay < millis() ) {
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
}
break;
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
Serial.println("RES");
//Serial.println("RES");
regWr( rHCTL, bmBUSRST ); //issue bus reset
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
break;
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
Serial.println("RCOMP");
//Serial.println("RCOMP");
if(( regRd( rHCTL ) & bmBUSRST ) == 0 )
{
tmpdata = regRd( rMODE ) | bmSOFKAENAB; //start SOF generation
@ -418,10 +462,11 @@ void USB::Task( void ) //USB state machine
}
break;
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( 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;
}
}
@ -429,20 +474,20 @@ void USB::Task( void ) //USB state machine
case USB_STATE_ADDRESSING:
Serial.println("ADR");
rcode = Addressing(&tmpaddr);
//rcode = Addressing(0, 0, &tmpaddr);
if (rcode == hrSUCCESS)
usb_task_state = USB_STATE_CONFIGURING;
else
{
usb_error = rcode;
usb_task_state = USB_STATE_ERROR;
}
//if (rcode == hrSUCCESS)
// usb_task_state = USB_STATE_CONFIGURING;
//else
//{
// usb_error = rcode;
// usb_task_state = USB_STATE_ERROR;
//}
break;
case USB_STATE_CONFIGURING:
Serial.print("CNF");
rcode = Configuring(tmpaddr);
rcode = Configuring(0, 0);
if (rcode)
{
@ -456,20 +501,23 @@ void USB::Task( void ) //USB state machine
usb_task_state = USB_STATE_RUNNING;
break;
case USB_STATE_RUNNING:
Serial.println("RUN");
//Serial.println("RUN");
break;
case USB_STATE_ERROR:
break;
} // 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)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
@ -479,65 +527,48 @@ uint8_t USB::Addressing(uint8_t *address)
Serial.println("epinfo");
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:");
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)
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
Serial.print("Addr:");
Serial.println(addr,HEX);
// Assign new address to the device
rcode = setAddr( 0, 0, bAddress );
rcode = setAddr( 0, 0, addr );
if (!rcode)
{
*address = addr;
}
else
if (rcode)
{
addrPool.FreeAddress(bAddress);
bAddress = 0;
Serial.print("setAddr:");
Serial.println(rcode, HEX);
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;
uint8_t rcode = 0, buf[8];
uint8_t rcode = 0;
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 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
devConfigIndex = 0;
return 0;
rcode = DefaultAddressing();
if (rcode)
Serial.println("Dfl fail");
return rcode;
}
//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("");
}
#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)

28
Usb.h
View file

@ -2,6 +2,8 @@
#ifndef _usb_h_
#define _usb_h_
#define USB_METHODS_INLINE
#include <inttypes.h>
#include "avrpins.h"
#include "max3421e.h"
@ -135,12 +137,21 @@
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL 0xD5
#define USB_ERROR_EPINFO_IS_NULL 0xD6
#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
{
public:
virtual uint8_t Init(uint8_t addr) = 0;
virtual uint8_t Release(uint8_t addr) = 0;
virtual uint8_t Init(uint8_t parent, uint8_t port) = 0;
virtual uint8_t Release() = 0;
virtual uint8_t Poll() = 0;
};
@ -250,6 +261,10 @@ class USB : public MAX3421E
public:
USB( void );
AddressPool& GetAddressPool()
{
return (AddressPool&)addrPool;
};
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
{
for (uint8_t i=0; i<USB_NUMDEVICES; i++)
@ -319,14 +334,15 @@ class USB : public MAX3421E
void Task( void );
uint8_t Addressing(uint8_t *address);
uint8_t Configuring(uint8_t addr);
uint8_t DefaultAddressing();
uint8_t Configuring(uint8_t parent, uint8_t port);
private:
void init();
};
#if defined(USB_METHODS_INLINE)
//get device descriptor
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 ));
@ -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 ));
}
#endif // defined(USB_METHODS_INLINE)
#endif //_usb_h_

View file

@ -50,14 +50,16 @@ struct UsbDevice
{
EP_RECORD *epinfo; // endpoint info pointer
uint8_t address; // address
bool lowspeed; // indicates if a device is the low speed one
uint8_t devclass; // device class
};
class AddressPool
{
public:
virtual uint8_t AllocAddress(UsbDeviceAddress parent, bool is_hub = false, uint8_t port = 0) = 0;
virtual void FreeAddress(UsbDeviceAddress addr) = 0;
virtual UsbDevice* GetUsbDevicePtr(uint8_t 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);
@ -66,7 +68,7 @@ typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
#define ADDR_ERROR_INVALID_ADDRESS 0xFF
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
@ -79,7 +81,7 @@ class AddressPoolImpl
void InitEntry(uint8_t index)
{
thePool[index].address = 0;
thePool[index].devclass = 0;
thePool[index].lowspeed = 0;
thePool[index].epinfo = &dev0ep;
};
// Returns thePool index for a given address
@ -146,7 +148,7 @@ public:
InitAllAddresses();
};
// Returns a pointer to a specified address entry
UsbDevice* GetUsbDevicePtr(uint8_t addr)
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr)
{
if (!addr)
return thePool;

View file

@ -209,7 +209,7 @@ int8_t MAX3421e< SS, INTR >::Init()
template< typename SS, typename INTR >
void MAX3421e< SS, INTR >::busprobe()
{
byte bus_sample;
uint8_t 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
@ -249,14 +249,15 @@ uint8_t MAX3421e< SS, INTR >::Task( void )
uint8_t pinvalue;
//Serial.print("Vbus state: ");
//Serial.println( vbusState, HEX );
pinvalue = digitalRead( MAX_INT );
pinvalue = INTR::Read();
//pinvalue = digitalRead( MAX_INT );
if( pinvalue == LOW ) {
rcode = IntHandler();
}
pinvalue = digitalRead( MAX_GPX );
if( pinvalue == LOW ) {
GpxHandler();
}
// pinvalue = digitalRead( MAX_GPX );
// if( pinvalue == LOW ) {
// GpxHandler();
// }
// usbSM(); //USB state machine
return( rcode );
}
@ -277,17 +278,17 @@ uint8_t MAX3421e< SS, INTR >::IntHandler()
regWr( rHIRQ, HIRQ_sendback );
return( HIRQ_sendback );
}
template< typename SS, typename INTR >
uint8_t MAX3421e< SS, INTR >::GpxHandler()
{
uint8_t GPINIRQ = regRd( rGPINIRQ ); //read GPIN IRQ register
// if( GPINIRQ & bmGPINIRQ7 ) { //vbus overload
// vbusPwr( OFF ); //attempt powercycle
// delay( 1000 );
// vbusPwr( ON );
// regWr( rGPINIRQ, bmGPINIRQ7 );
// }
return( GPINIRQ );
}
//template< typename SS, typename INTR >
//uint8_t MAX3421e< SS, INTR >::GpxHandler()
//{
// uint8_t GPINIRQ = regRd( rGPINIRQ ); //read GPIN IRQ register
//// if( GPINIRQ & bmGPINIRQ7 ) { //vbus overload
//// vbusPwr( OFF ); //attempt powercycle
//// delay( 1000 );
//// vbusPwr( ON );
//// regWr( rGPINIRQ, bmGPINIRQ7 );
//// }
// return( GPINIRQ );
//}
#endif //_USBHOST_H_

View file

@ -5,7 +5,7 @@ USBHub::USBHub(USB *p) :
bAddress(0),
bNbrPorts(0),
bInitState(0),
bPortResetCounter(1),
// bPortResetCounter(1),
qNextPollTime(0),
bPollEnable(false)
{
@ -24,28 +24,100 @@ USBHub::USBHub(USB *p) :
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;
UsbDevice *p = NULL;
EP_RECORD *oldep_ptr = NULL;
uint8_t len = 0;
uint16_t cd_len = 0;
AddressPool &addrPool = pUsb->GetAddressPool();
switch (bInitState)
{
case 0:
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)
goto FailGetDevDescr;
// Return if the device is not a hub
if (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass != 0x09)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
rcode = pUsb->setDevTableEntry(addr, epInfo);
// Assign epInfo to epinfo pointer
rcode = pUsb->setDevTableEntry(bAddress, epInfo);
if (rcode)
goto FailSetDevTblEntry;
@ -54,7 +126,7 @@ uint8_t USBHub::Init(uint8_t addr)
case 1:
// Get hub descriptor
rcode = pUsb->GetHubDescriptor(addr, 0, 0, 8, buf);
rcode = pUsb->GetHubDescriptor(bAddress, 0, 0, 8, buf);
if (rcode)
goto FailGetHubDescr;
@ -66,16 +138,32 @@ uint8_t USBHub::Init(uint8_t addr)
case 2:
// 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)
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.println(buf[5], HEX);
// Set Configuration Value
rcode = pUsb->setConf(addr, 0, buf[5]);
rcode = pUsb->setConf(bAddress, 0, buf[5]);
if (rcode)
goto FailSetConfDescr;
@ -87,49 +175,12 @@ uint8_t USBHub::Init(uint8_t addr)
case 3:
// Power on all ports
for (uint8_t j=1; j<=bNbrPorts; j++)
pUsb->HubPortPowerOn(addr, j);
pUsb->HubPortPowerOn(bAddress, j);
Serial.println("Ports powered");
bPollEnable = true;
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;
return 0;
@ -163,11 +214,13 @@ Fail:
return rcode;
}
uint8_t USBHub::Release(uint8_t addr)
uint8_t USBHub::Release()
{
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
bNbrPorts = 0;
bPortResetCounter = 0;
// bPortResetCounter = 0;
qNextPollTime = 0;
bPollEnable = false;
return 0;
@ -182,7 +235,8 @@ uint8_t USBHub::Poll()
if (qNextPollTime <= millis())
{
Serial.println("Poll");
Serial.print("Poll:");
Serial.println(bAddress, HEX);
rcode = GetHubStatus(bAddress);
if (rcode)
@ -190,7 +244,7 @@ uint8_t USBHub::Poll()
Serial.print("HubStatus:");
Serial.println(rcode,HEX);
}
qNextPollTime = millis() + 10;
qNextPollTime = millis() + 100;
}
return rcode;
}
@ -273,10 +327,10 @@ void USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
//Serial.print("Con:");
//Serial.println(bmHUB_PORT_EVENT_CONNECT, HEX);
Serial.print("Rc:");
Serial.println(bmHUB_PORT_EVENT_RESET_COMPLETE, HEX);
//Serial.print("Rc:");
//Serial.println(bmHUB_PORT_EVENT_RESET_COMPLETE, HEX);
PrintHubPortStatus(pUsb, addr, port);
PrintHubPortStatus(pUsb, addr, port, true);
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);
// 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);
// Begin addressing
pUsb->Addressing(&new_addr);
if (p)
p->lowspeed = true;
}
//uint8_t new_addr = addrPool.AllocAddress(addr, true, port);
//rcode = pUsb->setAddr(0, 0, new_addr);
//if (rcode)
//{
// Serial.print("ERR:");
// Serial.println(rcode, HEX);
//}
delay(50);
pUsb->Configuring(addr, port);
break;
// 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;
HubEvent evt;
@ -372,6 +420,9 @@ void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port)
Serial.print("INDICATOR:\t");
Serial.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_INDICATOR) > 0, DEC);
if (!print_changes)
return;
Serial.println("\nChange");
Serial.print("CONNECTION:\t");
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.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

View file

@ -63,7 +63,7 @@ class USBHub : USBDeviceConfig
uint8_t bAddress; // address
uint8_t bNbrPorts; // number of ports
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
bool bPollEnable; // poll enable flag
@ -73,12 +73,12 @@ class USBHub : USBDeviceConfig
public:
USBHub(USB *p);
virtual uint8_t Init(uint8_t addr);
virtual uint8_t Release(uint8_t addr);
virtual uint8_t Init(uint8_t parent, uint8_t port);
virtual uint8_t Release();
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);
// ---------------------------------