Stripped down arduino host shield library
This commit is contained in:
@@ -32,17 +32,11 @@ e-mail : support@circuitsathome.com
|
|||||||
|
|
||||||
// None of these should ever be included by a driver, or a user's sketch.
|
// None of these should ever be included by a driver, or a user's sketch.
|
||||||
#include "../lib/hostshield/settings.h"
|
#include "../lib/hostshield/settings.h"
|
||||||
#include "../lib/hostshield/printhex.h"
|
|
||||||
#include "../lib/hostshield/message.h"
|
|
||||||
#include "../lib/hostshield/hexdump.h"
|
|
||||||
#include "../lib/hostshield/sink_parser.h"
|
|
||||||
#include "../lib/hostshield/max3421e.h"
|
#include "../lib/hostshield/max3421e.h"
|
||||||
#include "../lib/hostshield/address.h"
|
#include "../lib/hostshield/address.h"
|
||||||
#include "../lib/hostshield/avrpins.h"
|
#include "../lib/hostshield/avrpins.h"
|
||||||
#include "../lib/hostshield/usb_ch9.h"
|
#include "../lib/hostshield/usb_ch9.h"
|
||||||
#include "../lib/hostshield/usbhost.h"
|
#include "../lib/hostshield/usbhost.h"
|
||||||
#include "../lib/hostshield/UsbCore.h"
|
#include "../lib/hostshield/UsbCore.h"
|
||||||
#include "../lib/hostshield/parsetools.h"
|
|
||||||
#include "../lib/hostshield/confdescparser.h"
|
|
||||||
|
|
||||||
#endif //_usb_h_
|
#endif //_usb_h_
|
||||||
|
|||||||
@@ -243,12 +243,9 @@ uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t*
|
|||||||
|
|
||||||
uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
|
uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
|
||||||
|
|
||||||
if(rcode) {
|
if(rcode)
|
||||||
USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81);
|
|
||||||
USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81);
|
|
||||||
USBTRACE3("(USB::InTransfer) ep requested ", ep, 0x81);
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
|
||||||
return InTransfer(pep, nak_limit, nbytesptr, data, bInterval);
|
return InTransfer(pep, nak_limit, nbytesptr, data, bInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,217 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
#if !defined(_usb_h_) || defined(__CONFDESCPARSER_H__)
|
|
||||||
#error "Never include confdescparser.h directly; include Usb.h instead"
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define __CONFDESCPARSER_H__
|
|
||||||
|
|
||||||
class UsbConfigXtracter {
|
|
||||||
public:
|
|
||||||
//virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0;
|
|
||||||
//virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0;
|
|
||||||
|
|
||||||
virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CP_MASK_COMPARE_CLASS 1
|
|
||||||
#define CP_MASK_COMPARE_SUBCLASS 2
|
|
||||||
#define CP_MASK_COMPARE_PROTOCOL 4
|
|
||||||
#define CP_MASK_COMPARE_ALL 7
|
|
||||||
|
|
||||||
// Configuration Descriptor Parser Class Template
|
|
||||||
|
|
||||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
|
||||||
class ConfigDescParser : public USBReadParser {
|
|
||||||
UsbConfigXtracter *theXtractor;
|
|
||||||
MultiValueBuffer theBuffer;
|
|
||||||
MultiByteValueParser valParser;
|
|
||||||
ByteSkipper theSkipper;
|
|
||||||
uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
|
|
||||||
|
|
||||||
uint8_t stateParseDescr; // ParseDescriptor state
|
|
||||||
|
|
||||||
uint8_t dscrLen; // Descriptor length
|
|
||||||
uint8_t dscrType; // Descriptor type
|
|
||||||
|
|
||||||
bool isGoodInterface; // Apropriate interface flag
|
|
||||||
uint8_t confValue; // Configuration value
|
|
||||||
uint8_t protoValue; // Protocol value
|
|
||||||
uint8_t ifaceNumber; // Interface number
|
|
||||||
uint8_t ifaceAltSet; // Interface alternate settings
|
|
||||||
|
|
||||||
bool UseOr;
|
|
||||||
bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn);
|
|
||||||
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void SetOR(void) {
|
|
||||||
UseOr = true;
|
|
||||||
}
|
|
||||||
ConfigDescParser(UsbConfigXtracter *xtractor);
|
|
||||||
void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
|
||||||
ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ConfigDescParser(UsbConfigXtracter *xtractor) :
|
|
||||||
theXtractor(xtractor),
|
|
||||||
stateParseDescr(0),
|
|
||||||
dscrLen(0),
|
|
||||||
dscrType(0),
|
|
||||||
UseOr(false) {
|
|
||||||
theBuffer.pValue = varBuffer;
|
|
||||||
valParser.Initialize(&theBuffer);
|
|
||||||
theSkipper.Initialize(&theBuffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
|
||||||
void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset __attribute__((unused))) {
|
|
||||||
uint16_t cntdn = (uint16_t)len;
|
|
||||||
uint8_t *p = (uint8_t*)pbuf;
|
|
||||||
|
|
||||||
while(cntdn)
|
|
||||||
if(!ParseDescriptor(&p, &cntdn))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parser for the configuration descriptor. Takes values for class, subclass, protocol fields in interface descriptor and
|
|
||||||
compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
|
|
||||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
|
||||||
bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) {
|
|
||||||
USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
|
|
||||||
USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer);
|
|
||||||
switch(stateParseDescr) {
|
|
||||||
case 0:
|
|
||||||
theBuffer.valueSize = 2;
|
|
||||||
valParser.Initialize(&theBuffer);
|
|
||||||
stateParseDescr = 1;
|
|
||||||
case 1:
|
|
||||||
if(!valParser.Parse(pp, pcntdn))
|
|
||||||
return false;
|
|
||||||
dscrLen = *((uint8_t*)theBuffer.pValue);
|
|
||||||
dscrType = *((uint8_t*)theBuffer.pValue + 1);
|
|
||||||
stateParseDescr = 2;
|
|
||||||
case 2:
|
|
||||||
// This is a sort of hack. Assuming that two bytes are all ready in the buffer
|
|
||||||
// the pointer is positioned two bytes ahead in order for the rest of descriptor
|
|
||||||
// to be read right after the size and the type fields.
|
|
||||||
// This should be used carefully. varBuffer should be used directly to handle data
|
|
||||||
// in the buffer.
|
|
||||||
theBuffer.pValue = varBuffer + 2;
|
|
||||||
stateParseDescr = 3;
|
|
||||||
case 3:
|
|
||||||
switch(dscrType) {
|
|
||||||
case USB_DESCRIPTOR_INTERFACE:
|
|
||||||
isGoodInterface = false;
|
|
||||||
break;
|
|
||||||
case USB_DESCRIPTOR_CONFIGURATION:
|
|
||||||
case USB_DESCRIPTOR_ENDPOINT:
|
|
||||||
case HID_DESCRIPTOR_HID:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
theBuffer.valueSize = dscrLen - 2;
|
|
||||||
valParser.Initialize(&theBuffer);
|
|
||||||
stateParseDescr = 4;
|
|
||||||
case 4:
|
|
||||||
switch(dscrType) {
|
|
||||||
case USB_DESCRIPTOR_CONFIGURATION:
|
|
||||||
if(!valParser.Parse(pp, pcntdn))
|
|
||||||
return false;
|
|
||||||
confValue = ucd->bConfigurationValue;
|
|
||||||
break;
|
|
||||||
case USB_DESCRIPTOR_INTERFACE:
|
|
||||||
if(!valParser.Parse(pp, pcntdn))
|
|
||||||
return false;
|
|
||||||
if((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID)
|
|
||||||
break;
|
|
||||||
if((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID)
|
|
||||||
break;
|
|
||||||
if(UseOr) {
|
|
||||||
if((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol)))
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
if((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
isGoodInterface = true;
|
|
||||||
ifaceNumber = uid->bInterfaceNumber;
|
|
||||||
ifaceAltSet = uid->bAlternateSetting;
|
|
||||||
protoValue = uid->bInterfaceProtocol;
|
|
||||||
break;
|
|
||||||
case USB_DESCRIPTOR_ENDPOINT:
|
|
||||||
if(!valParser.Parse(pp, pcntdn))
|
|
||||||
return false;
|
|
||||||
if(isGoodInterface)
|
|
||||||
if(theXtractor)
|
|
||||||
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
|
|
||||||
break;
|
|
||||||
//case HID_DESCRIPTOR_HID:
|
|
||||||
// if (!valParser.Parse(pp, pcntdn))
|
|
||||||
// return false;
|
|
||||||
// PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
|
|
||||||
// break;
|
|
||||||
default:
|
|
||||||
if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
theBuffer.pValue = varBuffer;
|
|
||||||
stateParseDescr = 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
|
||||||
void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc) {
|
|
||||||
Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80);
|
|
||||||
Notify(PSTR("bDescLength:\t\t"), 0x80);
|
|
||||||
PrintHex<uint8_t > (pDesc->bLength, 0x80);
|
|
||||||
|
|
||||||
Notify(PSTR("\r\nbDescriptorType:\t"), 0x80);
|
|
||||||
PrintHex<uint8_t > (pDesc->bDescriptorType, 0x80);
|
|
||||||
|
|
||||||
Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80);
|
|
||||||
PrintHex<uint16_t > (pDesc->bcdHID, 0x80);
|
|
||||||
|
|
||||||
Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80);
|
|
||||||
PrintHex<uint8_t > (pDesc->bCountryCode, 0x80);
|
|
||||||
|
|
||||||
Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80);
|
|
||||||
PrintHex<uint8_t > (pDesc->bNumDescriptors, 0x80);
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < pDesc->bNumDescriptors; i++) {
|
|
||||||
HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType);
|
|
||||||
|
|
||||||
Notify(PSTR("\r\nbDescrType:\t\t"), 0x80);
|
|
||||||
PrintHex<uint8_t > (pLT[i].bDescrType, 0x80);
|
|
||||||
|
|
||||||
Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80);
|
|
||||||
PrintHex<uint16_t > (pLT[i].wDescriptorLength, 0x80);
|
|
||||||
}
|
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __CONFDESCPARSER_H__
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_usb_h_) || defined(__HEXDUMP_H__)
|
|
||||||
#error "Never include hexdump.h directly; include Usb.h instead"
|
|
||||||
#else
|
|
||||||
#define __HEXDUMP_H__
|
|
||||||
|
|
||||||
extern int UsbDEBUGlvl;
|
|
||||||
|
|
||||||
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
|
||||||
class HexDumper : public BASE_CLASS {
|
|
||||||
uint8_t byteCount;
|
|
||||||
OFFSET_TYPE byteTotal;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
HexDumper() : byteCount(0), byteTotal(0) {
|
|
||||||
};
|
|
||||||
|
|
||||||
void Initialize() {
|
|
||||||
byteCount = 0;
|
|
||||||
byteTotal = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
|
||||||
void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset __attribute__((unused))) {
|
|
||||||
if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug.
|
|
||||||
for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
|
|
||||||
if(!byteCount) {
|
|
||||||
PrintHex<OFFSET_TYPE > (byteTotal, 0x80);
|
|
||||||
E_Notify(PSTR(": "), 0x80);
|
|
||||||
}
|
|
||||||
PrintHex<uint8_t > (pbuf[j], 0x80);
|
|
||||||
E_Notify(PSTR(" "), 0x80);
|
|
||||||
|
|
||||||
if(byteCount == 15) {
|
|
||||||
E_Notify(PSTR("\r\n"), 0x80);
|
|
||||||
byteCount = 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __HEXDUMP_H__
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_usb_h_) || defined(MACROS_H)
|
|
||||||
#error "Never include macros.h directly; include Usb.h instead"
|
|
||||||
#else
|
|
||||||
#define MACROS_H
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// HANDY MACROS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define VALUE_BETWEEN(v,l,h) (((v)>(l)) && ((v)<(h)))
|
|
||||||
#define VALUE_WITHIN(v,l,h) (((v)>=(l)) && ((v)<=(h)))
|
|
||||||
#define output_pgm_message(wa,fp,mp,el) wa = &mp, fp((char *)pgm_read_pointer(wa), el)
|
|
||||||
#define output_if_between(v,l,h,wa,fp,mp,el) if(VALUE_BETWEEN(v,l,h)) output_pgm_message(wa,fp,mp[v-(l+1)],el);
|
|
||||||
|
|
||||||
#define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
|
|
||||||
#ifndef __BYTE_GRABBING_DEFINED__
|
|
||||||
#define __BYTE_GRABBING_DEFINED__ 1
|
|
||||||
#ifdef BROKEN_OPTIMIZER_LITTLE_ENDIAN
|
|
||||||
// Note: Use this if your compiler generates horrible assembler!
|
|
||||||
#define BGRAB0(__usi__) (((uint8_t *)&(__usi__))[0])
|
|
||||||
#define BGRAB1(__usi__) (((uint8_t *)&(__usi__))[1])
|
|
||||||
#define BGRAB2(__usi__) (((uint8_t *)&(__usi__))[2])
|
|
||||||
#define BGRAB3(__usi__) (((uint8_t *)&(__usi__))[3])
|
|
||||||
#define BGRAB4(__usi__) (((uint8_t *)&(__usi__))[4])
|
|
||||||
#define BGRAB5(__usi__) (((uint8_t *)&(__usi__))[5])
|
|
||||||
#define BGRAB6(__usi__) (((uint8_t *)&(__usi__))[6])
|
|
||||||
#define BGRAB7(__usi__) (((uint8_t *)&(__usi__))[7])
|
|
||||||
#else
|
|
||||||
// Note: The cast alone to uint8_t is actually enough.
|
|
||||||
// GCC throws out the "& 0xff", and the size is no different.
|
|
||||||
// Some compilers need it.
|
|
||||||
#define BGRAB0(__usi__) ((uint8_t)((__usi__) & 0xff ))
|
|
||||||
#define BGRAB1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xff))
|
|
||||||
#define BGRAB2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xff))
|
|
||||||
#define BGRAB3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xff))
|
|
||||||
#define BGRAB4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xff))
|
|
||||||
#define BGRAB5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xff))
|
|
||||||
#define BGRAB6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xff))
|
|
||||||
#define BGRAB7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xff))
|
|
||||||
#endif
|
|
||||||
#define BOVER1(__usi__) ((uint16_t)(__usi__) << 8)
|
|
||||||
#define BOVER2(__usi__) ((uint32_t)(__usi__) << 16)
|
|
||||||
#define BOVER3(__usi__) ((uint32_t)(__usi__) << 24)
|
|
||||||
#define BOVER4(__usi__) ((uint64_t)(__usi__) << 32)
|
|
||||||
#define BOVER5(__usi__) ((uint64_t)(__usi__) << 40)
|
|
||||||
#define BOVER6(__usi__) ((uint64_t)(__usi__) << 48)
|
|
||||||
#define BOVER7(__usi__) ((uint64_t)(__usi__) << 56)
|
|
||||||
|
|
||||||
// These are the smallest and fastest ways I have found so far in pure C/C++.
|
|
||||||
#define BMAKE16(__usc1__,__usc0__) ((uint16_t)((uint16_t)(__usc0__) | (uint16_t)BOVER1(__usc1__)))
|
|
||||||
#define BMAKE32(__usc3__,__usc2__,__usc1__,__usc0__) ((uint32_t)((uint32_t)(__usc0__) | (uint32_t)BOVER1(__usc1__) | (uint32_t)BOVER2(__usc2__) | (uint32_t)BOVER3(__usc3__)))
|
|
||||||
#define BMAKE64(__usc7__,__usc6__,__usc5__,__usc4__,__usc3__,__usc2__,__usc1__,__usc0__) ((uint64_t)((uint64_t)__usc0__ | (uint64_t)BOVER1(__usc1__) | (uint64_t)BOVER2(__usc2__) | (uint64_t)BOVER3(__usc3__) | (uint64_t)BOVER4(__usc4__) | (uint64_t)BOVER5(__usc5__) | (uint64_t)BOVER6(__usc6__) | (uint64_t)BOVER1(__usc7__)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Debug macros: Strings are stored in progmem (flash) instead of RAM.
|
|
||||||
*/
|
|
||||||
#define USBTRACE(s) (Notify(PSTR(s), 0x80))
|
|
||||||
#define USBTRACE1(s,l) (Notify(PSTR(s), l))
|
|
||||||
#define USBTRACE2(s,r) (Notify(PSTR(s), 0x80), D_PrintHex((r), 0x80), Notify(PSTR("\r\n"), 0x80))
|
|
||||||
#define USBTRACE3(s,r,l) (Notify(PSTR(s), l), D_PrintHex((r), l), Notify(PSTR("\r\n"), l))
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MACROS_H */
|
|
||||||
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../../include/Usb.h"
|
|
||||||
// 0x80 is the default (i.e. trace) to turn off set this global to something lower.
|
|
||||||
// this allows for 126 other debugging levels.
|
|
||||||
// TO-DO: Allow assignment to a different serial port by software
|
|
||||||
int UsbDEBUGlvl = 0x80;
|
|
||||||
|
|
||||||
void E_Notifyc(char c, int lvl) {
|
|
||||||
if(UsbDEBUGlvl < lvl) return;
|
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
|
||||||
USB_HOST_SERIAL.print(c);
|
|
||||||
#else
|
|
||||||
USB_HOST_SERIAL.print(c, BYTE);
|
|
||||||
#endif
|
|
||||||
//USB_HOST_SERIAL.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void E_Notify(char const * msg, int lvl) {
|
|
||||||
if(UsbDEBUGlvl < lvl) return;
|
|
||||||
if(!msg) return;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
while((c = pgm_read_byte(msg++))) E_Notifyc(c, lvl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void E_NotifyStr(char const * msg, int lvl) {
|
|
||||||
if(UsbDEBUGlvl < lvl) return;
|
|
||||||
if(!msg) return;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
while((c = *msg++)) E_Notifyc(c, lvl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void E_Notify(uint8_t b, int lvl) {
|
|
||||||
if(UsbDEBUGlvl < lvl) return;
|
|
||||||
#if defined(ARDUINO) && ARDUINO >=100
|
|
||||||
USB_HOST_SERIAL.print(b);
|
|
||||||
#else
|
|
||||||
USB_HOST_SERIAL.print(b, DEC);
|
|
||||||
#endif
|
|
||||||
//USB_HOST_SERIAL.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void E_Notify(double d, int lvl) {
|
|
||||||
if(UsbDEBUGlvl < lvl) return;
|
|
||||||
USB_HOST_SERIAL.print(d);
|
|
||||||
//USB_HOST_SERIAL.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
|
||||||
|
|
||||||
void NotifyFailGetDevDescr(void) {
|
|
||||||
Notify(PSTR("\r\ngetDevDescr "), 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFailSetDevTblEntry(void) {
|
|
||||||
Notify(PSTR("\r\nsetDevTblEn "), 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFailGetConfDescr(void) {
|
|
||||||
Notify(PSTR("\r\ngetConf "), 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFailSetConfDescr(void) {
|
|
||||||
Notify(PSTR("\r\nsetConf "), 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFailGetDevDescr(uint8_t reason) {
|
|
||||||
NotifyFailGetDevDescr();
|
|
||||||
NotifyFail(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFailSetDevTblEntry(uint8_t reason) {
|
|
||||||
NotifyFailSetDevTblEntry();
|
|
||||||
NotifyFail(reason);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFailGetConfDescr(uint8_t reason) {
|
|
||||||
NotifyFailGetConfDescr();
|
|
||||||
NotifyFail(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFailSetConfDescr(uint8_t reason) {
|
|
||||||
NotifyFailSetConfDescr();
|
|
||||||
NotifyFail(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID) {
|
|
||||||
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
|
|
||||||
D_PrintHex<uint16_t > (VID, 0x80);
|
|
||||||
Notify(PSTR(" PID: "), 0x80);
|
|
||||||
D_PrintHex<uint16_t > (PID, 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotifyFail(uint8_t rcode) {
|
|
||||||
D_PrintHex<uint8_t > (rcode, 0x80);
|
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
#if !defined(_usb_h_) || defined(__MESSAGE_H__)
|
|
||||||
#error "Never include message.h directly; include Usb.h instead"
|
|
||||||
#else
|
|
||||||
#define __MESSAGE_H__
|
|
||||||
|
|
||||||
extern int UsbDEBUGlvl;
|
|
||||||
|
|
||||||
void E_Notify(char const * msg, int lvl);
|
|
||||||
void E_Notify(uint8_t b, int lvl);
|
|
||||||
void E_NotifyStr(char const * msg, int lvl);
|
|
||||||
void E_Notifyc(char c, int lvl);
|
|
||||||
|
|
||||||
#ifdef DEBUG_USB_HOST
|
|
||||||
#define Notify E_Notify
|
|
||||||
#define NotifyStr E_NotifyStr
|
|
||||||
#define Notifyc E_Notifyc
|
|
||||||
void NotifyFailGetDevDescr(uint8_t reason);
|
|
||||||
void NotifyFailSetDevTblEntry(uint8_t reason);
|
|
||||||
void NotifyFailGetConfDescr(uint8_t reason);
|
|
||||||
void NotifyFailSetConfDescr(uint8_t reason);
|
|
||||||
void NotifyFailGetDevDescr(void);
|
|
||||||
void NotifyFailSetDevTblEntry(void);
|
|
||||||
void NotifyFailGetConfDescr(void);
|
|
||||||
void NotifyFailSetConfDescr(void);
|
|
||||||
void NotifyFailUnknownDevice(uint16_t VID, uint16_t PID);
|
|
||||||
void NotifyFail(uint8_t rcode);
|
|
||||||
#else
|
|
||||||
#define Notify(...) ((void)0)
|
|
||||||
#define NotifyStr(...) ((void)0)
|
|
||||||
#define Notifyc(...) ((void)0)
|
|
||||||
#define NotifyFailGetDevDescr(...) ((void)0)
|
|
||||||
#define NotifyFailSetDevTblEntry(...) ((void)0)
|
|
||||||
#define NotifyFailGetConfDescr(...) ((void)0)
|
|
||||||
#define NotifyFailGetDevDescr(...) ((void)0)
|
|
||||||
#define NotifyFailSetDevTblEntry(...) ((void)0)
|
|
||||||
#define NotifyFailGetConfDescr(...) ((void)0)
|
|
||||||
#define NotifyFailSetConfDescr(...) ((void)0)
|
|
||||||
#define NotifyFailUnknownDevice(...) ((void)0)
|
|
||||||
#define NotifyFail(...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class ERROR_TYPE>
|
|
||||||
void ErrorMessage(uint8_t level, char const * msg, ERROR_TYPE rcode = 0) {
|
|
||||||
#ifdef DEBUG_USB_HOST
|
|
||||||
Notify(msg, level);
|
|
||||||
Notify(PSTR(": "), level);
|
|
||||||
D_PrintHex<ERROR_TYPE > (rcode, level);
|
|
||||||
Notify(PSTR("\r\n"), level);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ERROR_TYPE>
|
|
||||||
void ErrorMessage(char const * msg __attribute__((unused)), ERROR_TYPE rcode __attribute__((unused)) = 0) {
|
|
||||||
#ifdef DEBUG_USB_HOST
|
|
||||||
Notify(msg, 0x80);
|
|
||||||
Notify(PSTR(": "), 0x80);
|
|
||||||
D_PrintHex<ERROR_TYPE > (rcode, 0x80);
|
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __MESSAGE_H__
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
#include "../../include/Usb.h"
|
|
||||||
|
|
||||||
bool MultiByteValueParser::Parse(uint8_t **pp, uint16_t *pcntdn) {
|
|
||||||
if(!pBuf) {
|
|
||||||
Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for(; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++)
|
|
||||||
pBuf[valueSize - countDown] = (**pp);
|
|
||||||
|
|
||||||
if(countDown)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
countDown = valueSize;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me) {
|
|
||||||
switch(nStage) {
|
|
||||||
case 0:
|
|
||||||
pBuf->valueSize = lenSize;
|
|
||||||
theParser.Initialize(pBuf);
|
|
||||||
nStage = 1;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
if(!theParser.Parse(pp, pcntdn))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
arLen = 0;
|
|
||||||
arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue));
|
|
||||||
arLenCntdn = arLen;
|
|
||||||
nStage = 2;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
pBuf->valueSize = valSize;
|
|
||||||
theParser.Initialize(pBuf);
|
|
||||||
nStage = 3;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
for(; arLenCntdn; arLenCntdn--) {
|
|
||||||
if(!theParser.Parse(pp, pcntdn))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(pf)
|
|
||||||
pf(pBuf, (arLen - arLenCntdn), me);
|
|
||||||
}
|
|
||||||
|
|
||||||
nStage = 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_usb_h_) || defined(__PARSETOOLS_H__)
|
|
||||||
#error "Never include parsetools.h directly; include Usb.h instead"
|
|
||||||
#else
|
|
||||||
#define __PARSETOOLS_H__
|
|
||||||
|
|
||||||
struct MultiValueBuffer {
|
|
||||||
uint8_t valueSize;
|
|
||||||
void *pValue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
MultiValueBuffer() : valueSize(0), pValue(NULL) {
|
|
||||||
};
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
class MultiByteValueParser {
|
|
||||||
uint8_t * pBuf;
|
|
||||||
uint8_t countDown;
|
|
||||||
uint8_t valueSize;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) {
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t* GetBuffer() {
|
|
||||||
return pBuf;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Initialize(MultiValueBuffer * const pbuf) {
|
|
||||||
pBuf = (uint8_t*)pbuf->pValue;
|
|
||||||
countDown = valueSize = pbuf->valueSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Parse(uint8_t **pp, uint16_t *pcntdn);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ByteSkipper {
|
|
||||||
uint8_t *pBuf;
|
|
||||||
uint8_t nStage;
|
|
||||||
uint16_t countDown;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) {
|
|
||||||
};
|
|
||||||
|
|
||||||
void Initialize(MultiValueBuffer *pbuf) {
|
|
||||||
pBuf = (uint8_t*)pbuf->pValue;
|
|
||||||
countDown = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) {
|
|
||||||
switch(nStage) {
|
|
||||||
case 0:
|
|
||||||
countDown = bytes_to_skip;
|
|
||||||
nStage++;
|
|
||||||
case 1:
|
|
||||||
for(; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--);
|
|
||||||
|
|
||||||
if(!countDown)
|
|
||||||
nStage = 0;
|
|
||||||
};
|
|
||||||
return (!countDown);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Pointer to a callback function triggered for each element of PTP array when used with PTPArrayParser
|
|
||||||
typedef void (*PTP_ARRAY_EL_FUNC)(const MultiValueBuffer * const p, uint32_t count, const void *me);
|
|
||||||
|
|
||||||
class PTPListParser {
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum ParseMode {
|
|
||||||
modeArray, modeRange/*, modeEnum*/
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint8_t nStage;
|
|
||||||
uint8_t enStage;
|
|
||||||
|
|
||||||
uint32_t arLen;
|
|
||||||
uint32_t arLenCntdn;
|
|
||||||
|
|
||||||
uint8_t lenSize; // size of the array length field in bytes
|
|
||||||
uint8_t valSize; // size of the array element in bytes
|
|
||||||
|
|
||||||
MultiValueBuffer *pBuf;
|
|
||||||
|
|
||||||
// The only parser for both size and array element parsing
|
|
||||||
MultiByteValueParser theParser;
|
|
||||||
|
|
||||||
uint8_t /*ParseMode*/ prsMode;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
PTPListParser() :
|
|
||||||
nStage(0),
|
|
||||||
enStage(0),
|
|
||||||
arLen(0),
|
|
||||||
arLenCntdn(0),
|
|
||||||
lenSize(0),
|
|
||||||
valSize(0),
|
|
||||||
pBuf(NULL),
|
|
||||||
prsMode(modeArray) {
|
|
||||||
};
|
|
||||||
|
|
||||||
void Initialize(const uint8_t len_size, const uint8_t val_size, MultiValueBuffer * const p, const uint8_t mode = modeArray) {
|
|
||||||
pBuf = p;
|
|
||||||
lenSize = len_size;
|
|
||||||
valSize = val_size;
|
|
||||||
prsMode = mode;
|
|
||||||
|
|
||||||
if(prsMode == modeRange) {
|
|
||||||
arLenCntdn = arLen = 3;
|
|
||||||
nStage = 2;
|
|
||||||
} else {
|
|
||||||
arLenCntdn = arLen = 0;
|
|
||||||
nStage = 0;
|
|
||||||
}
|
|
||||||
enStage = 0;
|
|
||||||
theParser.Initialize(p);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me = NULL);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __PARSETOOLS_H__
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_usb_h_) || defined(__PRINTHEX_H__)
|
|
||||||
#error "Never include printhex.h directly; include Usb.h instead"
|
|
||||||
#else
|
|
||||||
#define __PRINTHEX_H__
|
|
||||||
|
|
||||||
void E_Notifyc(char c, int lvl);
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PrintHex(T val, int lvl) {
|
|
||||||
int num_nibbles = sizeof (T) * 2;
|
|
||||||
|
|
||||||
do {
|
|
||||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
|
||||||
if(v > 57) v += 7;
|
|
||||||
E_Notifyc(v, lvl);
|
|
||||||
} while(--num_nibbles);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PrintBin(T val, int lvl) {
|
|
||||||
for(T mask = (((T)1) << ((sizeof (T) << 3) - 1)); mask; mask >>= 1)
|
|
||||||
if(val & mask)
|
|
||||||
E_Notifyc('1', lvl);
|
|
||||||
else
|
|
||||||
E_Notifyc('0', lvl);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void SerialPrintHex(T val) {
|
|
||||||
int num_nibbles = sizeof (T) * 2;
|
|
||||||
|
|
||||||
do {
|
|
||||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
|
||||||
if(v > 57) v += 7;
|
|
||||||
USB_HOST_SERIAL.print(v);
|
|
||||||
} while(--num_nibbles);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void PrintHex2(Print *prn, T val) {
|
|
||||||
T mask = (((T)1) << (((sizeof (T) << 1) - 1) << 2));
|
|
||||||
|
|
||||||
while(mask > 1) {
|
|
||||||
if(val < mask)
|
|
||||||
prn->print("0");
|
|
||||||
|
|
||||||
mask >>= 4;
|
|
||||||
}
|
|
||||||
prn->print((T)val, HEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> void D_PrintHex(T val __attribute__((unused)), int lvl __attribute__((unused))) {
|
|
||||||
#ifdef DEBUG_USB_HOST
|
|
||||||
PrintHex<T > (val, lvl);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void D_PrintBin(T val, int lvl) {
|
|
||||||
#ifdef DEBUG_USB_HOST
|
|
||||||
PrintBin<T > (val, lvl);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __PRINTHEX_H__
|
|
||||||
@@ -24,7 +24,6 @@ e-mail : support@circuitsathome.com
|
|||||||
|
|
||||||
#ifndef USB_HOST_SHIELD_SETTINGS_H
|
#ifndef USB_HOST_SHIELD_SETTINGS_H
|
||||||
#define USB_HOST_SHIELD_SETTINGS_H
|
#define USB_HOST_SHIELD_SETTINGS_H
|
||||||
#include "macros.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// SPI Configuration
|
// SPI Configuration
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_usb_h_) || defined(__SINK_PARSER_H__)
|
|
||||||
#error "Never include hexdump.h directly; include Usb.h instead"
|
|
||||||
#else
|
|
||||||
#define __SINK_PARSER_H__
|
|
||||||
|
|
||||||
extern int UsbDEBUGlvl;
|
|
||||||
|
|
||||||
// This parser does absolutely nothing with the data, just swallows it.
|
|
||||||
|
|
||||||
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
|
|
||||||
class SinkParser : public BASE_CLASS {
|
|
||||||
public:
|
|
||||||
|
|
||||||
SinkParser() {
|
|
||||||
};
|
|
||||||
|
|
||||||
void Initialize() {
|
|
||||||
};
|
|
||||||
|
|
||||||
void Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __HEXDUMP_H__
|
|
||||||
@@ -1,427 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This software may be distributed and modified under the terms of the GNU
|
|
||||||
General Public License version 2 (GPL2) as published by the Free Software
|
|
||||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
|
||||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
|
||||||
on this software must also be made publicly available under the terms of
|
|
||||||
the GPL2 ("Copyleft").
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
#include "usbhub.h"
|
|
||||||
|
|
||||||
bool USBHub::bResetInitiated = false;
|
|
||||||
|
|
||||||
USBHub::USBHub(USB *p) :
|
|
||||||
pUsb(p),
|
|
||||||
bAddress(0),
|
|
||||||
bNbrPorts(0),
|
|
||||||
//bInitState(0),
|
|
||||||
qNextPollTime(0),
|
|
||||||
bPollEnable(false) {
|
|
||||||
epInfo[0].epAddr = 0;
|
|
||||||
epInfo[0].maxPktSize = 8;
|
|
||||||
epInfo[0].bmSndToggle = 0;
|
|
||||||
epInfo[0].bmRcvToggle = 0;
|
|
||||||
epInfo[0].bmNakPower = USB_NAK_MAX_POWER;
|
|
||||||
|
|
||||||
epInfo[1].epAddr = 1;
|
|
||||||
epInfo[1].maxPktSize = 8; //kludge
|
|
||||||
epInfo[1].bmSndToggle = 0;
|
|
||||||
epInfo[1].bmRcvToggle = 0;
|
|
||||||
epInfo[1].bmNakPower = USB_NAK_NOWAIT;
|
|
||||||
|
|
||||||
if(pUsb)
|
|
||||||
pUsb->RegisterDeviceClass(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
|
||||||
uint8_t buf[32];
|
|
||||||
USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
|
|
||||||
HubDescriptor* hd = reinterpret_cast<HubDescriptor*>(buf);
|
|
||||||
USB_CONFIGURATION_DESCRIPTOR * ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(buf);
|
|
||||||
uint8_t rcode;
|
|
||||||
UsbDevice *p = NULL;
|
|
||||||
EpInfo *oldep_ptr = NULL;
|
|
||||||
uint8_t len = 0;
|
|
||||||
uint16_t cd_len = 0;
|
|
||||||
|
|
||||||
//USBTRACE("\r\nHub Init Start ");
|
|
||||||
//D_PrintHex<uint8_t > (bInitState, 0x80);
|
|
||||||
|
|
||||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
|
||||||
|
|
||||||
//switch (bInitState) {
|
|
||||||
// case 0:
|
|
||||||
if(bAddress)
|
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
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;
|
|
||||||
|
|
||||||
p->lowspeed = lowspeed;
|
|
||||||
|
|
||||||
// Get device descriptor
|
|
||||||
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
|
|
||||||
|
|
||||||
p->lowspeed = false;
|
|
||||||
|
|
||||||
if(!rcode)
|
|
||||||
len = (buf[0] > 32) ? 32 : buf[0];
|
|
||||||
|
|
||||||
if(rcode) {
|
|
||||||
// Restore p->epinfo
|
|
||||||
p->epinfo = oldep_ptr;
|
|
||||||
return rcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract device class from device descriptor
|
|
||||||
// If device class is not a hub return
|
|
||||||
if(udd->bDeviceClass != 0x09)
|
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
// Allocate new address according to device class
|
|
||||||
bAddress = addrPool.AllocAddress(parent, (udd->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 = udd->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;
|
|
||||||
return rcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
//USBTRACE2("\r\nHub address: ", bAddress );
|
|
||||||
|
|
||||||
// Restore p->epinfo
|
|
||||||
p->epinfo = oldep_ptr;
|
|
||||||
|
|
||||||
if(len)
|
|
||||||
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
|
|
||||||
|
|
||||||
if(rcode)
|
|
||||||
goto FailGetDevDescr;
|
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, 2, epInfo);
|
|
||||||
|
|
||||||
if(rcode)
|
|
||||||
goto FailSetDevTblEntry;
|
|
||||||
|
|
||||||
// bInitState = 1;
|
|
||||||
|
|
||||||
// case 1:
|
|
||||||
// Get hub descriptor
|
|
||||||
rcode = GetHubDescriptor(0, 8, buf);
|
|
||||||
|
|
||||||
if(rcode)
|
|
||||||
goto FailGetHubDescr;
|
|
||||||
|
|
||||||
// Save number of ports for future use
|
|
||||||
bNbrPorts = hd->bNbrPorts;
|
|
||||||
|
|
||||||
// bInitState = 2;
|
|
||||||
|
|
||||||
// case 2:
|
|
||||||
// Read configuration Descriptor in Order To Obtain Proper Configuration Value
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, 8, 0, buf);
|
|
||||||
|
|
||||||
if(!rcode) {
|
|
||||||
cd_len = ucd->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Configuration Value
|
|
||||||
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
|
||||||
|
|
||||||
if(rcode)
|
|
||||||
goto FailSetConfDescr;
|
|
||||||
|
|
||||||
// bInitState = 3;
|
|
||||||
|
|
||||||
// case 3:
|
|
||||||
// Power on all ports
|
|
||||||
for(uint8_t j = 1; j <= bNbrPorts; j++)
|
|
||||||
SetPortFeature(HUB_FEATURE_PORT_POWER, j, 0); //HubPortPowerOn(j);
|
|
||||||
|
|
||||||
pUsb->SetHubPreMask();
|
|
||||||
bPollEnable = true;
|
|
||||||
// bInitState = 0;
|
|
||||||
//}
|
|
||||||
//bInitState = 0;
|
|
||||||
//USBTRACE("...OK\r\n");
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Oleg, No debugging?? -- xxxajk
|
|
||||||
FailGetDevDescr:
|
|
||||||
goto Fail;
|
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
|
||||||
goto Fail;
|
|
||||||
|
|
||||||
FailGetHubDescr:
|
|
||||||
goto Fail;
|
|
||||||
|
|
||||||
FailGetConfDescr:
|
|
||||||
goto Fail;
|
|
||||||
|
|
||||||
FailSetConfDescr:
|
|
||||||
goto Fail;
|
|
||||||
|
|
||||||
Fail:
|
|
||||||
USBTRACE("...FAIL\r\n");
|
|
||||||
return rcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBHub::Release() {
|
|
||||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
|
||||||
|
|
||||||
if(bAddress == 0x41)
|
|
||||||
pUsb->SetHubPreMask();
|
|
||||||
|
|
||||||
bAddress = 0;
|
|
||||||
bNbrPorts = 0;
|
|
||||||
qNextPollTime = 0;
|
|
||||||
bPollEnable = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBHub::Poll() {
|
|
||||||
uint8_t rcode = 0;
|
|
||||||
|
|
||||||
if(!bPollEnable)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L)) {
|
|
||||||
rcode = CheckHubStatus();
|
|
||||||
qNextPollTime = (uint32_t)millis() + 100;
|
|
||||||
}
|
|
||||||
return rcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBHub::CheckHubStatus() {
|
|
||||||
uint8_t rcode;
|
|
||||||
uint8_t buf[8];
|
|
||||||
uint16_t read = 1;
|
|
||||||
|
|
||||||
rcode = pUsb->inTransfer(bAddress, 1, &read, buf);
|
|
||||||
|
|
||||||
if(rcode)
|
|
||||||
return rcode;
|
|
||||||
|
|
||||||
//if (buf[0] & 0x01) // Hub Status Change
|
|
||||||
//{
|
|
||||||
// pUsb->PrintHubStatus(addr);
|
|
||||||
// rcode = GetHubStatus(1, 0, 1, 4, buf);
|
|
||||||
// if (rcode)
|
|
||||||
// {
|
|
||||||
// USB_HOST_SERIAL.print("GetHubStatus Error");
|
|
||||||
// USB_HOST_SERIAL.println(rcode, HEX);
|
|
||||||
// return rcode;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
for(uint8_t port = 1, mask = 0x02; port < 8; mask <<= 1, port++) {
|
|
||||||
if(buf[0] & mask) {
|
|
||||||
HubEvent evt;
|
|
||||||
evt.bmEvent = 0;
|
|
||||||
|
|
||||||
rcode = GetPortStatus(port, 4, evt.evtBuff);
|
|
||||||
|
|
||||||
if(rcode)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
rcode = PortStatusChange(port, evt);
|
|
||||||
|
|
||||||
if(rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(rcode)
|
|
||||||
return rcode;
|
|
||||||
}
|
|
||||||
} // for
|
|
||||||
|
|
||||||
for(uint8_t port = 1; port <= bNbrPorts; port++) {
|
|
||||||
HubEvent evt;
|
|
||||||
evt.bmEvent = 0;
|
|
||||||
|
|
||||||
rcode = GetPortStatus(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 = PortStatusChange(port, evt);
|
|
||||||
|
|
||||||
if(rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(rcode)
|
|
||||||
return rcode;
|
|
||||||
} // for
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBHub::ResetHubPort(uint8_t port) {
|
|
||||||
HubEvent evt;
|
|
||||||
evt.bmEvent = 0;
|
|
||||||
uint8_t rcode;
|
|
||||||
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0);
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0);
|
|
||||||
SetPortFeature(HUB_FEATURE_PORT_RESET, port, 0);
|
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < 3; i++) {
|
|
||||||
rcode = GetPortStatus(port, 4, evt.evtBuff);
|
|
||||||
if(rcode) break; // Some kind of error, bail.
|
|
||||||
if(evt.bmEvent == bmHUB_PORT_EVENT_RESET_COMPLETE || evt.bmEvent == bmHUB_PORT_EVENT_LS_RESET_COMPLETE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
delay(100); // simulate polling.
|
|
||||||
}
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_RESET, port, 0);
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0);
|
|
||||||
delay(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t USBHub::PortStatusChange(uint8_t port, HubEvent &evt) {
|
|
||||||
switch(evt.bmEvent) {
|
|
||||||
// Device connected event
|
|
||||||
case bmHUB_PORT_EVENT_CONNECT:
|
|
||||||
case bmHUB_PORT_EVENT_LS_CONNECT:
|
|
||||||
if(bResetInitiated)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0);
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0);
|
|
||||||
SetPortFeature(HUB_FEATURE_PORT_RESET, port, 0);
|
|
||||||
bResetInitiated = true;
|
|
||||||
return HUB_ERROR_PORT_HAS_BEEN_RESET;
|
|
||||||
|
|
||||||
// Device disconnected event
|
|
||||||
case bmHUB_PORT_EVENT_DISCONNECT:
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0);
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0);
|
|
||||||
bResetInitiated = false;
|
|
||||||
|
|
||||||
UsbDeviceAddress a;
|
|
||||||
a.devAddress = 0;
|
|
||||||
a.bmHub = 0;
|
|
||||||
a.bmParent = bAddress;
|
|
||||||
a.bmAddress = port;
|
|
||||||
pUsb->ReleaseDevice(a.devAddress);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Reset complete event
|
|
||||||
case bmHUB_PORT_EVENT_RESET_COMPLETE:
|
|
||||||
case bmHUB_PORT_EVENT_LS_RESET_COMPLETE:
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_RESET, port, 0);
|
|
||||||
ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0);
|
|
||||||
|
|
||||||
delay(20);
|
|
||||||
|
|
||||||
a.devAddress = bAddress;
|
|
||||||
|
|
||||||
pUsb->Configuring(a.bmAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED));
|
|
||||||
bResetInitiated = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
} // switch (evt.bmEvent)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintHubPortStatus(USBHub *hubptr, uint8_t addr __attribute__((unused)), uint8_t port, bool print_changes) {
|
|
||||||
uint8_t rcode = 0;
|
|
||||||
HubEvent evt;
|
|
||||||
|
|
||||||
rcode = hubptr->GetPortStatus(port, 4, evt.evtBuff);
|
|
||||||
|
|
||||||
if(rcode) {
|
|
||||||
USB_HOST_SERIAL.println("ERROR!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
USB_HOST_SERIAL.print("\r\nPort ");
|
|
||||||
USB_HOST_SERIAL.println(port, DEC);
|
|
||||||
|
|
||||||
USB_HOST_SERIAL.println("Status");
|
|
||||||
USB_HOST_SERIAL.print("CONNECTION:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_CONNECTION) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("ENABLE:\t\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_ENABLE) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("SUSPEND:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_SUSPEND) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("OVER_CURRENT:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_OVER_CURRENT) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("RESET:\t\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_RESET) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("POWER:\t\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_POWER) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("LOW_SPEED:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("HIGH_SPEED:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_HIGH_SPEED) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("TEST:\t\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_TEST) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("INDICATOR:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmStatus & bmHUB_PORT_STATUS_PORT_INDICATOR) > 0, DEC);
|
|
||||||
|
|
||||||
if(!print_changes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
USB_HOST_SERIAL.println("\r\nChange");
|
|
||||||
USB_HOST_SERIAL.print("CONNECTION:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_CONNECTION) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("ENABLE:\t\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_ENABLE) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("SUSPEND:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_SUSPEND) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("OVER_CURRENT:\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_OVER_CURRENT) > 0, DEC);
|
|
||||||
USB_HOST_SERIAL.print("RESET:\t\t");
|
|
||||||
USB_HOST_SERIAL.println((evt.bmChange & bmHUB_PORT_STATUS_C_PORT_RESET) > 0, DEC);
|
|
||||||
}
|
|
||||||
@@ -1,252 +0,0 @@
|
|||||||
/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
|
||||||
|
|
||||||
This software may be distributed and modified under the terms of the GNU
|
|
||||||
General Public License version 2 (GPL2) as published by the Free Software
|
|
||||||
Foundation and appearing in the file GPL2.TXT included in the packaging of
|
|
||||||
this file. Please note that GPL2 Section 2[b] requires that all works based
|
|
||||||
on this software must also be made publicly available under the terms of
|
|
||||||
the GPL2 ("Copyleft").
|
|
||||||
|
|
||||||
Contact information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Circuits At Home, LTD
|
|
||||||
Web : http://www.circuitsathome.com
|
|
||||||
e-mail : support@circuitsathome.com
|
|
||||||
*/
|
|
||||||
#if !defined(__USBHUB_H__)
|
|
||||||
#define __USBHUB_H__
|
|
||||||
|
|
||||||
#include "../../include/Usb.h"
|
|
||||||
|
|
||||||
#define USB_DESCRIPTOR_HUB 0x09 // Hub descriptor type
|
|
||||||
|
|
||||||
// Hub Requests
|
|
||||||
#define bmREQ_CLEAR_HUB_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
|
|
||||||
#define bmREQ_CLEAR_PORT_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
|
|
||||||
#define bmREQ_CLEAR_TT_BUFFER USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
|
|
||||||
#define bmREQ_GET_HUB_DESCRIPTOR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
|
|
||||||
#define bmREQ_GET_HUB_STATUS USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
|
|
||||||
#define bmREQ_GET_PORT_STATUS USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
|
|
||||||
#define bmREQ_RESET_TT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
|
|
||||||
#define bmREQ_SET_HUB_DESCRIPTOR USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
|
|
||||||
#define bmREQ_SET_HUB_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
|
|
||||||
#define bmREQ_SET_PORT_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
|
|
||||||
#define bmREQ_GET_TT_STATE USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
|
|
||||||
#define bmREQ_STOP_TT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
|
|
||||||
|
|
||||||
// Hub Class Requests
|
|
||||||
#define HUB_REQUEST_CLEAR_TT_BUFFER 8
|
|
||||||
#define HUB_REQUEST_RESET_TT 9
|
|
||||||
#define HUB_REQUEST_GET_TT_STATE 10
|
|
||||||
#define HUB_REQUEST_STOP_TT 11
|
|
||||||
|
|
||||||
// Hub Features
|
|
||||||
#define HUB_FEATURE_C_HUB_LOCAL_POWER 0
|
|
||||||
#define HUB_FEATURE_C_HUB_OVER_CURRENT 1
|
|
||||||
#define HUB_FEATURE_PORT_CONNECTION 0
|
|
||||||
#define HUB_FEATURE_PORT_ENABLE 1
|
|
||||||
#define HUB_FEATURE_PORT_SUSPEND 2
|
|
||||||
#define HUB_FEATURE_PORT_OVER_CURRENT 3
|
|
||||||
#define HUB_FEATURE_PORT_RESET 4
|
|
||||||
#define HUB_FEATURE_PORT_POWER 8
|
|
||||||
#define HUB_FEATURE_PORT_LOW_SPEED 9
|
|
||||||
#define HUB_FEATURE_C_PORT_CONNECTION 16
|
|
||||||
#define HUB_FEATURE_C_PORT_ENABLE 17
|
|
||||||
#define HUB_FEATURE_C_PORT_SUSPEND 18
|
|
||||||
#define HUB_FEATURE_C_PORT_OVER_CURRENT 19
|
|
||||||
#define HUB_FEATURE_C_PORT_RESET 20
|
|
||||||
#define HUB_FEATURE_PORT_TEST 21
|
|
||||||
#define HUB_FEATURE_PORT_INDICATOR 22
|
|
||||||
|
|
||||||
// Hub Port Test Modes
|
|
||||||
#define HUB_PORT_TEST_MODE_J 1
|
|
||||||
#define HUB_PORT_TEST_MODE_K 2
|
|
||||||
#define HUB_PORT_TEST_MODE_SE0_NAK 3
|
|
||||||
#define HUB_PORT_TEST_MODE_PACKET 4
|
|
||||||
#define HUB_PORT_TEST_MODE_FORCE_ENABLE 5
|
|
||||||
|
|
||||||
// Hub Port Indicator Color
|
|
||||||
#define HUB_PORT_INDICATOR_AUTO 0
|
|
||||||
#define HUB_PORT_INDICATOR_AMBER 1
|
|
||||||
#define HUB_PORT_INDICATOR_GREEN 2
|
|
||||||
#define HUB_PORT_INDICATOR_OFF 3
|
|
||||||
|
|
||||||
// Hub Port Status Bitmasks
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_CONNECTION 0x0001
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_ENABLE 0x0002
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_SUSPEND 0x0004
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_OVER_CURRENT 0x0008
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_RESET 0x0010
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_POWER 0x0100
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_LOW_SPEED 0x0200
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_HIGH_SPEED 0x0400
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_TEST 0x0800
|
|
||||||
#define bmHUB_PORT_STATUS_PORT_INDICATOR 0x1000
|
|
||||||
|
|
||||||
// Hub Port Status Change Bitmasks (used one byte instead of two)
|
|
||||||
#define bmHUB_PORT_STATUS_C_PORT_CONNECTION 0x0001
|
|
||||||
#define bmHUB_PORT_STATUS_C_PORT_ENABLE 0x0002
|
|
||||||
#define bmHUB_PORT_STATUS_C_PORT_SUSPEND 0x0004
|
|
||||||
#define bmHUB_PORT_STATUS_C_PORT_OVER_CURRENT 0x0008
|
|
||||||
#define bmHUB_PORT_STATUS_C_PORT_RESET 0x0010
|
|
||||||
|
|
||||||
// Hub Status Bitmasks (used one byte instead of two)
|
|
||||||
#define bmHUB_STATUS_LOCAL_POWER_SOURCE 0x01
|
|
||||||
#define bmHUB_STATUS_OVER_CURRENT 0x12
|
|
||||||
|
|
||||||
// Hub Status Change Bitmasks (used one byte instead of two)
|
|
||||||
#define bmHUB_STATUS_C_LOCAL_POWER_SOURCE 0x01
|
|
||||||
#define bmHUB_STATUS_C_OVER_CURRENT 0x12
|
|
||||||
|
|
||||||
|
|
||||||
// Hub Port Configuring Substates
|
|
||||||
#define USB_STATE_HUB_PORT_CONFIGURING 0xb0
|
|
||||||
#define USB_STATE_HUB_PORT_POWERED_OFF 0xb1
|
|
||||||
#define USB_STATE_HUB_PORT_WAIT_FOR_POWER_GOOD 0xb2
|
|
||||||
#define USB_STATE_HUB_PORT_DISCONNECTED 0xb3
|
|
||||||
#define USB_STATE_HUB_PORT_DISABLED 0xb4
|
|
||||||
#define USB_STATE_HUB_PORT_RESETTING 0xb5
|
|
||||||
#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
|
|
||||||
#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
|
|
||||||
#define bmHUB_PORT_STATE_DISABLED (0x0000 | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
|
||||||
|
|
||||||
// Hub Port Events
|
|
||||||
#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_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 HubDescriptor {
|
|
||||||
uint8_t bDescLength; // descriptor length
|
|
||||||
uint8_t bDescriptorType; // descriptor type
|
|
||||||
uint8_t bNbrPorts; // number of ports a hub equiped with
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint16_t LogPwrSwitchMode : 2;
|
|
||||||
uint16_t CompoundDevice : 1;
|
|
||||||
uint16_t OverCurrentProtectMode : 2;
|
|
||||||
uint16_t TTThinkTime : 2;
|
|
||||||
uint16_t PortIndicatorsSupported : 1;
|
|
||||||
uint16_t Reserved : 8;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
uint8_t bPwrOn2PwrGood;
|
|
||||||
uint8_t bHubContrCurrent;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct HubEvent {
|
|
||||||
|
|
||||||
union {
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint16_t bmStatus; // port status bits
|
|
||||||
uint16_t bmChange; // port status change bits
|
|
||||||
} __attribute__((packed));
|
|
||||||
uint32_t bmEvent;
|
|
||||||
uint8_t evtBuff[4];
|
|
||||||
};
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
class USBHub : USBDeviceConfig {
|
|
||||||
static bool bResetInitiated; // True when reset is triggered
|
|
||||||
|
|
||||||
USB *pUsb; // USB class instance pointer
|
|
||||||
|
|
||||||
EpInfo epInfo[2]; // interrupt endpoint info structure
|
|
||||||
|
|
||||||
uint8_t bAddress; // address
|
|
||||||
uint8_t bNbrPorts; // number of ports
|
|
||||||
// uint8_t bInitState; // initialization state variable
|
|
||||||
uint32_t qNextPollTime; // next poll time
|
|
||||||
bool bPollEnable; // poll enable flag
|
|
||||||
|
|
||||||
uint8_t CheckHubStatus();
|
|
||||||
uint8_t PortStatusChange(uint8_t port, HubEvent &evt);
|
|
||||||
|
|
||||||
public:
|
|
||||||
USBHub(USB *p);
|
|
||||||
|
|
||||||
uint8_t ClearHubFeature(uint8_t fid);
|
|
||||||
uint8_t ClearPortFeature(uint8_t fid, uint8_t port, uint8_t sel = 0);
|
|
||||||
uint8_t GetHubDescriptor(uint8_t index, uint16_t nbytes, uint8_t *dataptr);
|
|
||||||
uint8_t GetHubStatus(uint16_t nbytes, uint8_t* dataptr);
|
|
||||||
uint8_t GetPortStatus(uint8_t port, uint16_t nbytes, uint8_t* dataptr);
|
|
||||||
uint8_t SetHubDescriptor(uint8_t port, uint16_t nbytes, uint8_t* dataptr);
|
|
||||||
uint8_t SetHubFeature(uint8_t fid);
|
|
||||||
uint8_t SetPortFeature(uint8_t fid, uint8_t port, uint8_t sel = 0);
|
|
||||||
|
|
||||||
void PrintHubStatus();
|
|
||||||
|
|
||||||
uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
|
||||||
uint8_t Release();
|
|
||||||
uint8_t Poll();
|
|
||||||
void ResetHubPort(uint8_t port);
|
|
||||||
|
|
||||||
virtual uint8_t GetAddress() {
|
|
||||||
return bAddress;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual bool DEVCLASSOK(uint8_t klass) {
|
|
||||||
return (klass == 0x09);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Clear Hub Feature
|
|
||||||
|
|
||||||
inline uint8_t USBHub::ClearHubFeature(uint8_t fid) {
|
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
|
|
||||||
}
|
|
||||||
// Clear Port Feature
|
|
||||||
|
|
||||||
inline uint8_t USBHub::ClearPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
|
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000 | port) | (sel << 8)), 0, 0, NULL, NULL));
|
|
||||||
}
|
|
||||||
// Get Hub Descriptor
|
|
||||||
|
|
||||||
inline uint8_t USBHub::GetHubDescriptor(uint8_t index, uint16_t nbytes, uint8_t *dataptr) {
|
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, nbytes, dataptr, NULL));
|
|
||||||
}
|
|
||||||
// Get Hub Status
|
|
||||||
|
|
||||||
inline uint8_t USBHub::GetHubStatus(uint16_t nbytes, uint8_t* dataptr) {
|
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, nbytes, dataptr, NULL));
|
|
||||||
}
|
|
||||||
// Get Port Status
|
|
||||||
|
|
||||||
inline uint8_t USBHub::GetPortStatus(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
|
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, nbytes, dataptr, NULL));
|
|
||||||
}
|
|
||||||
// Set Hub Descriptor
|
|
||||||
|
|
||||||
inline uint8_t USBHub::SetHubDescriptor(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
|
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, nbytes, dataptr, NULL));
|
|
||||||
}
|
|
||||||
// Set Hub Feature
|
|
||||||
|
|
||||||
inline uint8_t USBHub::SetHubFeature(uint8_t fid) {
|
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
|
|
||||||
}
|
|
||||||
// Set Port Feature
|
|
||||||
|
|
||||||
inline uint8_t USBHub::SetPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
|
|
||||||
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000 | sel) << 8) | port), 0, 0, NULL, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);
|
|
||||||
|
|
||||||
#endif // __USBHUB_H__
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
project(checkm8_remote C)
|
project(checkm8_remote C)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
set(CMAKE_C_FLAGS -g)
|
set(CMAKE_C_FLAGS "-g -Wall")
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
add_executable(checkm8_remote main.c src/usb_helpers.c src/exploit.c src/payload.c src/command.c)
|
add_executable(checkm8_remote main.c src/usb_helpers.c src/exploit.c src/payload.c src/command.c)
|
||||||
|
|||||||
@@ -291,7 +291,8 @@ struct pwned_device *exploit_device()
|
|||||||
|
|
||||||
void free_device(struct pwned_device *dev)
|
void free_device(struct pwned_device *dev)
|
||||||
{
|
{
|
||||||
close_device_session(dev);
|
checkm8_debug_indent("free_device(dev = %p)\n", dev);
|
||||||
|
if(is_device_session_open(dev)) close_device_session(dev);
|
||||||
#ifndef WITH_ARDUINO
|
#ifndef WITH_ARDUINO
|
||||||
free(dev->bundle);
|
free(dev->bundle);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -105,6 +105,12 @@ int open_device_session(struct pwned_device *dev)
|
|||||||
close(ard_fd);
|
close(ard_fd);
|
||||||
return CHECKM8_FAIL_NOTDONE;
|
return CHECKM8_FAIL_NOTDONE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checkm8_debug_indent("\tunexpected response %X\n", buf);
|
||||||
|
close(ard_fd);
|
||||||
|
return CHECKM8_FAIL_PROT;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int i, usb_dev_count, ret = CHECKM8_FAIL_NODEV;
|
int i, usb_dev_count, ret = CHECKM8_FAIL_NODEV;
|
||||||
libusb_device **usb_device_list = NULL;
|
libusb_device **usb_device_list = NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user