mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Arduino-1.0 compatibility added
This commit is contained in:
parent
7972c403b1
commit
2c728cd7dd
39 changed files with 489 additions and 228 deletions
22
Usb.cpp
22
Usb.cpp
|
@ -20,7 +20,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "max3421e.h"
|
#include "max3421e.h"
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
#include "WProgram.h"
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint8_t usb_error = 0;
|
static uint8_t usb_error = 0;
|
||||||
static uint8_t usb_task_state;
|
static uint8_t usb_task_state;
|
||||||
|
@ -102,8 +107,15 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_l
|
||||||
if (!*ppep)
|
if (!*ppep)
|
||||||
return USB_ERROR_EP_NOT_FOUND_IN_TBL;
|
return USB_ERROR_EP_NOT_FOUND_IN_TBL;
|
||||||
|
|
||||||
nak_limit = (0x0001UL << ( ( (*ppep)->bmNakPower > USB_NAK_MAX_POWER ) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower) );
|
nak_limit = (0x0001UL << ( ( (*ppep)->bmNakPower > USB_NAK_MAX_POWER ) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower) );
|
||||||
|
nak_limit--;
|
||||||
|
/*
|
||||||
|
USBTRACE2("\r\nAddress: ", addr);
|
||||||
|
USBTRACE2(" EP: ", ep);
|
||||||
|
USBTRACE2(" NAK Power: ",(*ppep)->bmNakPower);
|
||||||
|
USBTRACE2(" NAK Limit: ", nak_limit);
|
||||||
|
USBTRACE("\r\n");
|
||||||
|
*/
|
||||||
regWr( rPERADDR, addr ); //set peripheral address
|
regWr( rPERADDR, addr ); //set peripheral address
|
||||||
|
|
||||||
uint8_t mode = regRd( rMODE );
|
uint8_t mode = regRd( rMODE );
|
||||||
|
@ -111,8 +123,6 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_l
|
||||||
// Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise
|
// Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise
|
||||||
regWr( rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED));
|
regWr( rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED));
|
||||||
|
|
||||||
//delay(20);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +364,7 @@ uint8_t USB::dispatchPkt( uint8_t token, uint8_t ep, uint16_t nak_limit )
|
||||||
while( timeout > millis() )
|
while( timeout > millis() )
|
||||||
{
|
{
|
||||||
regWr( rHXFR, ( token|ep )); //launch the transfer
|
regWr( rHXFR, ( token|ep )); //launch the transfer
|
||||||
rcode = 0xff;
|
rcode = USB_ERROR_TRANSFER_TIMEOUT;
|
||||||
|
|
||||||
while( millis() < timeout ) //wait for transfer completion
|
while( millis() < timeout ) //wait for transfer completion
|
||||||
{
|
{
|
||||||
|
|
11
Usb.h
11
Usb.h
|
@ -33,7 +33,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
@ -48,10 +53,12 @@ typedef MAX3421e<P6, P3> MAX3421E; // Black Widow
|
||||||
typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560
|
typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//Debug macros. In 1.0 it is possible to move strings to PROGMEM by defining USBTRACE (Serial.print(F(s)))
|
||||||
#define USBTRACE(s) (Serial.print((s)))
|
#define USBTRACE(s) (Serial.print((s)))
|
||||||
#define USBTRACE2(s,r) (Serial.print((s)), Serial.println((r),HEX))
|
#define USBTRACE2(s,r) (Serial.print((s)), Serial.println((r),HEX))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Common setup data constant combinations */
|
/* Common setup data constant combinations */
|
||||||
#define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //get descriptor request type
|
#define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //get descriptor request type
|
||||||
#define bmREQ_SET USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //set request type for all but 'set feature' and 'set interface'
|
#define bmREQ_SET USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //set request type for all but 'set feature' and 'set interface'
|
||||||
|
@ -94,6 +101,7 @@ typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Me
|
||||||
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9
|
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9
|
||||||
#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA
|
#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA
|
||||||
#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB
|
#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB
|
||||||
|
#define USB_ERROR_TRANSFER_TIMEOUT 0xFF
|
||||||
|
|
||||||
class USBDeviceConfig
|
class USBDeviceConfig
|
||||||
{
|
{
|
||||||
|
@ -105,10 +113,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#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. 0 means 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 //quit after receiving a single NAK
|
|
||||||
|
|
||||||
#define USB_NUMDEVICES 16 //number of USB devices
|
#define USB_NUMDEVICES 16 //number of USB devices
|
||||||
//#define HUB_MAX_HUBS 7 // 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
|
||||||
|
|
12
address.h
12
address.h
|
@ -21,7 +21,13 @@ e-mail : support@circuitsathome.com
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "max3421e.h"
|
#include "max3421e.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* NAK powers. To save space in endpoint data structure, amount of retries before giving up and returning 0x4 is stored in */
|
||||||
|
/* bmNakPower as a power of 2. The actual nak_limit is then calculated as nak_limit = ( 2^bmNakPower - 1) */
|
||||||
#define USB_NAK_MAX_POWER 15 //NAK binary order maximum value
|
#define USB_NAK_MAX_POWER 15 //NAK binary order maximum value
|
||||||
|
#define USB_NAK_DEFAULT 14 //default 32K-1 NAKs before giving up
|
||||||
|
#define USB_NAK_NOWAIT 1 //Single NAK stops transfer
|
||||||
|
#define USB_NAK_NONAK 0 //Do not count NAKs, stop retrying after USB Timeout
|
||||||
|
|
||||||
struct EpInfo
|
struct EpInfo
|
||||||
{
|
{
|
||||||
|
@ -34,8 +40,8 @@ struct EpInfo
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t bmSndToggle : 1; // Send toggle, when zerro bmSNDTOG0, bmSNDTOG1 otherwise
|
uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise
|
||||||
uint8_t bmRcvToggle : 1; // Send toggle, when zerro bmRCVTOG0, bmRCVTOG1 otherwise
|
uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise
|
||||||
uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value
|
uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -160,7 +166,7 @@ class AddressPoolImpl : public AddressPool
|
||||||
public:
|
public:
|
||||||
AddressPoolImpl() : hubCounter(0)
|
AddressPoolImpl() : hubCounter(0)
|
||||||
{
|
{
|
||||||
// Zerro address is reserved
|
// Zero address is reserved
|
||||||
InitEntry(0);
|
InitEntry(0);
|
||||||
|
|
||||||
thePool[0].address = 0;
|
thePool[0].address = 0;
|
||||||
|
|
5
adk.h
5
adk.h
|
@ -27,7 +27,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
|
|
@ -35,8 +35,10 @@ ACM::ACM(USB *p, CDCAsyncOper *pasync) :
|
||||||
epInfo[i].epAddr = 0;
|
epInfo[i].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
//epInfo[i].bmNakPower = USB_NAK_NOWAIT;
|
||||||
if (!i)
|
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||||
|
|
||||||
|
//if (!i)
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||||
}
|
}
|
||||||
if (pUsb)
|
if (pUsb)
|
||||||
|
|
5
cdcacm.h
5
cdcacm.h
|
@ -24,7 +24,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
|
|
@ -33,7 +33,7 @@ FTDI::FTDI(USB *p, FTDIAsyncOper *pasync) :
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
|
||||||
if (!i)
|
//if (!i)
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||||
}
|
}
|
||||||
if (pUsb)
|
if (pUsb)
|
||||||
|
|
|
@ -24,7 +24,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
|
|
@ -16,13 +16,13 @@ e-mail : support@circuitsathome.com
|
||||||
*/
|
*/
|
||||||
#include "cdcprolific.h"
|
#include "cdcprolific.h"
|
||||||
|
|
||||||
PL::PL(USB *p, CDCAsyncOper *pasync) :
|
PL2303::PL2303(USB *p, CDCAsyncOper *pasync) :
|
||||||
ACM(p, pasync),
|
ACM(p, pasync),
|
||||||
wPLType(0)
|
wPLType(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t PL::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||||
{
|
{
|
||||||
const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR);
|
const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
@ -132,12 +137,12 @@ enum pl2303_type
|
||||||
|
|
||||||
#define PL_MAX_ENDPOINTS 4
|
#define PL_MAX_ENDPOINTS 4
|
||||||
|
|
||||||
class PL : public ACM
|
class PL2303 : public ACM
|
||||||
{
|
{
|
||||||
uint16_t wPLType; // Type of chip
|
uint16_t wPLType; // Type of chip
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PL(USB *pusb, CDCAsyncOper *pasync);
|
PL2303(USB *pusb, CDCAsyncOper *pasync);
|
||||||
|
|
||||||
// USBDeviceConfig implementation
|
// USBDeviceConfig implementation
|
||||||
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
||||||
|
|
|
@ -164,11 +164,11 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
|
||||||
if (theXtractor)
|
if (theXtractor)
|
||||||
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
|
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
|
||||||
break;
|
break;
|
||||||
case HID_DESCRIPTOR_HID:
|
//case HID_DESCRIPTOR_HID:
|
||||||
if (!valParser.Parse(pp, pcntdn))
|
// if (!valParser.Parse(pp, pcntdn))
|
||||||
return false;
|
// return false;
|
||||||
PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
|
// PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
|
||||||
break;
|
// break;
|
||||||
default:
|
default:
|
||||||
if (!theSkipper.Skip(pp, pcntdn, dscrLen-2))
|
if (!theSkipper.Skip(pp, pcntdn, dscrLen-2))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -63,7 +63,7 @@ void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
|
||||||
void KbdRptParser::OnKeyPressed(uint8_t key)
|
void KbdRptParser::OnKeyPressed(uint8_t key)
|
||||||
{
|
{
|
||||||
Serial.print("ASCII: ");
|
Serial.print("ASCII: ");
|
||||||
Serial.println(key);
|
Serial.println((char)key);
|
||||||
};
|
};
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include <address.h>
|
#include <address.h>
|
||||||
#include <hidboot.h>
|
#include <hidboot.h>
|
||||||
|
|
||||||
#include <printhex.h>
|
#include <printhex.h>
|
||||||
#include <message.h>
|
#include <message.h>
|
||||||
#include <hexdump.h>
|
#include <hexdump.h>
|
||||||
|
@ -58,12 +57,12 @@ void MouseRptParser::OnMiddleButtonDown (MOUSEINFO *mi)
|
||||||
};
|
};
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
//USBHub Hub(&Usb);
|
USBHub Hub(&Usb);
|
||||||
HIDBoot<HID_PROTOCOL_MOUSE> Mouse(&Usb);
|
HIDBoot<HID_PROTOCOL_MOUSE> Mouse(&Usb);
|
||||||
|
|
||||||
uint32_t next_time;
|
uint32_t next_time;
|
||||||
|
|
||||||
MouseRptParser Prs;
|
MouseRptParser Prs;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
@ -77,7 +76,7 @@ void setup()
|
||||||
|
|
||||||
next_time = millis() + 5000;
|
next_time = millis() + 5000;
|
||||||
|
|
||||||
Mouse.SetReportParser(0, (HIDReportParser*)&Prs);
|
Mouse.SetReportParser(0,(HIDReportParser*)&Prs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
|
44
examples/HID/USBHID_desc/USBHID_desc.pde
Normal file
44
examples/HID/USBHID_desc/USBHID_desc.pde
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
#include <avrpins.h>
|
||||||
|
#include <max3421e.h>
|
||||||
|
#include <usbhost.h>
|
||||||
|
#include <usb_ch9.h>
|
||||||
|
#include <Usb.h>
|
||||||
|
#include <usbhub.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <address.h>
|
||||||
|
#include <hid.h>
|
||||||
|
#include <hiduniversal.h>
|
||||||
|
#include <hidescriptorparser.h>
|
||||||
|
#include <printhex.h>
|
||||||
|
#include <message.h>
|
||||||
|
#include <hexdump.h>
|
||||||
|
#include <parsetools.h>
|
||||||
|
|
||||||
|
#include "pgmstrings.h"
|
||||||
|
|
||||||
|
USB Usb;
|
||||||
|
USBHub Hub(&Usb);
|
||||||
|
HIDUniversal Hid(&Usb);
|
||||||
|
UniversalReportParser Uni;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin( 115200 );
|
||||||
|
Serial.println("Start");
|
||||||
|
|
||||||
|
if (Usb.Init() == -1)
|
||||||
|
Serial.println("OSC did not start.");
|
||||||
|
|
||||||
|
delay( 200 );
|
||||||
|
|
||||||
|
if (!Hid.SetReportParser(0, &Uni))
|
||||||
|
ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
Usb.Task();
|
||||||
|
}
|
||||||
|
|
52
examples/HID/USBHID_desc/pgmstrings.h
Normal file
52
examples/HID/USBHID_desc/pgmstrings.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#if !defined(__PGMSTRINGS_H__)
|
||||||
|
#define __PGMSTRINGS_H__
|
||||||
|
|
||||||
|
#define LOBYTE(x) ((char*)(&(x)))[0]
|
||||||
|
#define HIBYTE(x) ((char*)(&(x)))[1]
|
||||||
|
#define BUFSIZE 256 //buffer size
|
||||||
|
|
||||||
|
|
||||||
|
/* Print strings in Program Memory */
|
||||||
|
const char Gen_Error_str[] PROGMEM = "\r\nRequest error. Error code:\t";
|
||||||
|
const char Dev_Header_str[] PROGMEM ="\r\nDevice descriptor: ";
|
||||||
|
const char Dev_Length_str[] PROGMEM ="\r\nDescriptor Length:\t";
|
||||||
|
const char Dev_Type_str[] PROGMEM ="\r\nDescriptor type:\t";
|
||||||
|
const char Dev_Version_str[] PROGMEM ="\r\nUSB version:\t\t";
|
||||||
|
const char Dev_Class_str[] PROGMEM ="\r\nDevice class:\t\t";
|
||||||
|
const char Dev_Subclass_str[] PROGMEM ="\r\nDevice Subclass:\t";
|
||||||
|
const char Dev_Protocol_str[] PROGMEM ="\r\nDevice Protocol:\t";
|
||||||
|
const char Dev_Pktsize_str[] PROGMEM ="\r\nMax.packet size:\t";
|
||||||
|
const char Dev_Vendor_str[] PROGMEM ="\r\nVendor ID:\t\t";
|
||||||
|
const char Dev_Product_str[] PROGMEM ="\r\nProduct ID:\t\t";
|
||||||
|
const char Dev_Revision_str[] PROGMEM ="\r\nRevision ID:\t\t";
|
||||||
|
const char Dev_Mfg_str[] PROGMEM ="\r\nMfg.string index:\t";
|
||||||
|
const char Dev_Prod_str[] PROGMEM ="\r\nProd.string index:\t";
|
||||||
|
const char Dev_Serial_str[] PROGMEM ="\r\nSerial number index:\t";
|
||||||
|
const char Dev_Nconf_str[] PROGMEM ="\r\nNumber of conf.:\t";
|
||||||
|
const char Conf_Trunc_str[] PROGMEM ="Total length truncated to 256 bytes";
|
||||||
|
const char Conf_Header_str[] PROGMEM ="\r\nConfiguration descriptor:";
|
||||||
|
const char Conf_Totlen_str[] PROGMEM ="\r\nTotal length:\t\t";
|
||||||
|
const char Conf_Nint_str[] PROGMEM ="\r\nNum.intf:\t\t";
|
||||||
|
const char Conf_Value_str[] PROGMEM ="\r\nConf.value:\t\t";
|
||||||
|
const char Conf_String_str[] PROGMEM ="\r\nConf.string:\t\t";
|
||||||
|
const char Conf_Attr_str[] PROGMEM ="\r\nAttr.:\t\t\t";
|
||||||
|
const char Conf_Pwr_str[] PROGMEM ="\r\nMax.pwr:\t\t";
|
||||||
|
const char Int_Header_str[] PROGMEM ="\r\n\r\nInterface descriptor:";
|
||||||
|
const char Int_Number_str[] PROGMEM ="\r\nIntf.number:\t\t";
|
||||||
|
const char Int_Alt_str[] PROGMEM ="\r\nAlt.:\t\t\t";
|
||||||
|
const char Int_Endpoints_str[] PROGMEM ="\r\nEndpoints:\t\t";
|
||||||
|
const char Int_Class_str[] PROGMEM ="\r\nIntf. Class:\t\t";
|
||||||
|
const char Int_Subclass_str[] PROGMEM ="\r\nIntf. Subclass:\t\t";
|
||||||
|
const char Int_Protocol_str[] PROGMEM ="\r\nIntf. Protocol:\t\t";
|
||||||
|
const char Int_String_str[] PROGMEM ="\r\nIntf.string:\t\t";
|
||||||
|
const char End_Header_str[] PROGMEM ="\r\n\r\nEndpoint descriptor:";
|
||||||
|
const char End_Address_str[] PROGMEM ="\r\nEndpoint address:\t";
|
||||||
|
const char End_Attr_str[] PROGMEM ="\r\nAttr.:\t\t\t";
|
||||||
|
const char End_Pktsize_str[] PROGMEM ="\r\nMax.pkt size:\t\t";
|
||||||
|
const char End_Interval_str[] PROGMEM ="\r\nPolling interval:\t";
|
||||||
|
const char Unk_Header_str[] PROGMEM = "\r\nUnknown descriptor:";
|
||||||
|
const char Unk_Length_str[] PROGMEM ="\r\nLength:\t\t";
|
||||||
|
const char Unk_Type_str[] PROGMEM ="\r\nType:\t\t";
|
||||||
|
const char Unk_Contents_str[] PROGMEM ="\r\nContents:\t";
|
||||||
|
|
||||||
|
#endif // __PGMSTRINGS_H__
|
|
@ -10,13 +10,13 @@
|
||||||
#include "pgmstrings.h"
|
#include "pgmstrings.h"
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub1(&Usb);
|
//USBHub Hub1(&Usb);
|
||||||
USBHub Hub2(&Usb);
|
//USBHub Hub2(&Usb);
|
||||||
USBHub Hub3(&Usb);
|
//USBHub Hub3(&Usb);
|
||||||
USBHub Hub4(&Usb);
|
//USBHub Hub4(&Usb);
|
||||||
USBHub Hub5(&Usb);
|
//USBHub Hub5(&Usb);
|
||||||
USBHub Hub6(&Usb);
|
//USBHub Hub6(&Usb);
|
||||||
USBHub Hub7(&Usb);
|
//USBHub Hub7(&Usb);
|
||||||
|
|
||||||
uint32_t next_time;
|
uint32_t next_time;
|
||||||
|
|
||||||
|
@ -343,5 +343,5 @@ void printProgStr(const prog_char str[])
|
||||||
char c;
|
char c;
|
||||||
if(!str) return;
|
if(!str) return;
|
||||||
while((c = pgm_read_byte(str++)))
|
while((c = pgm_read_byte(str++)))
|
||||||
Serial.print(c,BYTE);
|
Serial.print(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ void loop()
|
||||||
|
|
||||||
if( rcvd ) { //more than zero bytes received
|
if( rcvd ) { //more than zero bytes received
|
||||||
for(uint16_t i=0; i < rcvd; i++ ) {
|
for(uint16_t i=0; i < rcvd; i++ ) {
|
||||||
Serial.print(buf[i]); //printing on the screen
|
Serial.print((char)buf[i]); //printing on the screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delay(10);
|
delay(10);
|
||||||
|
|
|
@ -63,7 +63,7 @@ uint8_t keylcl;
|
||||||
rcode = adk.SndData( 1, &keylcl );
|
rcode = adk.SndData( 1, &keylcl );
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.print( keylcl );
|
Serial.print((char) keylcl );
|
||||||
Serial.print(" : ");
|
Serial.print(" : ");
|
||||||
Serial.println( keylcl, HEX );
|
Serial.println( keylcl, HEX );
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <adk.h>
|
#include <adk.h>
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
|
//USBHub Hub(&Usb);
|
||||||
|
|
||||||
ADK adk(&Usb,"Circuits@Home, ltd.",
|
ADK adk(&Usb,"Circuits@Home, ltd.",
|
||||||
"USB Host Shield",
|
"USB Host Shield",
|
||||||
|
@ -50,7 +51,7 @@ void loop()
|
||||||
USBTRACE("\r\nData Packet.");
|
USBTRACE("\r\nData Packet.");
|
||||||
|
|
||||||
for( uint8_t i = 0; i < len; i++ ) {
|
for( uint8_t i = 0; i < len; i++ ) {
|
||||||
Serial.print(msg[i]);
|
Serial.print((char)msg[i]);
|
||||||
}
|
}
|
||||||
/* sending back what was received */
|
/* sending back what was received */
|
||||||
rcode = adk.SndData( strlen( recv ), (uint8_t *)recv );
|
rcode = adk.SndData( strlen( recv ), (uint8_t *)recv );
|
||||||
|
|
|
@ -69,21 +69,23 @@ void loop()
|
||||||
{
|
{
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
char strbuf[] = "DEADBEEF";
|
char strbuf[] = "DEADBEEF";
|
||||||
|
//char strbuf[] = "The quick brown fox jumps over the lazy dog";
|
||||||
|
//char strbuf[] = "This string contains 61 character to demonstrate FTDI buffers"; //add one symbol to it to see some garbage
|
||||||
Serial.print(".");
|
Serial.print(".");
|
||||||
|
|
||||||
rcode = Ftdi.SndData(8, (uint8_t*)strbuf);
|
rcode = Ftdi.SndData(strlen(strbuf), (uint8_t*)strbuf);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
|
ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
|
||||||
|
|
||||||
delay(50);
|
delay(50);
|
||||||
|
|
||||||
uint8_t buf[16];
|
uint8_t buf[64];
|
||||||
|
|
||||||
for (uint8_t i=0; i<16; i++)
|
for (uint8_t i=0; i<64; i++)
|
||||||
buf[i] = 0;
|
buf[i] = 0;
|
||||||
|
|
||||||
uint16_t rcvd = 15;
|
uint16_t rcvd = 64;
|
||||||
rcode = Ftdi.RcvData(&rcvd, buf);
|
rcode = Ftdi.RcvData(&rcvd, buf);
|
||||||
|
|
||||||
if (rcode && rcode != hrNAK)
|
if (rcode && rcode != hrNAK)
|
||||||
|
|
|
@ -339,5 +339,5 @@ void printProgStr(const prog_char str[])
|
||||||
char c;
|
char c;
|
||||||
if(!str) return;
|
if(!str) return;
|
||||||
while((c = pgm_read_byte(str++)))
|
while((c = pgm_read_byte(str++)))
|
||||||
Serial.print(c,BYTE);
|
Serial.print(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ uint8_t PLAsyncOper::OnInit(ACM *pacm)
|
||||||
USB Usb;
|
USB Usb;
|
||||||
//USBHub Hub(&Usb);
|
//USBHub Hub(&Usb);
|
||||||
PLAsyncOper AsyncOper;
|
PLAsyncOper AsyncOper;
|
||||||
PL Pl(&Usb, &AsyncOper);
|
PL2303 Pl(&Usb, &AsyncOper);
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
@ -96,7 +96,7 @@ void loop()
|
||||||
|
|
||||||
if( rcvd ) { //more than zero bytes received
|
if( rcvd ) { //more than zero bytes received
|
||||||
for(uint16_t i=0; i < rcvd; i++ ) {
|
for(uint16_t i=0; i < rcvd; i++ ) {
|
||||||
Serial.print(buf[i]); //printing on the screen
|
Serial.print((char)buf[i]); //printing on the screen
|
||||||
}
|
}
|
||||||
}//if( rcvd ...
|
}//if( rcvd ...
|
||||||
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
|
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
|
||||||
|
|
|
@ -52,9 +52,11 @@ uint8_t PLAsyncOper::OnInit(ACM *pacm)
|
||||||
}
|
}
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
//USBHub Hub(&Usb);
|
USBHub Hub(&Usb);
|
||||||
PLAsyncOper AsyncOper;
|
PLAsyncOper AsyncOper;
|
||||||
PL Pl(&Usb, &AsyncOper);
|
PL2303 Pl(&Usb, &AsyncOper);
|
||||||
|
uint32_t read_delay;
|
||||||
|
#define READ_DELAY 100
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
@ -69,23 +71,26 @@ void setup()
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
Usb.Task();
|
uint8_t rcode;
|
||||||
|
uint8_t buf[64]; //serial buffer equals Max.packet size of bulk-IN endpoint
|
||||||
|
uint16_t rcvd = 64;
|
||||||
|
|
||||||
|
Usb.Task();
|
||||||
|
|
||||||
if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
|
if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
|
||||||
{
|
{
|
||||||
uint8_t rcode;
|
|
||||||
uint8_t buf[64]; //serial buffer equals Max.packet size of bulk-IN endpoint
|
|
||||||
uint16_t rcvd = 64;
|
|
||||||
/* reading the GPS */
|
/* reading the GPS */
|
||||||
|
if( read_delay < millis() ){
|
||||||
|
read_delay += READ_DELAY;
|
||||||
rcode = Pl.RcvData(&rcvd, buf);
|
rcode = Pl.RcvData(&rcvd, buf);
|
||||||
if ( rcode && rcode != hrNAK )
|
if ( rcode && rcode != hrNAK )
|
||||||
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
|
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
|
||||||
if( rcvd ) { //more than zero bytes received
|
if( rcvd ) { //more than zero bytes received
|
||||||
for( uint16_t i=0; i < rcvd; i++ ) {
|
for( uint16_t i=0; i < rcvd; i++ ) {
|
||||||
Serial.print(buf[i]); //printing on the screen
|
Serial.print((char)buf[i]); //printing on the screen
|
||||||
}//for( uint16_t i=0; i < rcvd; i++...
|
}//for( uint16_t i=0; i < rcvd; i++...
|
||||||
}//if( rcvd
|
}//if( rcvd
|
||||||
//delay(10);
|
}//if( read_delay > millis()...
|
||||||
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
|
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ uint8_t PLAsyncOper::OnInit(ACM *pacm)
|
||||||
USB Usb;
|
USB Usb;
|
||||||
//USBHub Hub(&Usb);
|
//USBHub Hub(&Usb);
|
||||||
PLAsyncOper AsyncOper;
|
PLAsyncOper AsyncOper;
|
||||||
PL Pl(&Usb, &AsyncOper);
|
PL2303 Pl(&Usb, &AsyncOper);
|
||||||
TinyGPS gps;
|
TinyGPS gps;
|
||||||
|
|
||||||
void gpsdump(TinyGPS &gps);
|
void gpsdump(TinyGPS &gps);
|
||||||
|
|
|
@ -53,7 +53,7 @@ uint8_t PLAsyncOper::OnInit(ACM *pacm)
|
||||||
USB Usb;
|
USB Usb;
|
||||||
//USBHub Hub(&Usb);
|
//USBHub Hub(&Usb);
|
||||||
PLAsyncOper AsyncOper;
|
PLAsyncOper AsyncOper;
|
||||||
PL Pl(&Usb, &AsyncOper);
|
PL2303 Pl(&Usb, &AsyncOper);
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
@ -109,7 +109,7 @@ void loop()
|
||||||
Serial.print("\r\n"); //insert linefeed
|
Serial.print("\r\n"); //insert linefeed
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Serial.print(buf[i]); //printing on the screen
|
Serial.print((char)buf[i]); //printing on the screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
31
hid.cpp
31
hid.cpp
|
@ -1,40 +1,13 @@
|
||||||
/* 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 "hid.h"
|
#include "hid.h"
|
||||||
|
|
||||||
//const uint16_t HID::maxHidInterfaces = 3;
|
|
||||||
//const uint16_t HID::maxEpPerInterface = 2;
|
|
||||||
const uint8_t HID::epInterruptInIndex = 1;
|
|
||||||
const uint8_t HID::epInterruptOutIndex = 2;
|
|
||||||
|
|
||||||
|
|
||||||
//get HID report descriptor
|
//get HID report descriptor
|
||||||
uint8_t HID::GetReportDescr( uint8_t ep, USBReadParser *parser )
|
uint8_t HID::GetReportDescr( uint8_t ep, USBReadParser *parser )
|
||||||
{
|
{
|
||||||
const uint8_t constBufLen = 64;
|
const uint8_t constBufLen = 64;
|
||||||
uint8_t buf[constBufLen];
|
uint8_t buf[constBufLen];
|
||||||
|
|
||||||
//HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
|
uint8_t rcode = pUsb->ctrlReq( bAddress, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
||||||
|
HID_DESCRIPTOR_REPORT, 0x0000, 128, constBufLen, buf, (USBReadParser*)parser );
|
||||||
//return( pUsb->ctrlReq( bAddress, ep, /*bmREQ_HIDREPORT*/0x81, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
|
||||||
// HID_DESCRIPTOR_REPORT, 0x0000, constBufLen, constBufLen, buf, NULL ));
|
|
||||||
|
|
||||||
uint8_t rcode = pUsb->ctrlReq( bAddress, ep, /*bmREQ_HIDREPORT*/0x81, USB_REQUEST_GET_DESCRIPTOR, 0x00,
|
|
||||||
HID_DESCRIPTOR_REPORT, 0x0000, 0x4C1, constBufLen, buf, (USBReadParser*)parser );
|
|
||||||
|
|
||||||
//return ((rcode != hrSTALL) ? rcode : 0);
|
//return ((rcode != hrSTALL) ? rcode : 0);
|
||||||
return rcode;
|
return rcode;
|
||||||
|
|
52
hid.h
52
hid.h
|
@ -1,19 +1,3 @@
|
||||||
/* 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(__HID_H__)
|
#if !defined(__HID_H__)
|
||||||
#define __HID_H__
|
#define __HID_H__
|
||||||
|
|
||||||
|
@ -24,7 +8,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
@ -103,24 +92,6 @@ e-mail : support@circuitsathome.com
|
||||||
#define HID_PROTOCOL_KEYBOARD 0x01
|
#define HID_PROTOCOL_KEYBOARD 0x01
|
||||||
#define HID_PROTOCOL_MOUSE 0x02
|
#define HID_PROTOCOL_MOUSE 0x02
|
||||||
|
|
||||||
///* HID descriptor */
|
|
||||||
//typedef struct
|
|
||||||
//{
|
|
||||||
// uint8_t bLength;
|
|
||||||
// uint8_t bDescriptorType;
|
|
||||||
// uint16_t bcdHID; // HID class specification release
|
|
||||||
// uint8_t bCountryCode;
|
|
||||||
// uint8_t bNumDescriptors; // Number of additional class specific descriptors
|
|
||||||
// uint8_t bDescrType; // Type of class descriptor
|
|
||||||
// uint16_t wDescriptorLength; // Total size of the Report descriptor
|
|
||||||
//} USB_HID_DESCRIPTOR;
|
|
||||||
//
|
|
||||||
//typedef struct
|
|
||||||
//{
|
|
||||||
// uint8_t bDescrType; // Type of class descriptor
|
|
||||||
// uint16_t wDescriptorLength; // Total size of the Report descriptor
|
|
||||||
//} HID_CLASS_DESCRIPTOR_LEN_AND_TYPE;
|
|
||||||
|
|
||||||
struct HidItemPrefix
|
struct HidItemPrefix
|
||||||
{
|
{
|
||||||
uint8_t bSize : 2;
|
uint8_t bSize : 2;
|
||||||
|
@ -172,11 +143,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_REPORT_PARSERS 2
|
#define MAX_REPORT_PARSERS 2
|
||||||
|
|
||||||
#define maxHidInterfaces 3
|
|
||||||
#define maxEpPerInterface 2
|
|
||||||
#define totalEndpoints (maxHidInterfaces * maxEpPerInterface + 1)
|
|
||||||
|
|
||||||
#define HID_MAX_HID_CLASS_DESCRIPTORS 5
|
#define HID_MAX_HID_CLASS_DESCRIPTORS 5
|
||||||
|
|
||||||
class HID : public USBDeviceConfig, public UsbConfigXtracter
|
class HID : public USBDeviceConfig, public UsbConfigXtracter
|
||||||
|
@ -186,9 +152,13 @@ protected:
|
||||||
uint8_t bAddress; // address
|
uint8_t bAddress; // address
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const uint8_t epInterruptInIndex; // InterruptIN endpoint index
|
static const uint8_t epInterruptInIndex = 1; // InterruptIN endpoint index
|
||||||
static const uint8_t epInterruptOutIndex; // InterruptOUT endpoint index
|
static const uint8_t epInterruptOutIndex = 2; // InterruptOUT endpoint index
|
||||||
|
|
||||||
|
static const uint8_t maxHidInterfaces = 3;
|
||||||
|
static const uint8_t maxEpPerInterface = 2;
|
||||||
|
static const uint8_t totalEndpoints = (maxHidInterfaces * maxEpPerInterface + 1);
|
||||||
|
|
||||||
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||||
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
|
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
|
||||||
|
|
||||||
|
|
40
hidboot.h
40
hidboot.h
|
@ -25,7 +25,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
@ -208,9 +213,7 @@ void HIDBoot<BOOT_PROTOCOL>::Initialize()
|
||||||
epInfo[i].epAddr = 0;
|
epInfo[i].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||||
if (!i)
|
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
|
||||||
}
|
}
|
||||||
bNumEP = 1;
|
bNumEP = 1;
|
||||||
bNumIface = 0;
|
bNumIface = 0;
|
||||||
|
@ -322,18 +325,18 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
USBTRACE2("NC:", num_of_conf);
|
//USBTRACE2("NC:", num_of_conf);
|
||||||
|
|
||||||
for (uint8_t i=0; i<num_of_conf; i++)
|
for (uint8_t i=0; i<num_of_conf; i++)
|
||||||
{
|
{
|
||||||
HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
|
//HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
|
||||||
ConfigDescParser<
|
ConfigDescParser<
|
||||||
USB_CLASS_HID,
|
USB_CLASS_HID,
|
||||||
HID_BOOT_INTF_SUBCLASS,
|
HID_BOOT_INTF_SUBCLASS,
|
||||||
BOOT_PROTOCOL,
|
BOOT_PROTOCOL,
|
||||||
CP_MASK_COMPARE_ALL> confDescrParser(this);
|
CP_MASK_COMPARE_ALL> confDescrParser(this);
|
||||||
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
|
//rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
|
|
||||||
if (bNumEP > 1)
|
if (bNumEP > 1)
|
||||||
|
@ -343,13 +346,13 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
|
||||||
if (bNumEP < 2)
|
if (bNumEP < 2)
|
||||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||||
|
|
||||||
USBTRACE2("\r\nbAddr:", bAddress);
|
//USBTRACE2("\r\nbAddr:", bAddress);
|
||||||
USBTRACE2("\r\nbNumEP:", bNumEP);
|
//USBTRACE2("\r\nbNumEP:", bNumEP);
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
||||||
|
|
||||||
USBTRACE2("\r\nCnf:", bConfNum);
|
//USBTRACE2("\r\nCnf:", bConfNum);
|
||||||
|
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
|
@ -357,7 +360,7 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
USBTRACE2("\r\nIf:", bIfaceNum);
|
//USBTRACE2("\r\nIf:", bIfaceNum);
|
||||||
|
|
||||||
rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL);
|
rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL);
|
||||||
|
|
||||||
|
@ -413,9 +416,9 @@ void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t
|
||||||
if (bNumEP > 1 && conf != bConfNum)
|
if (bNumEP > 1 && conf != bConfNum)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
|
//ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
|
||||||
ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
|
//ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
|
||||||
ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
|
//ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
|
||||||
|
|
||||||
bConfNum = conf;
|
bConfNum = conf;
|
||||||
bIfaceNum = iface;
|
bIfaceNum = iface;
|
||||||
|
@ -424,7 +427,6 @@ void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t
|
||||||
|
|
||||||
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
||||||
{
|
{
|
||||||
USBTRACE("I8\r\n");
|
|
||||||
index = epInterruptInIndex;
|
index = epInterruptInIndex;
|
||||||
|
|
||||||
// Fill in the endpoint info structure
|
// Fill in the endpoint info structure
|
||||||
|
@ -434,7 +436,7 @@ void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t
|
||||||
|
|
||||||
bNumEP ++;
|
bNumEP ++;
|
||||||
|
|
||||||
PrintEndpointDescriptor(pep);
|
//PrintEndpointDescriptor(pep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,10 +480,10 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Poll()
|
||||||
USBTRACE2("Poll:", rcode);
|
USBTRACE2("Poll:", rcode);
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
for (uint8_t i=0; i<read; i++)
|
//for (uint8_t i=0; i<read; i++)
|
||||||
PrintHex<uint8_t>(buf[i]);
|
// PrintHex<uint8_t>(buf[i]);
|
||||||
if (read)
|
//if (read)
|
||||||
Serial.println("");
|
// Serial.println("");
|
||||||
|
|
||||||
if (pRptParser)
|
if (pRptParser)
|
||||||
pRptParser->Parse((HID*)this, 0, (uint8_t)read, buf);
|
pRptParser->Parse((HID*)this, 0, (uint8_t)read, buf);
|
||||||
|
|
|
@ -1,21 +1,4 @@
|
||||||
/* 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 "hidescriptorparser.h"
|
#include "hidescriptorparser.h"
|
||||||
//#include "hidusagetitlearrays.cpp"
|
|
||||||
|
|
||||||
const char *ReportDescParserBase::usagePageTitles0[] PROGMEM =
|
const char *ReportDescParserBase::usagePageTitles0[] PROGMEM =
|
||||||
{
|
{
|
||||||
|
@ -1060,7 +1043,7 @@ void ReportDescParserBase::Parse(const uint16_t len, const uint8_t *pbuf, const
|
||||||
//if (ParseItem(&p, &cntdn))
|
//if (ParseItem(&p, &cntdn))
|
||||||
// return;
|
// return;
|
||||||
}
|
}
|
||||||
USBTRACE2("Total:", totalSize);
|
//USBTRACE2("Total:", totalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReportDescParserBase::PrintValue(uint8_t *p, uint8_t len)
|
void ReportDescParserBase::PrintValue(uint8_t *p, uint8_t len)
|
||||||
|
@ -1348,7 +1331,7 @@ void ReportDescParserBase::PrintButtonPageUsage(uint16_t usage)
|
||||||
{
|
{
|
||||||
Notify(pstrSpace);
|
Notify(pstrSpace);
|
||||||
Notify(PSTR("Btn"));
|
Notify(PSTR("Btn"));
|
||||||
Serial.print(usage, DEC);
|
Serial.print(usage, HEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReportDescParserBase::PrintOrdinalPageUsage(uint16_t usage)
|
void ReportDescParserBase::PrintOrdinalPageUsage(uint16_t usage)
|
||||||
|
@ -1645,6 +1628,7 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn)
|
||||||
|
|
||||||
totalSize += (uint16_t)rptSize * (uint16_t)rptCount;
|
totalSize += (uint16_t)rptSize * (uint16_t)rptCount;
|
||||||
|
|
||||||
|
// Êàæåòñÿ ýòî íàäî äåëàòü â íà÷àëå, à íå â êîíöå...
|
||||||
rptSize = 0;
|
rptSize = 0;
|
||||||
rptCount = 0;
|
rptCount = 0;
|
||||||
useMin = 0;
|
useMin = 0;
|
||||||
|
@ -1661,8 +1645,13 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
{
|
{
|
||||||
uint8_t byte_offset = (totalSize >> 3); // calculate offset to the next unhandled byte i = (int)(totalCount / 8);
|
uint8_t byte_offset = (totalSize >> 3); // calculate offset to the next unhandled byte i = (int)(totalCount / 8);
|
||||||
uint32_t tmp = (byte_offset << 3);
|
uint32_t tmp = (byte_offset << 3);
|
||||||
uint8_t bit_offset = totalSize - tmp; // number of bits in the current byte already handled
|
uint8_t bit_offset = totalSize - tmp; // number of bits in the current byte already handled
|
||||||
uint8_t *p = pBuf + byte_offset; // current byte pointer
|
uint8_t *p = pBuf + byte_offset; // current byte pointer
|
||||||
|
|
||||||
|
|
||||||
|
//Serial.print("Itm:");
|
||||||
|
//PrintHex<uint8_t>(itm);
|
||||||
|
//Serial.println("");
|
||||||
|
|
||||||
//Serial.print(" tS:");
|
//Serial.print(" tS:");
|
||||||
//PrintHex<uint32_t>(totalSize);
|
//PrintHex<uint32_t>(totalSize);
|
||||||
|
@ -1684,11 +1673,35 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
|
|
||||||
uint8_t usage = useMin;
|
uint8_t usage = useMin;
|
||||||
|
|
||||||
|
//Serial.print("\r\nUseMin:");
|
||||||
|
//PrintHex<uint8_t>(useMin);
|
||||||
|
//Serial.println("");
|
||||||
|
|
||||||
|
//Serial.print("UseMax:");
|
||||||
|
//PrintHex<uint8_t>(useMax);
|
||||||
|
//Serial.println("");
|
||||||
|
|
||||||
|
//Serial.print("pF:");
|
||||||
|
//PrintHex<uint16_t>(useMin);
|
||||||
|
//Serial.println("");
|
||||||
|
|
||||||
bool print_usemin_usemax = ( (useMin < useMax) && ((itm & 3) == 2) && pfUsage) ? true : false;
|
bool print_usemin_usemax = ( (useMin < useMax) && ((itm & 3) == 2) && pfUsage) ? true : false;
|
||||||
|
|
||||||
uint8_t bits_of_byte = 8;
|
uint8_t bits_of_byte = 8;
|
||||||
|
|
||||||
for (uint8_t i=0; i<rptCount; i++, usage++)
|
// rptSize==1, rptCount==10i
|
||||||
|
// x x x x x x x x x x
|
||||||
|
// | |
|
||||||
|
// one bit field
|
||||||
|
//
|
||||||
|
// | |
|
||||||
|
// one byte == 8 bits
|
||||||
|
//
|
||||||
|
// | |
|
||||||
|
// field array == 10 bits
|
||||||
|
|
||||||
|
// for each field in field array defined by rptCount
|
||||||
|
for (uint8_t field=0; field<rptCount; field++, usage++)
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -1697,33 +1710,41 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
uint32_t dwResult;
|
uint32_t dwResult;
|
||||||
} result;
|
} result;
|
||||||
|
|
||||||
result.dwResult = 0;
|
result.dwResult = 0;
|
||||||
|
|
||||||
uint8_t mask = 0;
|
uint8_t mask = 0;
|
||||||
|
|
||||||
// bits_left - number of bits in the field left to process
|
if (print_usemin_usemax)
|
||||||
|
pfUsage(usage);
|
||||||
|
|
||||||
|
// bits_left - number of bits in the field(array of fields, depending on Report Count) left to process
|
||||||
// bits_of_byte - number of bits in current byte left to process
|
// bits_of_byte - number of bits in current byte left to process
|
||||||
// bits_to_copy - number of bits to copy to result buffer
|
// bits_to_copy - number of bits to copy to result buffer
|
||||||
|
|
||||||
|
// for each bit in a field
|
||||||
for (uint8_t bits_left=rptSize, bits_to_copy=0; bits_left;
|
for (uint8_t bits_left=rptSize, bits_to_copy=0; bits_left;
|
||||||
bits_left -= bits_to_copy)
|
bits_left -= bits_to_copy)
|
||||||
{
|
{
|
||||||
bits_to_copy = (bits_left > 8) ? 8 : (bits_left > bits_of_byte) ? bits_of_byte : bits_left;
|
bits_to_copy = (bits_left > bits_of_byte) ? bits_of_byte : bits_left;
|
||||||
|
//bits_to_copy = (bits_left > 8) ? 8 : (bits_left > bits_of_byte) ? bits_of_byte : bits_left;
|
||||||
|
|
||||||
result.dwResult <<= bits_to_copy; // Result buffer is shifted by the number of bits to be copied into it
|
result.dwResult <<= bits_to_copy; // Result buffer is shifted by the number of bits to be copied into it
|
||||||
|
|
||||||
if (bits_to_copy == 8)
|
//if (bits_to_copy == 8)
|
||||||
{
|
//{
|
||||||
result.bResult[0] = *p;
|
// result.dwResult = (uint32_t)*p;
|
||||||
bits_of_byte = 8;
|
// bits_of_byte = 8;
|
||||||
p ++;
|
// p ++;
|
||||||
continue;
|
// continue;
|
||||||
}
|
//}
|
||||||
|
|
||||||
uint8_t val = *p;
|
uint8_t val = *p;
|
||||||
|
|
||||||
val >>= (8 - bits_of_byte); // Shift by the number of bits already processed
|
val >>= (8 - bits_of_byte); // Shift by the number of bits already processed
|
||||||
|
|
||||||
|
//Serial.print(" bl:");
|
||||||
|
//PrintHex<uint8_t>(bits_left);
|
||||||
|
|
||||||
//Serial.print(" sh:");
|
//Serial.print(" sh:");
|
||||||
//PrintHex<uint8_t>(8 - bits_of_byte);
|
//PrintHex<uint8_t>(8 - bits_of_byte);
|
||||||
|
|
||||||
|
@ -1741,7 +1762,8 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
result.bResult[0] = (result.bResult[0] | (val & mask));
|
result.bResult[0] = (result.bResult[0] | (val & mask));
|
||||||
|
|
||||||
//Serial.print(" res:");
|
//Serial.print(" res:");
|
||||||
//PrintHex<uint8_t>(result.bResult[0]);
|
//Serial.print(": ");
|
||||||
|
//PrintHex<uint32_t>(result.dwResult);
|
||||||
|
|
||||||
//Serial.print(" b2c:");
|
//Serial.print(" b2c:");
|
||||||
//PrintHex<uint8_t>(bits_to_copy);
|
//PrintHex<uint8_t>(bits_to_copy);
|
||||||
|
@ -1750,13 +1772,120 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
|
|
||||||
//Serial.print(" bob:");
|
//Serial.print(" bob:");
|
||||||
//PrintHex<uint8_t>(bits_of_byte);
|
//PrintHex<uint8_t>(bits_of_byte);
|
||||||
|
|
||||||
|
if (bits_of_byte < 1)
|
||||||
|
{
|
||||||
|
bits_of_byte = 8;
|
||||||
|
p ++;
|
||||||
|
}
|
||||||
|
//Serial.println("");
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintByteValue(result.bResult[0]);
|
PrintByteValue(result.dwResult);
|
||||||
}
|
}
|
||||||
Serial.println("");
|
Serial.println("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
|
//{
|
||||||
|
// uint8_t byte_offset = (totalSize >> 3); // calculate offset to the next unhandled byte i = (int)(totalCount / 8);
|
||||||
|
// uint32_t tmp = (byte_offset << 3);
|
||||||
|
// uint8_t bit_offset = totalSize - tmp; // number of bits in the current byte already handled
|
||||||
|
// uint8_t *p = pBuf + byte_offset; // current byte pointer
|
||||||
|
//
|
||||||
|
// //Serial.print(" tS:");
|
||||||
|
// //PrintHex<uint32_t>(totalSize);
|
||||||
|
//
|
||||||
|
// //Serial.print(" byO:");
|
||||||
|
// //PrintHex<uint8_t>(byte_offset);
|
||||||
|
//
|
||||||
|
// //Serial.print(" biO:");
|
||||||
|
// //PrintHex<uint8_t>(bit_offset);
|
||||||
|
//
|
||||||
|
// //Serial.print(" rSz:");
|
||||||
|
// //PrintHex<uint8_t>(rptSize);
|
||||||
|
//
|
||||||
|
// //Serial.print(" rCn:");
|
||||||
|
// //PrintHex<uint8_t>(rptCount);
|
||||||
|
//
|
||||||
|
// if (bit_offset)
|
||||||
|
// *p >>= bit_offset;
|
||||||
|
//
|
||||||
|
// uint8_t usage = useMin;
|
||||||
|
//
|
||||||
|
// bool print_usemin_usemax = ( (useMin < useMax) && ((itm & 3) == 2) && pfUsage) ? true : false;
|
||||||
|
//
|
||||||
|
// uint8_t bits_of_byte = 8;
|
||||||
|
//
|
||||||
|
// for (uint8_t i=0; i<rptCount; i++, usage++)
|
||||||
|
// {
|
||||||
|
// union
|
||||||
|
// {
|
||||||
|
// uint8_t bResult[4];
|
||||||
|
// uint16_t wResult[2];
|
||||||
|
// uint32_t dwResult;
|
||||||
|
// } result;
|
||||||
|
//
|
||||||
|
// result.dwResult = 0;
|
||||||
|
//
|
||||||
|
// uint8_t mask = 0;
|
||||||
|
//
|
||||||
|
// // bits_left - number of bits in the field(array of fields, depending on Report Count) left to process
|
||||||
|
// // bits_of_byte - number of bits in current byte left to process
|
||||||
|
// // bits_to_copy - number of bits to copy to result buffer
|
||||||
|
//
|
||||||
|
// for (uint8_t bits_left=rptSize, bits_to_copy=0; bits_left;
|
||||||
|
// bits_left -= bits_to_copy)
|
||||||
|
// {
|
||||||
|
// bits_to_copy = (bits_left > 8) ? 8 : (bits_left > bits_of_byte) ? bits_of_byte : bits_left;
|
||||||
|
//
|
||||||
|
// result.dwResult <<= bits_to_copy; // Result buffer is shifted by the number of bits to be copied into it
|
||||||
|
//
|
||||||
|
// if (bits_to_copy == 8)
|
||||||
|
// {
|
||||||
|
// result.bResult[0] = *p;
|
||||||
|
// bits_of_byte = 8;
|
||||||
|
// p ++;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// uint8_t val = *p;
|
||||||
|
//
|
||||||
|
// val >>= (8 - bits_of_byte); // Shift by the number of bits already processed
|
||||||
|
//
|
||||||
|
// //Serial.print(" sh:");
|
||||||
|
// //PrintHex<uint8_t>(8 - bits_of_byte);
|
||||||
|
//
|
||||||
|
// mask = 0;
|
||||||
|
//
|
||||||
|
// for (uint8_t j=bits_to_copy; j; j--)
|
||||||
|
// {
|
||||||
|
// mask <<= 1;
|
||||||
|
// mask |= 1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //Serial.print(" msk:");
|
||||||
|
// //PrintHex<uint8_t>(mask);
|
||||||
|
//
|
||||||
|
// result.bResult[0] = (result.bResult[0] | (val & mask));
|
||||||
|
//
|
||||||
|
// //Serial.print(" res:");
|
||||||
|
// //PrintHex<uint8_t>(result.bResult[0]);
|
||||||
|
//
|
||||||
|
// //Serial.print(" b2c:");
|
||||||
|
// //PrintHex<uint8_t>(bits_to_copy);
|
||||||
|
//
|
||||||
|
// bits_of_byte -= bits_to_copy;
|
||||||
|
//
|
||||||
|
// //Serial.print(" bob:");
|
||||||
|
// //PrintHex<uint8_t>(bits_of_byte);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// PrintByteValue(result.bResult[0]);
|
||||||
|
// }
|
||||||
|
// Serial.println("");
|
||||||
|
//}
|
||||||
|
|
||||||
void UniversalReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
|
void UniversalReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
|
||||||
{
|
{
|
||||||
ReportDescParser2 prs(len, buf);
|
ReportDescParser2 prs(len, buf);
|
||||||
|
|
|
@ -24,7 +24,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
|
|
|
@ -51,13 +51,13 @@ void HIDUniversal::Initialize()
|
||||||
epInfo[i].epAddr = 0;
|
epInfo[i].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||||
if (!i)
|
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
|
||||||
}
|
}
|
||||||
bNumEP = 1;
|
bNumEP = 1;
|
||||||
bNumIface = 0;
|
bNumIface = 0;
|
||||||
bConfNum = 0;
|
bConfNum = 0;
|
||||||
|
|
||||||
|
ZeroMemory(constBuffLen, prevBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HIDUniversal::SetReportParser(uint8_t id, HIDReportParser *prs)
|
bool HIDUniversal::SetReportParser(uint8_t id, HIDReportParser *prs)
|
||||||
|
@ -96,7 +96,6 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||||
UsbDevice *p = NULL;
|
UsbDevice *p = NULL;
|
||||||
EpInfo *oldep_ptr = NULL;
|
EpInfo *oldep_ptr = NULL;
|
||||||
uint8_t len = 0;
|
uint8_t len = 0;
|
||||||
uint16_t cd_len = 0;
|
|
||||||
|
|
||||||
uint8_t num_of_conf; // number of configurations
|
uint8_t num_of_conf; // number of configurations
|
||||||
uint8_t num_of_intf; // number of interfaces
|
uint8_t num_of_intf; // number of interfaces
|
||||||
|
@ -195,11 +194,11 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||||
|
|
||||||
for (uint8_t i=0; i<num_of_conf; i++)
|
for (uint8_t i=0; i<num_of_conf; i++)
|
||||||
{
|
{
|
||||||
HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
|
//HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
|
||||||
ConfigDescParser<USB_CLASS_HID, 0, 0,
|
ConfigDescParser<USB_CLASS_HID, 0, 0,
|
||||||
CP_MASK_COMPARE_CLASS> confDescrParser(this);
|
CP_MASK_COMPARE_CLASS> confDescrParser(this);
|
||||||
|
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
|
//rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
|
|
||||||
if (bNumEP > 1)
|
if (bNumEP > 1)
|
||||||
|
@ -215,7 +214,6 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||||
USBTRACE2("\r\nCnf:", bConfNum);
|
USBTRACE2("\r\nCnf:", bConfNum);
|
||||||
|
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
//rcode = pUsb->setConf(bAddress, 0, 0);
|
|
||||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
|
@ -226,16 +224,9 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||||
if (hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
|
if (hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
USBTRACE("Proto\r\n");
|
|
||||||
|
|
||||||
//rcode = SetProtocol(hidInterfaces[i].bmInterface, HID_RPT_PROTOCOL);
|
|
||||||
|
|
||||||
//if (rcode)
|
|
||||||
// goto FailSetProtocol;
|
|
||||||
|
|
||||||
rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
|
rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode && rcode != hrSTALL)
|
||||||
goto FailSetIdle;
|
goto FailSetIdle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,9 +294,9 @@ void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint
|
||||||
if (bNumEP > 1 && conf != bConfNum)
|
if (bNumEP > 1 && conf != bConfNum)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
|
//ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
|
||||||
ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
|
//ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
|
||||||
ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
|
//ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
|
||||||
|
|
||||||
bConfNum = conf;
|
bConfNum = conf;
|
||||||
|
|
||||||
|
@ -323,31 +314,24 @@ void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
||||||
{
|
|
||||||
USBTRACE("I8\r\n");
|
|
||||||
index = epInterruptInIndex;
|
index = epInterruptInIndex;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
USBTRACE("I0\r\n");
|
|
||||||
index = epInterruptOutIndex;
|
index = epInterruptOutIndex;
|
||||||
}
|
|
||||||
|
|
||||||
if (index)
|
if (index)
|
||||||
{
|
{
|
||||||
USBTRACE2("Ind:", index);
|
|
||||||
|
|
||||||
// Fill in the endpoint info structure
|
// Fill in the endpoint info structure
|
||||||
epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
|
epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
|
||||||
epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
|
epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
|
||||||
epInfo[bNumEP].epAttribs = 0;
|
epInfo[bNumEP].epAttribs = 0;
|
||||||
|
epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
|
||||||
|
|
||||||
// Fill in the endpoint index list
|
// Fill in the endpoint index list
|
||||||
piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
|
piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
|
||||||
|
|
||||||
bNumEP ++;
|
bNumEP ++;
|
||||||
}
|
}
|
||||||
PrintEndpointDescriptor(pep);
|
//PrintEndpointDescriptor(pep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -362,6 +346,25 @@ uint8_t HIDUniversal::Release()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<len; i++)
|
||||||
|
if (buf1[i] != buf2[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<len; i++)
|
||||||
|
buf[i] = 0;
|
||||||
|
}
|
||||||
|
void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<len; i++)
|
||||||
|
dest[i] = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t HIDUniversal::Poll()
|
uint8_t HIDUniversal::Poll()
|
||||||
{
|
{
|
||||||
uint8_t rcode = 0;
|
uint8_t rcode = 0;
|
||||||
|
@ -373,18 +376,14 @@ uint8_t HIDUniversal::Poll()
|
||||||
{
|
{
|
||||||
qNextPollTime = millis() + 50;
|
qNextPollTime = millis() + 50;
|
||||||
|
|
||||||
const uint8_t const_buff_len = 16;
|
uint8_t buf[constBuffLen];
|
||||||
uint8_t buf[const_buff_len];
|
|
||||||
|
|
||||||
for (uint8_t i=0; i<bNumIface; i++)
|
for (uint8_t i=0; i<bNumIface; i++)
|
||||||
{
|
{
|
||||||
uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
|
uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
|
||||||
uint16_t read = (uint16_t)epInfo[index].maxPktSize;
|
uint16_t read = (uint16_t)epInfo[index].maxPktSize;
|
||||||
|
|
||||||
USBTRACE2("i:", i);
|
ZeroMemory(constBuffLen, buf);
|
||||||
USBTRACE2("Ind:", index);
|
|
||||||
USBTRACE2("EP:", epInfo[index].epAddr);
|
|
||||||
USBTRACE2("Rd:", read);
|
|
||||||
|
|
||||||
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
|
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
|
||||||
|
|
||||||
|
@ -392,25 +391,31 @@ uint8_t HIDUniversal::Poll()
|
||||||
{
|
{
|
||||||
if (rcode != hrNAK)
|
if (rcode != hrNAK)
|
||||||
USBTRACE2("Poll:", rcode);
|
USBTRACE2("Poll:", rcode);
|
||||||
else
|
|
||||||
USBTRACE2("poll:", rcode);
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
Serial.print("Read:");
|
|
||||||
PrintHex<uint8_t>(read);
|
if (read > constBuffLen)
|
||||||
Serial.println("");
|
read = constBuffLen;
|
||||||
|
|
||||||
|
bool identical = BuffersIdentical(read, buf, prevBuf);
|
||||||
|
|
||||||
|
SaveBuffer(read, buf, prevBuf);
|
||||||
|
|
||||||
|
if (identical)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Serial.print("\r\nBuf: ");
|
||||||
|
|
||||||
for (uint8_t i=0; i<read; i++)
|
for (uint8_t i=0; i<read; i++)
|
||||||
PrintHex<uint8_t>(buf[i]);
|
PrintHex<uint8_t>(buf[i]);
|
||||||
if (read)
|
|
||||||
Serial.println("");
|
Serial.println("");
|
||||||
|
|
||||||
HIDReportParser *prs = GetReportParser( ((bHasReportId) ? *buf : 0) );
|
HIDReportParser *prs = GetReportParser( ((bHasReportId) ? *buf : 0) );
|
||||||
|
|
||||||
if (prs)
|
if (prs)
|
||||||
prs->Parse(this, bHasReportId, (uint8_t)read, buf);
|
prs->Parse(this, bHasReportId, (uint8_t)read, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,16 @@ class HIDUniversal : public HID
|
||||||
uint32_t qNextPollTime; // next poll time
|
uint32_t qNextPollTime; // next poll time
|
||||||
bool bPollEnable; // poll enable flag
|
bool bPollEnable; // poll enable flag
|
||||||
|
|
||||||
|
static const uint16_t constBuffLen = 64; // event buffer length
|
||||||
|
uint8_t prevBuf[constBuffLen]; // previous event buffer
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
HIDInterface* FindInterface(uint8_t iface, uint8_t alt, uint8_t proto);
|
HIDInterface* FindInterface(uint8_t iface, uint8_t alt, uint8_t proto);
|
||||||
|
|
||||||
|
void ZeroMemory(uint8_t len, uint8_t *buf);
|
||||||
|
bool BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2);
|
||||||
|
void SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool bHasReportId;
|
bool bHasReportId;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "WProgram.h"
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// pin definition and set/clear
|
// pin definition and set/clear
|
||||||
|
|
||||||
|
|
|
@ -23,5 +23,9 @@ void Notify(char const * msg)
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
while((c = pgm_read_byte(msg++)))
|
while((c = pgm_read_byte(msg++)))
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
Serial.print(c);
|
||||||
|
#else
|
||||||
Serial.print(c,BYTE);
|
Serial.print(c,BYTE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include <WProgram.h>
|
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct MultiValueBuffer
|
struct MultiValueBuffer
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,11 @@ e-mail : support@circuitsathome.com
|
||||||
#if !defined(__PRINTHEX_H__)
|
#if !defined(__PRINTHEX_H__)
|
||||||
#define __PRINTHEX_H__
|
#define __PRINTHEX_H__
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PrintHex(T val)
|
void PrintHex(T val)
|
||||||
|
|
|
@ -18,7 +18,6 @@ e-mail : support@circuitsathome.com
|
||||||
#ifndef _USBHOST_H_
|
#ifndef _USBHOST_H_
|
||||||
#define _USBHOST_H_
|
#define _USBHOST_H_
|
||||||
|
|
||||||
//#include <WProgram.h>
|
|
||||||
#include "avrpins.h"
|
#include "avrpins.h"
|
||||||
#include "max3421e.h"
|
#include "max3421e.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
|
|
|
@ -32,8 +32,9 @@ USBHub::USBHub(USB *p) :
|
||||||
epInfo[0].bmNakPower = USB_NAK_MAX_POWER;
|
epInfo[0].bmNakPower = USB_NAK_MAX_POWER;
|
||||||
|
|
||||||
epInfo[1].epAddr = 1;
|
epInfo[1].epAddr = 1;
|
||||||
epInfo[1].maxPktSize = 1;
|
epInfo[1].maxPktSize = 8; //kludge
|
||||||
epInfo[1].epAttribs = 0;
|
epInfo[1].epAttribs = 0;
|
||||||
|
epInfo[1].bmNakPower = USB_NAK_NOWAIT;
|
||||||
|
|
||||||
if (pUsb)
|
if (pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
|
@ -368,7 +369,7 @@ void PrintHubPortStatus(USBHub *hubptr, uint8_t addr, uint8_t port, bool print_c
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
{
|
{
|
||||||
Serial.println("ERROR!!!");
|
Serial.println("ERROR!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Serial.print("\r\nPort ");
|
Serial.print("\r\nPort ");
|
||||||
|
|
5
usbhub.h
5
usbhub.h
|
@ -24,7 +24,12 @@ e-mail : support@circuitsathome.com
|
||||||
#include "usbhost.h"
|
#include "usbhost.h"
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define USB_DESCRIPTOR_HUB 0x09 // Hub descriptor type
|
#define USB_DESCRIPTOR_HUB 0x09 // Hub descriptor type
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue