mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
next big change
This commit is contained in:
parent
d3a52a7616
commit
2be575ffc0
8 changed files with 1071 additions and 1384 deletions
227
Usb.h
227
Usb.h
|
@ -138,32 +138,26 @@
|
||||||
#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
|
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD8
|
||||||
|
#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xD9
|
||||||
//class USBDeviceConfig
|
#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDA
|
||||||
//{
|
|
||||||
//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 parent, uint8_t port) = 0;
|
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed) = 0;
|
||||||
virtual uint8_t Release() = 0;
|
virtual uint8_t Release() = 0;
|
||||||
virtual uint8_t Poll() = 0;
|
virtual uint8_t Poll() = 0;
|
||||||
|
virtual uint8_t GetAddress() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define USB_XFER_TIMEOUT 5000 //USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
|
#define USB_XFER_TIMEOUT 5000 //USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
|
||||||
#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. o meand NAKs are not counted
|
#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. o meand NAKs are not counted
|
||||||
#define USB_RETRY_LIMIT 3 //retry limit for a transfer
|
#define USB_RETRY_LIMIT 3 //retry limit for a transfer
|
||||||
#define USB_SETTLE_DELAY 200 //settle delay in milliseconds
|
#define USB_SETTLE_DELAY 200 //settle delay in milliseconds
|
||||||
#define USB_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code
|
#define USB_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code
|
||||||
|
|
||||||
#define USB_NUMDEVICES 6 //number of USB devices
|
#define USB_NUMDEVICES 64 //number of USB devices
|
||||||
#define HUB_MAX_HUBS 5 // maximum number of hubs that can be attached to the host controller
|
#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller
|
||||||
#define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms
|
#define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms
|
||||||
|
|
||||||
/* USB state machine states */
|
/* USB state machine states */
|
||||||
|
@ -208,12 +202,12 @@ typedef struct {
|
||||||
unsigned int wLength; // 6 Depends on bRequest
|
unsigned int wLength; // 6 Depends on bRequest
|
||||||
} SETUP_PKT, *PSETUP_PKT;
|
} SETUP_PKT, *PSETUP_PKT;
|
||||||
|
|
||||||
/* device record structure */
|
///* device record structure */
|
||||||
typedef struct
|
//typedef struct
|
||||||
{
|
//{
|
||||||
EP_RECORD *epinfo; //device endpoint information
|
// EpInfo *epinfo; //device endpoint information
|
||||||
uint8_t devclass; //device class
|
// uint8_t devclass; //device class
|
||||||
} DEV_RECORD;
|
//} DEV_RECORD;
|
||||||
|
|
||||||
|
|
||||||
struct HubDescriptor
|
struct HubDescriptor
|
||||||
|
@ -237,30 +231,30 @@ struct HubDescriptor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Base class for incomming data parser
|
||||||
|
class UsbReadParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Parse(const uint8_t len, const uint8_t *pbuf, const uint16_t &offset) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//typedef MAX3421e<P6, P3> MAX3421E; // Black Widdow
|
//typedef MAX3421e<P6, P3> MAX3421E; // Black Widdow
|
||||||
typedef MAX3421e<P10, P9> MAX3421E; // Duemielanove
|
typedef MAX3421e<P10, P9> MAX3421E; // Duemielanove
|
||||||
|
|
||||||
class USB : public MAX3421E
|
class USB : public MAX3421E
|
||||||
{
|
{
|
||||||
//data structures
|
|
||||||
/* device table. Filled during enumeration */
|
|
||||||
/* index corresponds to device address */
|
|
||||||
/* each entry contains pointer to endpoint structure */
|
|
||||||
/* and device class to use in various places */
|
|
||||||
//DEV_RECORD devtable[ USB_NUMDEVICES + 1 ];
|
|
||||||
//EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device
|
|
||||||
|
|
||||||
//byte usb_task_state;
|
|
||||||
|
|
||||||
|
|
||||||
AddressPoolImpl<USB_NUMDEVICES> addrPool;
|
AddressPoolImpl<USB_NUMDEVICES> addrPool;
|
||||||
USBDeviceConfig* devConfig[USB_NUMDEVICES];
|
USBDeviceConfig* devConfig[USB_NUMDEVICES];
|
||||||
uint8_t devConfigIndex;
|
uint8_t devConfigIndex;
|
||||||
|
uint8_t bmHubPre;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
USB( void );
|
USB( void );
|
||||||
|
|
||||||
|
void SetHubPreMask() { bmHubPre |= bmHUBPRE; };
|
||||||
|
void ResetHubPreMask() { bmHubPre &= (~bmHUBPRE); };
|
||||||
|
|
||||||
AddressPool& GetAddressPool()
|
AddressPool& GetAddressPool()
|
||||||
{
|
{
|
||||||
return (AddressPool&)addrPool;
|
return (AddressPool&)addrPool;
|
||||||
|
@ -284,163 +278,156 @@ class USB : public MAX3421E
|
||||||
uint8_t getUsbTaskState( void );
|
uint8_t getUsbTaskState( void );
|
||||||
void setUsbTaskState( uint8_t state );
|
void setUsbTaskState( uint8_t state );
|
||||||
|
|
||||||
EP_RECORD* getDevTableEntry( uint8_t addr, uint8_t ep );
|
EpInfo* getEpInfoEntry( uint8_t addr, uint8_t ep );
|
||||||
uint8_t setDevTableEntry( uint8_t addr, EP_RECORD* eprecord_ptr );
|
uint8_t setEpInfoEntry( uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr );
|
||||||
|
|
||||||
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 );
|
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);
|
||||||
|
|
||||||
/* Control requests */
|
/* Control requests */
|
||||||
uint8_t getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr );
|
||||||
uint8_t getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr );
|
||||||
uint8_t getStrDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t index, unsigned int langid, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t getStrDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t index, unsigned int langid, uint8_t* dataptr );
|
||||||
uint8_t setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr );
|
||||||
uint8_t setConf( uint8_t addr, uint8_t ep, uint8_t conf_value, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t setConf( uint8_t addr, uint8_t ep, uint8_t conf_value );
|
||||||
/**/
|
/**/
|
||||||
uint8_t setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol );
|
||||||
uint8_t getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr );
|
||||||
uint8_t getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr );
|
||||||
uint8_t 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 = USB_NAK_LIMIT );
|
uint8_t setReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr );
|
||||||
uint8_t 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 = USB_NAK_LIMIT );
|
uint8_t getReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr );
|
||||||
uint8_t getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr );
|
||||||
uint8_t setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration );
|
||||||
/**/
|
/**/
|
||||||
uint8_t ctrlData( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t ctrlData( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, boolean direction );
|
||||||
uint8_t ctrlStatus( uint8_t ep, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t ctrlStatus( uint8_t ep, boolean direction, uint16_t nak_limit );
|
||||||
uint8_t inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data );
|
||||||
uint8_t outTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t outTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data );
|
||||||
uint8_t dispatchPkt( uint8_t token, uint8_t ep, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t dispatchPkt( uint8_t token, uint8_t ep, uint16_t nak_limit );
|
||||||
|
|
||||||
// Hub Methods
|
// Hub Methods
|
||||||
uint8_t ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid );
|
||||||
uint8_t ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel = 0, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel = 0 );
|
||||||
uint8_t GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr );
|
||||||
uint8_t GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr );
|
||||||
uint8_t GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr );
|
||||||
uint8_t SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr );
|
||||||
uint8_t SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid );
|
||||||
uint8_t SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel = 0, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel = 0 );
|
||||||
|
|
||||||
uint8_t HubPortPowerOn(uint8_t addr, uint8_t port);
|
uint8_t HubPortPowerOn(uint8_t addr, uint8_t port);
|
||||||
uint8_t HubPortReset(uint8_t addr, uint8_t port);
|
uint8_t HubPortReset(uint8_t addr, uint8_t port);
|
||||||
uint8_t HubClearPortFeatures(uint8_t addr, uint8_t port, uint8_t bm_features);
|
uint8_t HubClearPortFeatures(uint8_t addr, uint8_t port, uint8_t bm_features);
|
||||||
|
|
||||||
uint8_t GetNumDevices();
|
|
||||||
uint8_t GetNumHubs();
|
|
||||||
|
|
||||||
uint8_t PollHubs();
|
|
||||||
uint8_t PollHub();
|
|
||||||
|
|
||||||
void PrintHubStatus(/*USB *usbptr,*/ uint8_t addr);
|
void PrintHubStatus(/*USB *usbptr,*/ uint8_t addr);
|
||||||
|
|
||||||
void Task( void );
|
void Task( void );
|
||||||
|
|
||||||
uint8_t DefaultAddressing();
|
uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed);
|
||||||
|
uint8_t Configuring(uint8_t parent, uint8_t port, bool lowspeed);
|
||||||
uint8_t Configuring(uint8_t parent, uint8_t port);
|
uint8_t ReleaseDevice(uint8_t addr);
|
||||||
|
|
||||||
|
//typedef void (*USBREADCALLBACK)(uint16_t nbytes, uint8_t *data, uint16_t offset);
|
||||||
|
|
||||||
|
//uint8_t 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, USBREADCALLBACK pf);
|
||||||
|
|
||||||
|
uint8_t 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);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
uint8_t SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_limit);
|
||||||
|
uint8_t OutTransfer(EpInfo *pep, uint16_t nak_limit, unsigned int nbytes, uint8_t *data);
|
||||||
|
uint8_t InTransfer (EpInfo *pep, uint16_t nak_limit, unsigned int nbytes, uint8_t* data);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(USB_METHODS_INLINE)
|
//#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 ) {
|
||||||
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 ));
|
||||||
}
|
}
|
||||||
//get configuration descriptor
|
//get configuration descriptor
|
||||||
inline uint8_t USB::getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr, unsigned int nak_limit ) {
|
inline uint8_t USB::getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
//get string descriptor
|
//get string descriptor
|
||||||
inline 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 ) {
|
inline uint8_t USB::getStrDescr( uint8_t addr, uint8_t ep, unsigned int nuint8_ts, uint8_t index, unsigned int langid, uint8_t* dataptr ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr ));
|
||||||
}
|
}
|
||||||
//set address
|
//set address
|
||||||
inline uint8_t USB::setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr, unsigned int nak_limit ) {
|
inline uint8_t USB::setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr ) {
|
||||||
return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL, nak_limit ));
|
return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL ));
|
||||||
}
|
}
|
||||||
//set configuration
|
//set configuration
|
||||||
inline uint8_t USB::setConf( uint8_t addr, uint8_t ep, uint8_t conf_value, unsigned int nak_limit ) {
|
inline uint8_t USB::setConf( uint8_t addr, uint8_t ep, uint8_t conf_value ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL ));
|
||||||
}
|
}
|
||||||
//class requests
|
//class requests
|
||||||
inline uint8_t USB::setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol, unsigned int nak_limit ) {
|
inline uint8_t USB::setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, NULL, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, NULL ));
|
||||||
}
|
}
|
||||||
inline uint8_t USB::getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr, unsigned int nak_limit ) {
|
inline uint8_t USB::getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr ));
|
||||||
}
|
}
|
||||||
//get HID report descriptor
|
//get HID report descriptor
|
||||||
inline uint8_t USB::getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit ) {
|
inline uint8_t USB::getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
inline 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 ) {
|
inline 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 ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
inline 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
|
inline 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 ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
/* returns one byte of data in dataptr */
|
/* returns one byte of data in dataptr */
|
||||||
inline uint8_t USB::getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr, unsigned int nak_limit ) {
|
inline uint8_t USB::getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr ));
|
||||||
}
|
}
|
||||||
inline uint8_t USB::setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration, unsigned int nak_limit ) {
|
inline uint8_t USB::setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration ) {
|
||||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL ));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
// Clear Hub Feature
|
||||||
inline uint8_t USB::ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit )
|
inline uint8_t USB::ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid )
|
||||||
{
|
{
|
||||||
return( ctrlReq( addr, ep, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, NULL, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, NULL ));
|
||||||
}
|
}
|
||||||
// Clear Port Feature
|
// Clear Port Feature
|
||||||
inline uint8_t USB::ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel, unsigned int nak_limit )
|
inline uint8_t USB::ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel )
|
||||||
{
|
{
|
||||||
return( ctrlReq( addr, ep, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000|port)|(sel<<8)), 0, NULL, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000|port)|(sel<<8)), 0, NULL ));
|
||||||
}
|
}
|
||||||
// Get Hub Descriptor
|
// Get Hub Descriptor
|
||||||
inline uint8_t USB::GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr, unsigned int nak_limit )
|
inline uint8_t USB::GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr )
|
||||||
{
|
{
|
||||||
return( ctrlReq( addr, ep, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
// Get Hub Status
|
// Get Hub Status
|
||||||
inline uint8_t USB::GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
inline uint8_t USB::GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr )
|
||||||
{
|
{
|
||||||
return( ctrlReq( addr, ep, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
// Get Port Status
|
// Get Port Status
|
||||||
inline uint8_t USB::GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
inline uint8_t USB::GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr )
|
||||||
{
|
{
|
||||||
//Serial.println(bmREQ_GET_PORT_STATUS, BIN);
|
return( ctrlReq( addr, ep, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr ));
|
||||||
return( ctrlReq( addr, ep, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr, nak_limit ));
|
|
||||||
}
|
}
|
||||||
// Set Hub Descriptor
|
// Set Hub Descriptor
|
||||||
inline uint8_t USB::SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
inline uint8_t USB::SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr )
|
||||||
{
|
{
|
||||||
return( ctrlReq( addr, ep, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, dataptr, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
// Set Hub Feature
|
// Set Hub Feature
|
||||||
inline uint8_t USB::SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit )
|
inline uint8_t USB::SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid )
|
||||||
{
|
{
|
||||||
return( ctrlReq( addr, ep, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, NULL, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, NULL ));
|
||||||
}
|
}
|
||||||
// Set Port Feature
|
// Set Port Feature
|
||||||
inline uint8_t USB::SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel, unsigned int nak_limit )
|
inline uint8_t USB::SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel )
|
||||||
{
|
{
|
||||||
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 ));
|
||||||
}
|
}
|
||||||
#endif // defined(USB_METHODS_INLINE)
|
//#endif // defined(USB_METHODS_INLINE)
|
||||||
|
|
||||||
#endif //_usb_h_
|
#endif //_usb_h_
|
91
address.h
91
address.h
|
@ -4,19 +4,25 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "max3421e.h"
|
#include "max3421e.h"
|
||||||
|
|
||||||
/* Endpoint information structure */
|
#define USB_NAK_MAX_POWER 15 //NAK binary order maximum value
|
||||||
/* bToggle of endpoint 0 initialized to 0xff */
|
|
||||||
/* during enumeration bToggle is set to 00 */
|
struct EpInfo
|
||||||
typedef struct
|
{
|
||||||
{
|
uint8_t epAddr; // Endpoint address
|
||||||
uint8_t epAddr; //copy from endpoint descriptor. Bit 7 indicates direction ( ignored for control endpoints )
|
uint8_t maxPktSize; // Maximum packet size
|
||||||
uint8_t Attr; // Endpoint transfer type.
|
|
||||||
unsigned int MaxPktSize; // Maximum packet size.
|
union
|
||||||
uint8_t Interval; // Polling interval in frames.
|
{
|
||||||
uint8_t sndToggle; //last toggle value, bitmask for HCTL toggle bits
|
uint8_t epAttribs;
|
||||||
uint8_t rcvToggle; //last toggle value, bitmask for HCTL toggle bits
|
|
||||||
/* not sure if both are necessary */
|
struct
|
||||||
} EP_RECORD;
|
{
|
||||||
|
uint8_t bmSndToggle : 1; // Send toggle, when zerro bmSNDTOG0, bmSNDTOG1 otherwise
|
||||||
|
uint8_t bmRcvToggle : 1; // Send toggle, when zerro bmRCVTOG0, bmRCVTOG1 otherwise
|
||||||
|
uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// 7 6 5 4 3 2 1 0
|
// 7 6 5 4 3 2 1 0
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
@ -48,10 +54,11 @@ struct UsbDeviceAddress
|
||||||
|
|
||||||
struct UsbDevice
|
struct UsbDevice
|
||||||
{
|
{
|
||||||
EP_RECORD *epinfo; // endpoint info pointer
|
EpInfo *epinfo; // endpoint info pointer
|
||||||
uint8_t address; // address
|
uint8_t address; // address
|
||||||
|
uint8_t epcount; // number of endpoints
|
||||||
bool lowspeed; // indicates if a device is the low speed one
|
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
|
||||||
|
@ -70,7 +77,7 @@ typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
|
||||||
template <const uint8_t MAX_DEVICES_ALLOWED>
|
template <const uint8_t MAX_DEVICES_ALLOWED>
|
||||||
class AddressPoolImpl : public AddressPool
|
class AddressPoolImpl : public AddressPool
|
||||||
{
|
{
|
||||||
EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device
|
EpInfo dev0ep; //Endpoint data structure used during enumeration for uninitialized device
|
||||||
|
|
||||||
uint8_t hubCounter; // hub counter is kept
|
uint8_t hubCounter; // hub counter is kept
|
||||||
// in order to avoid hub address duplication
|
// in order to avoid hub address duplication
|
||||||
|
@ -81,6 +88,7 @@ class AddressPoolImpl : public AddressPool
|
||||||
void InitEntry(uint8_t index)
|
void InitEntry(uint8_t index)
|
||||||
{
|
{
|
||||||
thePool[index].address = 0;
|
thePool[index].address = 0;
|
||||||
|
thePool[index].epcount = 1;
|
||||||
thePool[index].lowspeed = 0;
|
thePool[index].lowspeed = 0;
|
||||||
thePool[index].epinfo = &dev0ep;
|
thePool[index].epinfo = &dev0ep;
|
||||||
};
|
};
|
||||||
|
@ -141,9 +149,9 @@ public:
|
||||||
thePool[0].address = 0;
|
thePool[0].address = 0;
|
||||||
thePool[0].epinfo = &dev0ep;
|
thePool[0].epinfo = &dev0ep;
|
||||||
dev0ep.epAddr = 0;
|
dev0ep.epAddr = 0;
|
||||||
dev0ep.MaxPktSize = 8;
|
dev0ep.maxPktSize = 8;
|
||||||
dev0ep.sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
dev0ep.epAttribs = 0; //set DATA0/1 toggles to 0
|
||||||
dev0ep.rcvToggle = bmRCVTOG0;
|
dev0ep.bmNakPower = USB_NAK_MAX_POWER;
|
||||||
|
|
||||||
InitAllAddresses();
|
InitAllAddresses();
|
||||||
};
|
};
|
||||||
|
@ -171,20 +179,28 @@ public:
|
||||||
// Allocates new address
|
// Allocates new address
|
||||||
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0)
|
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0)
|
||||||
{
|
{
|
||||||
|
if (parent != 0 && port == 0)
|
||||||
|
Serial.println("PRT:0");
|
||||||
|
|
||||||
if (parent > 127 || port > 7)
|
if (parent > 127 || port > 7)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// finds first empty address entry starting from one
|
// finds first empty address entry starting from one
|
||||||
uint8_t index = FindAddressIndex(0);
|
uint8_t index = FindAddressIndex(0);
|
||||||
|
|
||||||
Serial.println(index, DEC);
|
|
||||||
|
|
||||||
if (!index) // if empty entry is not found
|
if (!index) // if empty entry is not found
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (parent == 0)
|
if (parent == 0)
|
||||||
{
|
{
|
||||||
thePool[index].address = (is_hub) ? 0x41 : 1;
|
if (is_hub)
|
||||||
|
{
|
||||||
|
thePool[index].address = 0x41;
|
||||||
|
hubCounter ++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
thePool[index].address = 1;
|
||||||
|
|
||||||
return thePool[index].address;
|
return thePool[index].address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +220,13 @@ public:
|
||||||
}
|
}
|
||||||
thePool[index].address = *((uint8_t*)&addr);
|
thePool[index].address = *((uint8_t*)&addr);
|
||||||
|
|
||||||
|
Serial.print("Addr:");
|
||||||
|
Serial.print(addr.bmHub, HEX);
|
||||||
|
Serial.print(".");
|
||||||
|
Serial.print(addr.bmParent, HEX);
|
||||||
|
Serial.print(".");
|
||||||
|
Serial.println(addr.bmAddress, HEX);
|
||||||
|
|
||||||
return thePool[index].address;
|
return thePool[index].address;
|
||||||
};
|
};
|
||||||
// Empties pool entry
|
// Empties pool entry
|
||||||
|
@ -220,20 +243,20 @@ public:
|
||||||
};
|
};
|
||||||
// Returns number of hubs attached
|
// Returns number of hubs attached
|
||||||
// It can be rather helpfull to find out if there are hubs attached than getting the exact number of hubs.
|
// It can be rather helpfull to find out if there are hubs attached than getting the exact number of hubs.
|
||||||
uint8_t GetNumHubs()
|
//uint8_t GetNumHubs()
|
||||||
{
|
//{
|
||||||
return hubCounter;
|
// return hubCounter;
|
||||||
};
|
//};
|
||||||
uint8_t GetNumDevices()
|
//uint8_t GetNumDevices()
|
||||||
{
|
//{
|
||||||
uint8_t counter = 0;
|
// uint8_t counter = 0;
|
||||||
|
|
||||||
for (uint8_t i=1; i<MAX_DEVICES_ALLOWED; i++)
|
// for (uint8_t i=1; i<MAX_DEVICES_ALLOWED; i++)
|
||||||
if (thePool[i].address != 0);
|
// if (thePool[i].address != 0);
|
||||||
counter ++;
|
// counter ++;
|
||||||
|
|
||||||
return counter;
|
// return counter;
|
||||||
};
|
//};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ADDRESS_H__
|
#endif // __ADDRESS_H__
|
930
avrpins.h
930
avrpins.h
|
@ -1,466 +1,466 @@
|
||||||
/* copied from Konstantin Chizhov's AVR port templates */
|
/* copied from Konstantin Chizhov's AVR port templates */
|
||||||
|
|
||||||
#ifndef _avrpins_h_
|
#ifndef _avrpins_h_
|
||||||
#define _avrpins_h_
|
#define _avrpins_h_
|
||||||
|
|
||||||
//#include "WProgram.h"
|
//#include "WProgram.h"
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|
||||||
#ifdef PORTA
|
#ifdef PORTA
|
||||||
#define USE_PORTA
|
#define USE_PORTA
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTB
|
#ifdef PORTB
|
||||||
#define USE_PORTB
|
#define USE_PORTB
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTC
|
#ifdef PORTC
|
||||||
#define USE_PORTC
|
#define USE_PORTC
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTD
|
#ifdef PORTD
|
||||||
#define USE_PORTD
|
#define USE_PORTD
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTE
|
#ifdef PORTE
|
||||||
#define USE_PORTE
|
#define USE_PORTE
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTF
|
#ifdef PORTF
|
||||||
#define USE_PORTF
|
#define USE_PORTF
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTG
|
#ifdef PORTG
|
||||||
#define USE_PORTG
|
#define USE_PORTG
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTH
|
#ifdef PORTH
|
||||||
#define USE_PORTH
|
#define USE_PORTH
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTJ
|
#ifdef PORTJ
|
||||||
#define USE_PORTJ
|
#define USE_PORTJ
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTK
|
#ifdef PORTK
|
||||||
#define USE_PORTK
|
#define USE_PORTK
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTQ
|
#ifdef PORTQ
|
||||||
#define USE_PORTQ
|
#define USE_PORTQ
|
||||||
#endif
|
#endif
|
||||||
#ifdef PORTR
|
#ifdef PORTR
|
||||||
#define USE_PORTR
|
#define USE_PORTR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TCCR0A
|
#ifdef TCCR0A
|
||||||
#define USE_TCCR0A
|
#define USE_TCCR0A
|
||||||
#endif
|
#endif
|
||||||
#ifdef TCCR1A
|
#ifdef TCCR1A
|
||||||
#define USE_TCCR1A
|
#define USE_TCCR1A
|
||||||
#endif
|
#endif
|
||||||
#ifdef TCCR2A
|
#ifdef TCCR2A
|
||||||
#define USE_TCCR2A
|
#define USE_TCCR2A
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Port definitions for AtTiny, AtMega families.
|
//Port definitions for AtTiny, AtMega families.
|
||||||
|
|
||||||
#define MAKE_PORT(portName, ddrName, pinName, className, ID) \
|
#define MAKE_PORT(portName, ddrName, pinName, className, ID) \
|
||||||
class className{\
|
class className{\
|
||||||
public:\
|
public:\
|
||||||
typedef uint8_t DataT;\
|
typedef uint8_t DataT;\
|
||||||
public:\
|
public:\
|
||||||
static void Write(DataT value){portName = value;}\
|
static void Write(DataT value){portName = value;}\
|
||||||
static void ClearAndSet(DataT clearMask, DataT value){portName = (portName & ~clearMask) | value;}\
|
static void ClearAndSet(DataT clearMask, DataT value){portName = (portName & ~clearMask) | value;}\
|
||||||
static DataT Read(){return portName;}\
|
static DataT Read(){return portName;}\
|
||||||
static void DirWrite(DataT value){ddrName = value;}\
|
static void DirWrite(DataT value){ddrName = value;}\
|
||||||
static DataT DirRead(){return ddrName;}\
|
static DataT DirRead(){return ddrName;}\
|
||||||
static void Set(DataT value){portName |= value;}\
|
static void Set(DataT value){portName |= value;}\
|
||||||
static void Clear(DataT value){portName &= ~value;}\
|
static void Clear(DataT value){portName &= ~value;}\
|
||||||
static void Toggle(DataT value){portName ^= value;}\
|
static void Toggle(DataT value){portName ^= value;}\
|
||||||
static void DirSet(DataT value){ddrName |= value;}\
|
static void DirSet(DataT value){ddrName |= value;}\
|
||||||
static void DirClear(DataT value){ddrName &= ~value;}\
|
static void DirClear(DataT value){ddrName &= ~value;}\
|
||||||
static void DirToggle(DataT value){ddrName ^= value;}\
|
static void DirToggle(DataT value){ddrName ^= value;}\
|
||||||
static DataT PinRead(){return pinName;}\
|
static DataT PinRead(){return pinName;}\
|
||||||
enum{Id = ID};\
|
enum{Id = ID};\
|
||||||
enum{Width=sizeof(DataT)*8};\
|
enum{Width=sizeof(DataT)*8};\
|
||||||
};
|
};
|
||||||
|
|
||||||
// TCCR registers to set/clear Arduino PWM
|
// TCCR registers to set/clear Arduino PWM
|
||||||
#define MAKE_TCCR(TccrName, className) \
|
#define MAKE_TCCR(TccrName, className) \
|
||||||
class className{\
|
class className{\
|
||||||
public:\
|
public:\
|
||||||
typedef uint8_t DataT;\
|
typedef uint8_t DataT;\
|
||||||
public:\
|
public:\
|
||||||
static void Write(DataT value){TccrName = value;}\
|
static void Write(DataT value){TccrName = value;}\
|
||||||
static void ClearAndSet(DataT clearMask, DataT value){TccrName = (TccrName & ~clearMask) | value;}\
|
static void ClearAndSet(DataT clearMask, DataT value){TccrName = (TccrName & ~clearMask) | value;}\
|
||||||
static DataT Read(){return TccrName;}\
|
static DataT Read(){return TccrName;}\
|
||||||
static void Set(DataT value){TccrName |= value;}\
|
static void Set(DataT value){TccrName |= value;}\
|
||||||
static void Clear(DataT value){TccrName &= ~value;}\
|
static void Clear(DataT value){TccrName &= ~value;}\
|
||||||
static void Toggle(DataT value){TccrName ^= value;}\
|
static void Toggle(DataT value){TccrName ^= value;}\
|
||||||
enum{Width=sizeof(DataT)*8};\
|
enum{Width=sizeof(DataT)*8};\
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_PORTA
|
#ifdef USE_PORTA
|
||||||
MAKE_PORT(PORTA, DDRA, PINA, Porta, 'A')
|
MAKE_PORT(PORTA, DDRA, PINA, Porta, 'A')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTB
|
#ifdef USE_PORTB
|
||||||
MAKE_PORT(PORTB, DDRB, PINB, Portb, 'B')
|
MAKE_PORT(PORTB, DDRB, PINB, Portb, 'B')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTC
|
#ifdef USE_PORTC
|
||||||
MAKE_PORT(PORTC, DDRC, PINC, Portc, 'C')
|
MAKE_PORT(PORTC, DDRC, PINC, Portc, 'C')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTD
|
#ifdef USE_PORTD
|
||||||
MAKE_PORT(PORTD, DDRD, PIND, Portd, 'D')
|
MAKE_PORT(PORTD, DDRD, PIND, Portd, 'D')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTE
|
#ifdef USE_PORTE
|
||||||
MAKE_PORT(PORTE, DDRE, PINE, Porte, 'E')
|
MAKE_PORT(PORTE, DDRE, PINE, Porte, 'E')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTF
|
#ifdef USE_PORTF
|
||||||
MAKE_PORT(PORTF, DDRF, PINF, Portf, 'F')
|
MAKE_PORT(PORTF, DDRF, PINF, Portf, 'F')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTG
|
#ifdef USE_PORTG
|
||||||
MAKE_PORT(PORTG, DDRG, PING, Portg, 'G')
|
MAKE_PORT(PORTG, DDRG, PING, Portg, 'G')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTH
|
#ifdef USE_PORTH
|
||||||
MAKE_PORT(PORTH, DDRH, PINH, Porth, 'H')
|
MAKE_PORT(PORTH, DDRH, PINH, Porth, 'H')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTJ
|
#ifdef USE_PORTJ
|
||||||
MAKE_PORT(PORTJ, DDRJ, PINJ, Portj, 'J')
|
MAKE_PORT(PORTJ, DDRJ, PINJ, Portj, 'J')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTK
|
#ifdef USE_PORTK
|
||||||
MAKE_PORT(PORTK, DDRK, PINK, Portk, 'K')
|
MAKE_PORT(PORTK, DDRK, PINK, Portk, 'K')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTQ
|
#ifdef USE_PORTQ
|
||||||
MAKE_PORT(PORTQ, DDRQ, PINQ, Portq, 'Q')
|
MAKE_PORT(PORTQ, DDRQ, PINQ, Portq, 'Q')
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_PORTR
|
#ifdef USE_PORTR
|
||||||
MAKE_PORT(PORTR, DDRR, PINR, Portr, 'R')
|
MAKE_PORT(PORTR, DDRR, PINR, Portr, 'R')
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TCCR0A
|
#ifdef USE_TCCR0A
|
||||||
MAKE_TCCR(TCCR0A, Tccr0a)
|
MAKE_TCCR(TCCR0A, Tccr0a)
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TCCR1A
|
#ifdef USE_TCCR1A
|
||||||
MAKE_TCCR(TCCR1A, Tccr1a)
|
MAKE_TCCR(TCCR1A, Tccr1a)
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_TCCR2A
|
#ifdef USE_TCCR2A
|
||||||
MAKE_TCCR(TCCR2A, Tccr2a)
|
MAKE_TCCR(TCCR2A, Tccr2a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// this class represents one pin in a IO port.
|
// this class represents one pin in a IO port.
|
||||||
// It is fully static.
|
// It is fully static.
|
||||||
template<typename PORT, uint8_t PIN>
|
template<typename PORT, uint8_t PIN>
|
||||||
class TPin
|
class TPin
|
||||||
{
|
{
|
||||||
// BOOST_STATIC_ASSERT(PIN < PORT::Width);
|
// BOOST_STATIC_ASSERT(PIN < PORT::Width);
|
||||||
public:
|
public:
|
||||||
typedef PORT Port;
|
typedef PORT Port;
|
||||||
enum{Number = PIN};
|
enum{Number = PIN};
|
||||||
|
|
||||||
static void Set() { PORT::Set(1 << PIN); }
|
static void Set() { PORT::Set(1 << PIN); }
|
||||||
|
|
||||||
static void Set(uint8_t val){
|
static void Set(uint8_t val){
|
||||||
if(val)
|
if(val)
|
||||||
Set();
|
Set();
|
||||||
else Clear();}
|
else Clear();}
|
||||||
|
|
||||||
static void SetDir(uint8_t val){
|
static void SetDir(uint8_t val){
|
||||||
if(val)
|
if(val)
|
||||||
SetDirWrite();
|
SetDirWrite();
|
||||||
else SetDirRead();}
|
else SetDirRead();}
|
||||||
|
|
||||||
static void Clear(){PORT::Clear(1 << PIN);}
|
static void Clear(){PORT::Clear(1 << PIN);}
|
||||||
|
|
||||||
static void Toggle(){PORT::Toggle(1 << PIN);}
|
static void Toggle(){PORT::Toggle(1 << PIN);}
|
||||||
|
|
||||||
static void SetDirRead(){PORT::DirClear(1 << PIN);}
|
static void SetDirRead(){PORT::DirClear(1 << PIN);}
|
||||||
|
|
||||||
static void SetDirWrite(){PORT::DirSet(1 << PIN);}
|
static void SetDirWrite(){PORT::DirSet(1 << PIN);}
|
||||||
|
|
||||||
static uint8_t IsSet(){return PORT::PinRead() & (uint8_t)(1 << PIN);}
|
static uint8_t IsSet(){return PORT::PinRead() & (uint8_t)(1 << PIN);}
|
||||||
|
|
||||||
static void WaiteForSet(){ while(IsSet()==0){} }
|
static void WaiteForSet(){ while(IsSet()==0){} }
|
||||||
|
|
||||||
static void WaiteForClear(){ while(IsSet()){} }
|
static void WaiteForClear(){ while(IsSet()){} }
|
||||||
}; //class TPin...
|
}; //class TPin...
|
||||||
|
|
||||||
// this class represents one bit in TCCR port.
|
// this class represents one bit in TCCR port.
|
||||||
// used to set/clear TCCRx bits
|
// used to set/clear TCCRx bits
|
||||||
// It is fully static.
|
// It is fully static.
|
||||||
template<typename TCCR, uint8_t COM>
|
template<typename TCCR, uint8_t COM>
|
||||||
class TCom
|
class TCom
|
||||||
{
|
{
|
||||||
// BOOST_STATIC_ASSERT(PIN < PORT::Width);
|
// BOOST_STATIC_ASSERT(PIN < PORT::Width);
|
||||||
public:
|
public:
|
||||||
typedef TCCR Tccr;
|
typedef TCCR Tccr;
|
||||||
enum{Com = COM};
|
enum{Com = COM};
|
||||||
|
|
||||||
static void Set() { TCCR::Set(1 << COM); }
|
static void Set() { TCCR::Set(1 << COM); }
|
||||||
|
|
||||||
static void Clear() { TCCR::Clear(1 << COM); }
|
static void Clear() { TCCR::Clear(1 << COM); }
|
||||||
|
|
||||||
static void Toggle() { TCCR::Toggle(1 << COM); }
|
static void Toggle() { TCCR::Toggle(1 << COM); }
|
||||||
}; //class TCom...
|
}; //class TCom...
|
||||||
|
|
||||||
//Short pin definitions
|
//Short pin definitions
|
||||||
#ifdef USE_PORTA
|
#ifdef USE_PORTA
|
||||||
typedef TPin<Porta, 0> Pa0;
|
typedef TPin<Porta, 0> Pa0;
|
||||||
typedef TPin<Porta, 1> Pa1;
|
typedef TPin<Porta, 1> Pa1;
|
||||||
typedef TPin<Porta, 2> Pa2;
|
typedef TPin<Porta, 2> Pa2;
|
||||||
typedef TPin<Porta, 3> Pa3;
|
typedef TPin<Porta, 3> Pa3;
|
||||||
typedef TPin<Porta, 4> Pa4;
|
typedef TPin<Porta, 4> Pa4;
|
||||||
typedef TPin<Porta, 5> Pa5;
|
typedef TPin<Porta, 5> Pa5;
|
||||||
typedef TPin<Porta, 6> Pa6;
|
typedef TPin<Porta, 6> Pa6;
|
||||||
typedef TPin<Porta, 7> Pa7;
|
typedef TPin<Porta, 7> Pa7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTB
|
#ifdef USE_PORTB
|
||||||
typedef TPin<Portb, 0> Pb0;
|
typedef TPin<Portb, 0> Pb0;
|
||||||
typedef TPin<Portb, 1> Pb1;
|
typedef TPin<Portb, 1> Pb1;
|
||||||
typedef TPin<Portb, 2> Pb2;
|
typedef TPin<Portb, 2> Pb2;
|
||||||
typedef TPin<Portb, 3> Pb3;
|
typedef TPin<Portb, 3> Pb3;
|
||||||
typedef TPin<Portb, 4> Pb4;
|
typedef TPin<Portb, 4> Pb4;
|
||||||
typedef TPin<Portb, 5> Pb5;
|
typedef TPin<Portb, 5> Pb5;
|
||||||
typedef TPin<Portb, 6> Pb6;
|
typedef TPin<Portb, 6> Pb6;
|
||||||
typedef TPin<Portb, 7> Pb7;
|
typedef TPin<Portb, 7> Pb7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTC
|
#ifdef USE_PORTC
|
||||||
typedef TPin<Portc, 0> Pc0;
|
typedef TPin<Portc, 0> Pc0;
|
||||||
typedef TPin<Portc, 1> Pc1;
|
typedef TPin<Portc, 1> Pc1;
|
||||||
typedef TPin<Portc, 2> Pc2;
|
typedef TPin<Portc, 2> Pc2;
|
||||||
typedef TPin<Portc, 3> Pc3;
|
typedef TPin<Portc, 3> Pc3;
|
||||||
typedef TPin<Portc, 4> Pc4;
|
typedef TPin<Portc, 4> Pc4;
|
||||||
typedef TPin<Portc, 5> Pc5;
|
typedef TPin<Portc, 5> Pc5;
|
||||||
typedef TPin<Portc, 6> Pc6;
|
typedef TPin<Portc, 6> Pc6;
|
||||||
typedef TPin<Portc, 7> Pc7;
|
typedef TPin<Portc, 7> Pc7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTD
|
#ifdef USE_PORTD
|
||||||
typedef TPin<Portd, 0> Pd0;
|
typedef TPin<Portd, 0> Pd0;
|
||||||
typedef TPin<Portd, 1> Pd1;
|
typedef TPin<Portd, 1> Pd1;
|
||||||
typedef TPin<Portd, 2> Pd2;
|
typedef TPin<Portd, 2> Pd2;
|
||||||
typedef TPin<Portd, 3> Pd3;
|
typedef TPin<Portd, 3> Pd3;
|
||||||
typedef TPin<Portd, 4> Pd4;
|
typedef TPin<Portd, 4> Pd4;
|
||||||
typedef TPin<Portd, 5> Pd5;
|
typedef TPin<Portd, 5> Pd5;
|
||||||
typedef TPin<Portd, 6> Pd6;
|
typedef TPin<Portd, 6> Pd6;
|
||||||
typedef TPin<Portd, 7> Pd7;
|
typedef TPin<Portd, 7> Pd7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTE
|
#ifdef USE_PORTE
|
||||||
typedef TPin<Porte, 0> Pe0;
|
typedef TPin<Porte, 0> Pe0;
|
||||||
typedef TPin<Porte, 1> Pe1;
|
typedef TPin<Porte, 1> Pe1;
|
||||||
typedef TPin<Porte, 2> Pe2;
|
typedef TPin<Porte, 2> Pe2;
|
||||||
typedef TPin<Porte, 3> Pe3;
|
typedef TPin<Porte, 3> Pe3;
|
||||||
typedef TPin<Porte, 4> Pe4;
|
typedef TPin<Porte, 4> Pe4;
|
||||||
typedef TPin<Porte, 5> Pe5;
|
typedef TPin<Porte, 5> Pe5;
|
||||||
typedef TPin<Porte, 6> Pe6;
|
typedef TPin<Porte, 6> Pe6;
|
||||||
typedef TPin<Porte, 7> Pe7;
|
typedef TPin<Porte, 7> Pe7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTF
|
#ifdef USE_PORTF
|
||||||
typedef TPin<Portf, 0> Pf0;
|
typedef TPin<Portf, 0> Pf0;
|
||||||
typedef TPin<Portf, 1> Pf1;
|
typedef TPin<Portf, 1> Pf1;
|
||||||
typedef TPin<Portf, 2> Pf2;
|
typedef TPin<Portf, 2> Pf2;
|
||||||
typedef TPin<Portf, 3> Pf3;
|
typedef TPin<Portf, 3> Pf3;
|
||||||
typedef TPin<Portf, 4> Pf4;
|
typedef TPin<Portf, 4> Pf4;
|
||||||
typedef TPin<Portf, 5> Pf5;
|
typedef TPin<Portf, 5> Pf5;
|
||||||
typedef TPin<Portf, 6> Pf6;
|
typedef TPin<Portf, 6> Pf6;
|
||||||
typedef TPin<Portf, 7> Pf7;
|
typedef TPin<Portf, 7> Pf7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTG
|
#ifdef USE_PORTG
|
||||||
typedef TPin<Portg, 0> Pg0;
|
typedef TPin<Portg, 0> Pg0;
|
||||||
typedef TPin<Portg, 1> Pg1;
|
typedef TPin<Portg, 1> Pg1;
|
||||||
typedef TPin<Portg, 2> Pg2;
|
typedef TPin<Portg, 2> Pg2;
|
||||||
typedef TPin<Portg, 3> Pg3;
|
typedef TPin<Portg, 3> Pg3;
|
||||||
typedef TPin<Portg, 4> Pg4;
|
typedef TPin<Portg, 4> Pg4;
|
||||||
typedef TPin<Portg, 5> Pg5;
|
typedef TPin<Portg, 5> Pg5;
|
||||||
typedef TPin<Portg, 6> Pg6;
|
typedef TPin<Portg, 6> Pg6;
|
||||||
typedef TPin<Portg, 7> Pg7;
|
typedef TPin<Portg, 7> Pg7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTH
|
#ifdef USE_PORTH
|
||||||
typedef TPin<Porth, 0> Ph0;
|
typedef TPin<Porth, 0> Ph0;
|
||||||
typedef TPin<Porth, 1> Ph1;
|
typedef TPin<Porth, 1> Ph1;
|
||||||
typedef TPin<Porth, 2> Ph2;
|
typedef TPin<Porth, 2> Ph2;
|
||||||
typedef TPin<Porth, 3> Ph3;
|
typedef TPin<Porth, 3> Ph3;
|
||||||
typedef TPin<Porth, 4> Ph4;
|
typedef TPin<Porth, 4> Ph4;
|
||||||
typedef TPin<Porth, 5> Ph5;
|
typedef TPin<Porth, 5> Ph5;
|
||||||
typedef TPin<Porth, 6> Ph6;
|
typedef TPin<Porth, 6> Ph6;
|
||||||
typedef TPin<Porth, 7> Ph7;
|
typedef TPin<Porth, 7> Ph7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTJ
|
#ifdef USE_PORTJ
|
||||||
typedef TPin<Portj, 0> Pj0;
|
typedef TPin<Portj, 0> Pj0;
|
||||||
typedef TPin<Portj, 1> Pj1;
|
typedef TPin<Portj, 1> Pj1;
|
||||||
typedef TPin<Portj, 2> Pj2;
|
typedef TPin<Portj, 2> Pj2;
|
||||||
typedef TPin<Portj, 3> Pj3;
|
typedef TPin<Portj, 3> Pj3;
|
||||||
typedef TPin<Portj, 4> Pj4;
|
typedef TPin<Portj, 4> Pj4;
|
||||||
typedef TPin<Portj, 5> Pj5;
|
typedef TPin<Portj, 5> Pj5;
|
||||||
typedef TPin<Portj, 6> Pj6;
|
typedef TPin<Portj, 6> Pj6;
|
||||||
typedef TPin<Portj, 7> Pj7;
|
typedef TPin<Portj, 7> Pj7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTK
|
#ifdef USE_PORTK
|
||||||
typedef TPin<Portk, 0> Pk0;
|
typedef TPin<Portk, 0> Pk0;
|
||||||
typedef TPin<Portk, 1> Pk1;
|
typedef TPin<Portk, 1> Pk1;
|
||||||
typedef TPin<Portk, 2> Pk2;
|
typedef TPin<Portk, 2> Pk2;
|
||||||
typedef TPin<Portk, 3> Pk3;
|
typedef TPin<Portk, 3> Pk3;
|
||||||
typedef TPin<Portk, 4> Pk4;
|
typedef TPin<Portk, 4> Pk4;
|
||||||
typedef TPin<Portk, 5> Pk5;
|
typedef TPin<Portk, 5> Pk5;
|
||||||
typedef TPin<Portk, 6> Pk6;
|
typedef TPin<Portk, 6> Pk6;
|
||||||
typedef TPin<Portk, 7> Pk7;
|
typedef TPin<Portk, 7> Pk7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTQ
|
#ifdef USE_PORTQ
|
||||||
typedef TPin<Portq, 0> Pq0;
|
typedef TPin<Portq, 0> Pq0;
|
||||||
typedef TPin<Portq, 1> Pq1;
|
typedef TPin<Portq, 1> Pq1;
|
||||||
typedef TPin<Portq, 2> Pq2;
|
typedef TPin<Portq, 2> Pq2;
|
||||||
typedef TPin<Portq, 3> Pq3;
|
typedef TPin<Portq, 3> Pq3;
|
||||||
typedef TPin<Portq, 4> Pq4;
|
typedef TPin<Portq, 4> Pq4;
|
||||||
typedef TPin<Portq, 5> Pq5;
|
typedef TPin<Portq, 5> Pq5;
|
||||||
typedef TPin<Portq, 6> Pq6;
|
typedef TPin<Portq, 6> Pq6;
|
||||||
typedef TPin<Portq, 7> Pq7;
|
typedef TPin<Portq, 7> Pq7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PORTR
|
#ifdef USE_PORTR
|
||||||
typedef TPin<Portr, 0> Pr0;
|
typedef TPin<Portr, 0> Pr0;
|
||||||
typedef TPin<Portr, 1> Pr1;
|
typedef TPin<Portr, 1> Pr1;
|
||||||
typedef TPin<Portr, 2> Pr2;
|
typedef TPin<Portr, 2> Pr2;
|
||||||
typedef TPin<Portr, 3> Pr3;
|
typedef TPin<Portr, 3> Pr3;
|
||||||
typedef TPin<Portr, 4> Pr4;
|
typedef TPin<Portr, 4> Pr4;
|
||||||
typedef TPin<Portr, 5> Pr5;
|
typedef TPin<Portr, 5> Pr5;
|
||||||
typedef TPin<Portr, 6> Pr6;
|
typedef TPin<Portr, 6> Pr6;
|
||||||
typedef TPin<Portr, 7> Pr7;
|
typedef TPin<Portr, 7> Pr7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TCCR0A
|
#ifdef USE_TCCR0A
|
||||||
typedef TCom<Tccr0a, COM0A1> Tc0a; //P6
|
typedef TCom<Tccr0a, COM0A1> Tc0a; //P6
|
||||||
typedef TCom<Tccr0a, COM0B1> Tc0b; //P5
|
typedef TCom<Tccr0a, COM0B1> Tc0b; //P5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TCCR1A
|
#ifdef USE_TCCR1A
|
||||||
typedef TCom<Tccr1a, COM1A1> Tc1a; //P9
|
typedef TCom<Tccr1a, COM1A1> Tc1a; //P9
|
||||||
typedef TCom<Tccr1a, COM1B1> Tc1b; //P10
|
typedef TCom<Tccr1a, COM1B1> Tc1b; //P10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TCCR2A
|
#ifdef USE_TCCR2A
|
||||||
typedef TCom<Tccr2a, COM2A1> Tc2a; //P11
|
typedef TCom<Tccr2a, COM2A1> Tc2a; //P11
|
||||||
typedef TCom<Tccr2a, COM2B1> Tc2b; //P3
|
typedef TCom<Tccr2a, COM2B1> Tc2b; //P3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename Tp_pin, typename Tc_bit>
|
template<typename Tp_pin, typename Tc_bit>
|
||||||
class Tp_Tc
|
class Tp_Tc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void SetDir(uint8_t val){
|
static void SetDir(uint8_t val){
|
||||||
if(val)
|
if(val)
|
||||||
SetDirWrite();
|
SetDirWrite();
|
||||||
else SetDirRead();
|
else SetDirRead();
|
||||||
}
|
}
|
||||||
static void SetDirRead(){
|
static void SetDirRead(){
|
||||||
Tp_pin::SetDirRead(); //set pin direction
|
Tp_pin::SetDirRead(); //set pin direction
|
||||||
Tc_bit::Clear(); //disconnect pin from PWM
|
Tc_bit::Clear(); //disconnect pin from PWM
|
||||||
}
|
}
|
||||||
static void SetDirWrite(){
|
static void SetDirWrite(){
|
||||||
Tp_pin::SetDirWrite();
|
Tp_pin::SetDirWrite();
|
||||||
Tc_bit::Clear();
|
Tc_bit::Clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* pin definitions for cases where it's necessary to clear compare output mode bits */
|
/* pin definitions for cases where it's necessary to clear compare output mode bits */
|
||||||
|
|
||||||
//typedef Tp_Tc<Pd3, Tc2b> P3; //Arduino pin 3
|
//typedef Tp_Tc<Pd3, Tc2b> P3; //Arduino pin 3
|
||||||
//typedef Tp_Tc<Pd5, Tc0b> P5; //Arduino pin 5
|
//typedef Tp_Tc<Pd5, Tc0b> P5; //Arduino pin 5
|
||||||
//typedef Tp_Tc<Pd6, Tc0a> P6; //Arduino pin 6
|
//typedef Tp_Tc<Pd6, Tc0a> P6; //Arduino pin 6
|
||||||
//typedef Tp_Tc<Pb1, Tc1a> P9; //Arduino pin 9
|
//typedef Tp_Tc<Pb1, Tc1a> P9; //Arduino pin 9
|
||||||
//typedef Tp_Tc<Pb2, Tc1b> P10; //Arduino pin 10
|
//typedef Tp_Tc<Pb2, Tc1b> P10; //Arduino pin 10
|
||||||
//typedef Tp_Tc<Pb3, Tc2a> P11; //Arduino pin 11
|
//typedef Tp_Tc<Pb3, Tc2a> P11; //Arduino pin 11
|
||||||
|
|
||||||
/* Arduino pin definitions */
|
/* Arduino pin definitions */
|
||||||
#if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__)
|
#if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__)
|
||||||
|
|
||||||
// "Mega" Arduino pin numbers
|
// "Mega" Arduino pin numbers
|
||||||
|
|
||||||
#define P0 Pe0
|
#define P0 Pe0
|
||||||
#define P1 Pe1
|
#define P1 Pe1
|
||||||
#define P2 Pe4
|
#define P2 Pe4
|
||||||
#define P3 Pe5
|
#define P3 Pe5
|
||||||
#define P4 Pg5
|
#define P4 Pg5
|
||||||
#define P5 Pe5
|
#define P5 Pe5
|
||||||
#define P6 Ph3
|
#define P6 Ph3
|
||||||
#define P7 Ph4
|
#define P7 Ph4
|
||||||
|
|
||||||
#define P8 Ph5
|
#define P8 Ph5
|
||||||
#define P9 Ph6
|
#define P9 Ph6
|
||||||
#define P10 Pb4
|
#define P10 Pb4
|
||||||
#define P11 Pb5
|
#define P11 Pb5
|
||||||
#define P12 Pb6
|
#define P12 Pb6
|
||||||
#define P13 Pb7
|
#define P13 Pb7
|
||||||
|
|
||||||
#define P14 Pj1
|
#define P14 Pj1
|
||||||
#define P15 Pj0
|
#define P15 Pj0
|
||||||
#define P16 Ph1
|
#define P16 Ph1
|
||||||
#define P17 Ph0
|
#define P17 Ph0
|
||||||
#define P18 Pd3
|
#define P18 Pd3
|
||||||
#define P19 Pd2
|
#define P19 Pd2
|
||||||
#define P20 Pd1
|
#define P20 Pd1
|
||||||
#define P21 Pd0
|
#define P21 Pd0
|
||||||
|
|
||||||
#define P22 Pa0
|
#define P22 Pa0
|
||||||
#define P23 Pa1
|
#define P23 Pa1
|
||||||
#define P24 Pa2
|
#define P24 Pa2
|
||||||
#define P25 Pa3
|
#define P25 Pa3
|
||||||
#define P26 Pa4
|
#define P26 Pa4
|
||||||
#define P27 Pa5
|
#define P27 Pa5
|
||||||
#define P28 Pa6
|
#define P28 Pa6
|
||||||
#define P29 Pa7
|
#define P29 Pa7
|
||||||
#define P30 Pc7
|
#define P30 Pc7
|
||||||
#define P31 Pc6
|
#define P31 Pc6
|
||||||
#define P32 Pc5
|
#define P32 Pc5
|
||||||
#define P33 Pc4
|
#define P33 Pc4
|
||||||
#define P34 Pc3
|
#define P34 Pc3
|
||||||
#define P35 Pc2
|
#define P35 Pc2
|
||||||
#define P36 Pc1
|
#define P36 Pc1
|
||||||
#define P37 Pc0
|
#define P37 Pc0
|
||||||
|
|
||||||
#define P38 Pd7
|
#define P38 Pd7
|
||||||
#define P39 Pg2
|
#define P39 Pg2
|
||||||
#define P40 Pg1
|
#define P40 Pg1
|
||||||
#define P41 Pg0
|
#define P41 Pg0
|
||||||
#define P42 Pl7
|
#define P42 Pl7
|
||||||
#define P43 Pl6
|
#define P43 Pl6
|
||||||
#define P44 Pl5
|
#define P44 Pl5
|
||||||
#define P45 Pl4
|
#define P45 Pl4
|
||||||
#define P46 Pl3
|
#define P46 Pl3
|
||||||
#define P47 Pl2
|
#define P47 Pl2
|
||||||
#define P48 Pl1
|
#define P48 Pl1
|
||||||
#define P49 Pl0
|
#define P49 Pl0
|
||||||
#define P50 Pb3
|
#define P50 Pb3
|
||||||
#define P51 Pb2
|
#define P51 Pb2
|
||||||
#define P52 Pb1
|
#define P52 Pb1
|
||||||
#define P53 Pb0
|
#define P53 Pb0
|
||||||
|
|
||||||
#endif //"Mega" pin definitions
|
#endif //"Mega" pin definitions
|
||||||
|
|
||||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
|
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
|
||||||
//"Classical" Arduino pin numbers
|
//"Classical" Arduino pin numbers
|
||||||
|
|
||||||
#define P0 Pd0
|
#define P0 Pd0
|
||||||
#define P1 Pd1
|
#define P1 Pd1
|
||||||
#define P2 Pd2
|
#define P2 Pd2
|
||||||
#define P3 Pd3
|
#define P3 Pd3
|
||||||
#define P4 Pd4
|
#define P4 Pd4
|
||||||
#define P5 Pd5
|
#define P5 Pd5
|
||||||
#define P6 Pd6
|
#define P6 Pd6
|
||||||
#define P7 Pd7
|
#define P7 Pd7
|
||||||
|
|
||||||
#define P8 Pb0
|
#define P8 Pb0
|
||||||
#define P9 Pb1
|
#define P9 Pb1
|
||||||
#define P10 Pb2
|
#define P10 Pb2
|
||||||
#define P11 Pb3
|
#define P11 Pb3
|
||||||
#define P12 Pb4
|
#define P12 Pb4
|
||||||
#define P13 Pb5
|
#define P13 Pb5
|
||||||
|
|
||||||
#define P14 Pc0
|
#define P14 Pc0
|
||||||
#define P15 Pc1
|
#define P15 Pc1
|
||||||
#define P16 Pc2
|
#define P16 Pc2
|
||||||
#define P17 Pc3
|
#define P17 Pc3
|
||||||
#define P18 Pc4
|
#define P18 Pc4
|
||||||
#define P19 Pc5
|
#define P19 Pc5
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //_avrpins_h_
|
#endif //_avrpins_h_
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
/* pin numbers to port numbers */
|
/* pin numbers to port numbers */
|
||||||
|
|
||||||
//#define MAX_SS 10
|
//#define MAX_SS 10
|
||||||
//#define MAX_INT 3 // Black Widdow
|
#define MAX_INT 3 // Black Widdow
|
||||||
#define MAX_INT 9 // Duemielanove
|
//#define MAX_INT 9 // Duemielanove
|
||||||
|
|
||||||
#define MAX_GPX 8
|
#define MAX_GPX 8
|
||||||
//#define MAX_RESET 7
|
//#define MAX_RESET 7
|
||||||
|
|
|
@ -249,7 +249,7 @@ 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 = INTR::Read();
|
pinvalue = INTR::IsSet(); //Read();
|
||||||
//pinvalue = digitalRead( MAX_INT );
|
//pinvalue = digitalRead( MAX_INT );
|
||||||
if( pinvalue == LOW ) {
|
if( pinvalue == LOW ) {
|
||||||
rcode = IntHandler();
|
rcode = IntHandler();
|
||||||
|
|
204
usbhub.cpp
204
usbhub.cpp
|
@ -1,35 +1,34 @@
|
||||||
#include "usbhub.h"
|
#include "usbhub.h"
|
||||||
|
|
||||||
|
bool USBHub::bResetInitiated = false;
|
||||||
|
|
||||||
USBHub::USBHub(USB *p) :
|
USBHub::USBHub(USB *p) :
|
||||||
pUsb(p),
|
pUsb(p),
|
||||||
bAddress(0),
|
bAddress(0),
|
||||||
bNbrPorts(0),
|
bNbrPorts(0),
|
||||||
bInitState(0),
|
bInitState(0),
|
||||||
// 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].epAttribs = 0;
|
||||||
epInfo[0].rcvToggle = bmRCVTOG0;
|
epInfo[0].bmNakPower = USB_NAK_MAX_POWER;
|
||||||
|
|
||||||
epInfo[1].epAddr = 1;
|
epInfo[1].epAddr = 1;
|
||||||
epInfo[1].MaxPktSize = 1;
|
epInfo[1].maxPktSize = 1;
|
||||||
epInfo[1].Interval = 0xff;
|
epInfo[1].epAttribs = 0;
|
||||||
epInfo[1].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
|
||||||
epInfo[1].rcvToggle = bmRCVTOG0;
|
|
||||||
|
|
||||||
if (pUsb)
|
if (pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||||
{
|
{
|
||||||
uint8_t buf[32];
|
uint8_t buf[32];
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
UsbDevice *p = NULL;
|
UsbDevice *p = NULL;
|
||||||
EP_RECORD *oldep_ptr = NULL;
|
EpInfo *oldep_ptr = NULL;
|
||||||
uint8_t len = 0;
|
uint8_t len = 0;
|
||||||
uint16_t cd_len = 0;
|
uint16_t cd_len = 0;
|
||||||
|
|
||||||
|
@ -38,8 +37,6 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
switch (bInitState)
|
switch (bInitState)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
Serial.println("Init");
|
|
||||||
|
|
||||||
if (bAddress)
|
if (bAddress)
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||||
|
|
||||||
|
@ -50,10 +47,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
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");
|
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
}
|
|
||||||
|
|
||||||
// Save old pointer to EP_RECORD of address 0
|
// Save old pointer to EP_RECORD of address 0
|
||||||
oldep_ptr = p->epinfo;
|
oldep_ptr = p->epinfo;
|
||||||
|
@ -61,9 +55,13 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
||||||
p->epinfo = epInfo;
|
p->epinfo = epInfo;
|
||||||
|
|
||||||
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
// Get device descriptor
|
// Get device descriptor
|
||||||
rcode = pUsb->getDevDescr( 0, 0, 8, (uint8_t*)buf );
|
rcode = pUsb->getDevDescr( 0, 0, 8, (uint8_t*)buf );
|
||||||
|
|
||||||
|
p->lowspeed = false;
|
||||||
|
|
||||||
if (!rcode)
|
if (!rcode)
|
||||||
len = (buf[0] > 32) ? 32 : buf[0];
|
len = (buf[0] > 32) ? 32 : buf[0];
|
||||||
|
|
||||||
|
@ -71,8 +69,6 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
{
|
{
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
Serial.println("getDevDesc:");
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +84,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from the device descriptor
|
// Extract Max Packet Size from the device descriptor
|
||||||
epInfo[0].MaxPktSize = ((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
epInfo[0].maxPktSize = ((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
||||||
|
|
||||||
// Assign new address to the device
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr( 0, 0, bAddress );
|
rcode = pUsb->setAddr( 0, 0, bAddress );
|
||||||
|
@ -99,14 +95,9 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
Serial.print("setAddr:");
|
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.print("Addr:");
|
|
||||||
Serial.println(bAddress, HEX);
|
|
||||||
|
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
|
@ -117,7 +108,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setDevTableEntry(bAddress, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 2, epInfo);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
@ -159,17 +150,12 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.print("Conf val:");
|
|
||||||
Serial.println(buf[5], HEX);
|
|
||||||
|
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
Serial.println("Hub configured");
|
|
||||||
|
|
||||||
bInitState = 3;
|
bInitState = 3;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -177,8 +163,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
for (uint8_t j=1; j<=bNbrPorts; j++)
|
for (uint8_t j=1; j<=bNbrPorts; j++)
|
||||||
pUsb->HubPortPowerOn(bAddress, j);
|
pUsb->HubPortPowerOn(bAddress, j);
|
||||||
|
|
||||||
Serial.println("Ports powered");
|
pUsb->SetHubPreMask();
|
||||||
|
|
||||||
bPollEnable = true;
|
bPollEnable = true;
|
||||||
bInitState = 0;
|
bInitState = 0;
|
||||||
}
|
}
|
||||||
|
@ -186,31 +171,24 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
Serial.print("getDevDescr:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
Serial.print("setDevTblEn:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailGetHubDescr:
|
FailGetHubDescr:
|
||||||
Serial.print("getHub:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
Serial.print("getConf:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
Serial.print("setConf:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailGetPortStatus:
|
FailGetPortStatus:
|
||||||
Serial.print("GetPortStatus:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,9 +196,11 @@ uint8_t USBHub::Release()
|
||||||
{
|
{
|
||||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
|
|
||||||
|
if (bAddress == 0x41)
|
||||||
|
pUsb->SetHubPreMask();
|
||||||
|
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
bNbrPorts = 0;
|
bNbrPorts = 0;
|
||||||
// bPortResetCounter = 0;
|
|
||||||
qNextPollTime = 0;
|
qNextPollTime = 0;
|
||||||
bPollEnable = false;
|
bPollEnable = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -235,51 +215,27 @@ uint8_t USBHub::Poll()
|
||||||
|
|
||||||
if (qNextPollTime <= millis())
|
if (qNextPollTime <= millis())
|
||||||
{
|
{
|
||||||
Serial.print("Poll:");
|
|
||||||
Serial.println(bAddress, HEX);
|
Serial.println(bAddress, HEX);
|
||||||
|
|
||||||
rcode = GetHubStatus(bAddress);
|
rcode = GetHubStatus(bAddress);
|
||||||
if (rcode)
|
|
||||||
{
|
|
||||||
Serial.print("HubStatus:");
|
|
||||||
Serial.println(rcode,HEX);
|
|
||||||
}
|
|
||||||
qNextPollTime = millis() + 100;
|
qNextPollTime = millis() + 100;
|
||||||
}
|
}
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//bmHUB_PORT_STATUS_C_PORT_CONNECTION
|
|
||||||
//bmHUB_PORT_STATUS_C_PORT_ENABLE
|
|
||||||
//bmHUB_PORT_STATUS_C_PORT_SUSPEND
|
|
||||||
//bmHUB_PORT_STATUS_C_PORT_OVER_CURRENT
|
|
||||||
//bmHUB_PORT_STATUS_C_PORT_RESET
|
|
||||||
|
|
||||||
uint8_t USBHub::GetHubStatus(uint8_t addr)
|
uint8_t USBHub::GetHubStatus(uint8_t addr)
|
||||||
{
|
{
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
uint8_t buf[8];
|
uint8_t buf[8];
|
||||||
|
|
||||||
// uint8_t inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data, unsigned int nak_limit = USB_NAK_LIMIT );
|
rcode = pUsb->inTransfer(addr, 1, 1, buf);
|
||||||
//Serial.println(devtable[1].epinfo->epAddr, HEX);
|
|
||||||
|
|
||||||
rcode = pUsb->inTransfer(addr, 1, 1, buf, 1);
|
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
{
|
|
||||||
Serial.print("inTransfer:");
|
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
|
||||||
Serial.print("Int:");
|
|
||||||
Serial.println(buf[0],HEX);
|
|
||||||
|
|
||||||
//return 0;
|
|
||||||
|
|
||||||
if (buf[0] & 0x01) // Hub Status Change
|
if (buf[0] & 0x01) // Hub Status Change
|
||||||
{
|
{
|
||||||
pUsb->PrintHubStatus(addr);
|
//pUsb->PrintHubStatus(addr);
|
||||||
//rcode = GetHubStatus(1, 0, 1, 4, buf);
|
//rcode = GetHubStatus(1, 0, 1, 4, buf);
|
||||||
//if (rcode)
|
//if (rcode)
|
||||||
//{
|
//{
|
||||||
|
@ -298,91 +254,91 @@ uint8_t USBHub::GetHubStatus(uint8_t addr)
|
||||||
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff);
|
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
{
|
|
||||||
Serial.print("GetPortStatus err:");
|
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
Serial.print("on port:");
|
|
||||||
Serial.println(port, DEC);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
HubPortStatusChange(addr, port, evt);
|
rcode = HubPortStatusChange(addr, port, evt);
|
||||||
|
|
||||||
|
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (rcode)
|
||||||
|
return rcode;
|
||||||
}
|
}
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
|
for (uint8_t port=1; port<=bNbrPorts; port++)
|
||||||
|
{
|
||||||
|
HubEvent evt;
|
||||||
|
evt.bmEvent = 0;
|
||||||
|
|
||||||
|
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff);
|
||||||
|
|
||||||
|
if (rcode)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((evt.bmStatus & bmHUB_PORT_STATE_CHECK_DISABLED) != bmHUB_PORT_STATE_DISABLED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Emulate connection event for the port
|
||||||
|
evt.bmChange |= bmHUB_PORT_STATUS_C_PORT_CONNECTION;
|
||||||
|
|
||||||
|
rcode = HubPortStatusChange(addr, port, evt);
|
||||||
|
|
||||||
|
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (rcode)
|
||||||
|
return rcode;
|
||||||
|
} // for
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
|
uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
|
||||||
{
|
{
|
||||||
Serial.print("Prt:");
|
|
||||||
Serial.print(port,HEX);
|
|
||||||
|
|
||||||
Serial.print("\tEvt:");
|
|
||||||
Serial.println(evt.bmEvent,HEX);
|
|
||||||
Serial.print("\tSt:");
|
|
||||||
Serial.println(evt.bmStatus,HEX);
|
|
||||||
Serial.print("\tCh:");
|
|
||||||
Serial.println(evt.bmChange,HEX);
|
|
||||||
|
|
||||||
|
|
||||||
//Serial.print("Con:");
|
|
||||||
//Serial.println(bmHUB_PORT_EVENT_CONNECT, HEX);
|
|
||||||
|
|
||||||
//Serial.print("Rc:");
|
|
||||||
//Serial.println(bmHUB_PORT_EVENT_RESET_COMPLETE, HEX);
|
|
||||||
|
|
||||||
PrintHubPortStatus(pUsb, addr, port, true);
|
|
||||||
|
|
||||||
switch (evt.bmEvent)
|
switch (evt.bmEvent)
|
||||||
{
|
{
|
||||||
//case (bmHUB_PORT_STATE_DISABLED | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_SUSPEND):
|
|
||||||
// Serial.println("DIS");
|
|
||||||
// pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_PORT_ENABLE | HUB_FEATURE_C_PORT_CONNECTION);
|
|
||||||
// pUsb->HubPortReset(addr, port);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// Device connected event
|
// Device connected event
|
||||||
case bmHUB_PORT_EVENT_CONNECT:
|
case bmHUB_PORT_EVENT_CONNECT:
|
||||||
Serial.println("CON");
|
case bmHUB_PORT_EVENT_LS_CONNECT:
|
||||||
|
if (bResetInitiated)
|
||||||
|
return 0;
|
||||||
|
|
||||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_ENABLE);
|
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_ENABLE);
|
||||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION);
|
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION);
|
||||||
pUsb->HubPortReset(addr, port);
|
pUsb->HubPortReset(addr, port);
|
||||||
break;
|
bResetInitiated = true;
|
||||||
|
return HUB_ERROR_PORT_HAS_BEEN_RESET;
|
||||||
|
|
||||||
|
// Device disconnected event
|
||||||
|
case bmHUB_PORT_EVENT_DISCONNECT:
|
||||||
|
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_ENABLE);
|
||||||
|
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION);
|
||||||
|
bResetInitiated = false;
|
||||||
|
|
||||||
|
UsbDeviceAddress a;
|
||||||
|
a.bmHub = 0;
|
||||||
|
a.bmParent = addr;
|
||||||
|
a.bmAddress = port;
|
||||||
|
pUsb->ReleaseDevice(a.devAddress);
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Reset complete event
|
// Reset complete event
|
||||||
case bmHUB_PORT_EVENT_RESET_COMPLETE:
|
case bmHUB_PORT_EVENT_RESET_COMPLETE:
|
||||||
Serial.println("RCMPL");
|
case bmHUB_PORT_EVENT_LS_RESET_COMPLETE:
|
||||||
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
|
delay(20);
|
||||||
if (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
|
||||||
{
|
|
||||||
UsbDevice *p = pUsb->GetAddressPool().GetUsbDevicePtr(addr);
|
|
||||||
|
|
||||||
if (p)
|
a.devAddress = addr;
|
||||||
p->lowspeed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(50);
|
pUsb->Configuring(a.bmAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED) );
|
||||||
|
bResetInitiated = false;
|
||||||
pUsb->Configuring(addr, port);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Suspended or resuming state
|
|
||||||
case bmHUB_PORT_STATE_SUSPENDED:
|
|
||||||
Serial.println("SUSP");
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Resume complete event
|
|
||||||
case (bmHUB_PORT_STATE_ENABLED | HUB_FEATURE_C_PORT_SUSPEND):
|
|
||||||
break;
|
|
||||||
|
|
||||||
//case bmHUB_PORT_STATE_RESUMING:
|
|
||||||
// break;
|
|
||||||
|
|
||||||
} // switch (evt.bmEvent)
|
} // switch (evt.bmEvent)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes)
|
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes)
|
||||||
{
|
{
|
||||||
uint8_t rcode = 0;
|
uint8_t rcode = 0;
|
||||||
|
|
54
usbhub.h
54
usbhub.h
|
@ -19,25 +19,27 @@
|
||||||
#define USB_STATE_HUB_PORT_RESETTING 0xb5
|
#define USB_STATE_HUB_PORT_RESETTING 0xb5
|
||||||
#define USB_STATE_HUB_PORT_ENABLED 0xb6
|
#define USB_STATE_HUB_PORT_ENABLED 0xb6
|
||||||
|
|
||||||
|
// Additional Error Codes
|
||||||
|
#define HUB_ERROR_PORT_HAS_BEEN_RESET 0xb1
|
||||||
|
|
||||||
|
|
||||||
// The bit mask to check for all necessary state bits
|
// The bit mask to check for all necessary state bits
|
||||||
#define bmHUB_PORT_STATUS_ALL_MAIN ((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_ENABLE | bmHUB_PORT_STATUS_C_PORT_SUSPEND | bmHUB_PORT_STATUS_C_PORT_RESET) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_SUSPEND)
|
#define bmHUB_PORT_STATUS_ALL_MAIN ((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_ENABLE | bmHUB_PORT_STATUS_C_PORT_SUSPEND | bmHUB_PORT_STATUS_C_PORT_RESET) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_SUSPEND)
|
||||||
|
|
||||||
|
// Bit mask to check for DISABLED state in HubEvent::bmStatus field
|
||||||
|
#define bmHUB_PORT_STATE_CHECK_DISABLED (0x0000 | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_SUSPEND)
|
||||||
|
|
||||||
// Hub Port States
|
// Hub Port States
|
||||||
//#define bmHUB_PORT_STATE_POWERED ((0UL | bmHUB_PORT_STATUS_PORT_POWER) << 16)
|
#define bmHUB_PORT_STATE_DISABLED (0x0000 | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
||||||
#define bmHUB_PORT_STATE_DISCONNECTED ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE) << 16)
|
|
||||||
|
|
||||||
#define bmHUB_PORT_STATE_DISABLED ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION))
|
|
||||||
|
|
||||||
#define bmHUB_PORT_STATE_RESETTING ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_RESET) << 16)
|
|
||||||
#define bmHUB_PORT_STATE_ENABLED ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE) << 16)
|
|
||||||
#define bmHUB_PORT_STATE_SUSPENDED ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_SUSPEND) << 16)
|
|
||||||
|
|
||||||
// Hub Port Events
|
// Hub Port Events
|
||||||
#define bmHUB_PORT_EVENT_CONNECT (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATE_DISABLED)
|
#define bmHUB_PORT_EVENT_CONNECT (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
||||||
|
#define bmHUB_PORT_EVENT_DISCONNECT (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATUS_PORT_POWER)
|
||||||
#define bmHUB_PORT_EVENT_RESET_COMPLETE (((0UL | bmHUB_PORT_STATUS_C_PORT_RESET) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
#define bmHUB_PORT_EVENT_RESET_COMPLETE (((0UL | bmHUB_PORT_STATUS_C_PORT_RESET) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
||||||
|
|
||||||
#define bmHUB_PORT_EVENT_PORT_ENABLED (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_ENABLE) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
#define bmHUB_PORT_EVENT_LS_CONNECT (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
||||||
|
#define bmHUB_PORT_EVENT_LS_RESET_COMPLETE (((0UL | bmHUB_PORT_STATUS_C_PORT_RESET) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
||||||
|
#define bmHUB_PORT_EVENT_LS_PORT_ENABLED (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_ENABLE) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
||||||
|
|
||||||
struct HubEvent
|
struct HubEvent
|
||||||
{
|
{
|
||||||
|
@ -56,50 +58,30 @@ struct HubEvent
|
||||||
|
|
||||||
class USBHub : USBDeviceConfig
|
class USBHub : USBDeviceConfig
|
||||||
{
|
{
|
||||||
|
static bool bResetInitiated; // True when reset is triggered
|
||||||
|
|
||||||
USB *pUsb; // USB class instance pointer
|
USB *pUsb; // USB class instance pointer
|
||||||
|
|
||||||
EP_RECORD epInfo[2]; // interrupt endpoint info structure
|
EpInfo epInfo[2]; // interrupt endpoint info structure
|
||||||
|
|
||||||
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
|
|
||||||
uint32_t qNextPollTime; // next poll time
|
uint32_t qNextPollTime; // next poll time
|
||||||
bool bPollEnable; // poll enable flag
|
bool bPollEnable; // poll enable flag
|
||||||
|
|
||||||
uint8_t GetHubStatus(uint8_t addr);
|
uint8_t GetHubStatus(uint8_t addr);
|
||||||
void HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt);
|
uint8_t HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
USBHub(USB *p);
|
USBHub(USB *p);
|
||||||
|
|
||||||
virtual uint8_t Init(uint8_t parent, uint8_t port);
|
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
||||||
virtual uint8_t Release();
|
virtual uint8_t Release();
|
||||||
virtual uint8_t Poll();
|
virtual uint8_t Poll();
|
||||||
|
virtual uint8_t GetAddress() { return bAddress; };
|
||||||
};
|
};
|
||||||
|
|
||||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);
|
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------
|
|
||||||
// | H | H | H | P | P | P | S | S |
|
|
||||||
// ---------------------------------
|
|
||||||
// H - hub ID
|
|
||||||
// P - port number
|
|
||||||
// S - port state
|
|
||||||
|
|
||||||
struct UsbHubPortState
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint8_t bmState : 2;
|
|
||||||
uint8_t bmPort : 3;
|
|
||||||
uint8_t bmHub : 3;
|
|
||||||
};
|
|
||||||
uint8_t portState;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __USBHUB_H__
|
#endif // __USBHUB_H__
|
Loading…
Reference in a new issue