mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
HID joystick support and examples
This commit is contained in:
parent
31a1357954
commit
3d068a0637
15 changed files with 292 additions and 207 deletions
1
Usb.cpp
1
Usb.cpp
|
@ -391,6 +391,7 @@ uint8_t USB::dispatchPkt( uint8_t token, uint8_t ep, uint16_t nak_limit )
|
||||||
nak_count ++;
|
nak_count ++;
|
||||||
if( nak_limit && ( nak_count == nak_limit ))
|
if( nak_limit && ( nak_count == nak_limit ))
|
||||||
return( rcode );
|
return( rcode );
|
||||||
|
//delay(1);
|
||||||
break;
|
break;
|
||||||
case hrTIMEOUT:
|
case hrTIMEOUT:
|
||||||
retry_count ++;
|
retry_count ++;
|
||||||
|
|
|
@ -24,8 +24,8 @@ e-mail : support@circuitsathome.com
|
||||||
|
|
||||||
/* NAK powers. To save space in endpoint data structure, amount of retries before giving up and returning 0x4 is stored in */
|
/* 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) */
|
/* 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 16 //NAK binary order maximum value
|
||||||
#define USB_NAK_DEFAULT 14 //default 32K-1 NAKs before giving up
|
#define USB_NAK_DEFAULT 14 //default 16K-1 NAKs before giving up
|
||||||
#define USB_NAK_NOWAIT 1 //Single NAK stops transfer
|
#define USB_NAK_NOWAIT 1 //Single NAK stops transfer
|
||||||
#define USB_NAK_NONAK 0 //Do not count NAKs, stop retrying after USB Timeout
|
#define USB_NAK_NONAK 0 //Do not count NAKs, stop retrying after USB Timeout
|
||||||
|
|
||||||
|
|
14
cdcacm.cpp
14
cdcacm.cpp
|
@ -210,9 +210,9 @@ Fail:
|
||||||
|
|
||||||
void ACM::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep)
|
void ACM::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep)
|
||||||
{
|
{
|
||||||
ErrorMessage<uint8_t>(PSTR("Conf.Val"), conf);
|
//ErrorMessage<uint8_t>(PSTR("Conf.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;
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ void ACM::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
|
||||||
|
|
||||||
bNumEP ++;
|
bNumEP ++;
|
||||||
|
|
||||||
PrintEndpointDescriptor(pep);
|
//PrintEndpointDescriptor(pep);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ACM::Release()
|
uint8_t ACM::Release()
|
||||||
|
@ -298,6 +298,12 @@ uint8_t ACM::SndData(uint16_t nbytes, uint8_t *dataptr)
|
||||||
return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr);
|
return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* untested */
|
||||||
|
uint8_t ACM::GetNotif( uint16_t *bytes_rcvd, uint8_t *dataptr )
|
||||||
|
{
|
||||||
|
return pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, bytes_rcvd, dataptr);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t ACM::SetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr)
|
uint8_t ACM::SetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr)
|
||||||
{
|
{
|
||||||
return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL ));
|
return( pUsb->ctrlReq( bAddress, 0, bmREQ_CDCOUT, CDC_SET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL ));
|
||||||
|
|
22
cdcacm.h
22
cdcacm.h
|
@ -89,6 +89,17 @@ e-mail : support@circuitsathome.com
|
||||||
#define CDC_GET_LINE_PARMS 0x35
|
#define CDC_GET_LINE_PARMS 0x35
|
||||||
#define CDC_DIAL_DIGITS 0x36
|
#define CDC_DIAL_DIGITS 0x36
|
||||||
|
|
||||||
|
//Class-Specific Notification Codes
|
||||||
|
#define NETWORK_CONNECTION 0x00
|
||||||
|
#define RESPONSE_AVAILABLE 0x01
|
||||||
|
#define AUX_JACK_HOOK_STATE 0x08
|
||||||
|
#define RING_DETECT 0x09
|
||||||
|
#define SERIAL_STATE 0x20
|
||||||
|
#define CALL_STATE_CHANGE 0x28
|
||||||
|
#define LINE_STATE_CHANGE 0x29
|
||||||
|
#define CONNECTION_SPEED_CHANGE 0x2a
|
||||||
|
|
||||||
|
|
||||||
// CDC Functional Descriptor Structures
|
// CDC Functional Descriptor Structures
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -125,6 +136,16 @@ typedef struct
|
||||||
uint8_t bDataBits; // Data bits (5, 6, 7, 8 or 16)
|
uint8_t bDataBits; // Data bits (5, 6, 7, 8 or 16)
|
||||||
} LINE_CODING;
|
} LINE_CODING;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t bmRequestType; // 0xa1 for class-specific notifications
|
||||||
|
uint8_t bNotification;
|
||||||
|
uint16_t wValue;
|
||||||
|
uint16_t wIndex;
|
||||||
|
uint16_t wLength;
|
||||||
|
uint16_t bmState; //UART state bitmap for SERIAL_STATE, other notifications variable length
|
||||||
|
} CLASS_NOTIFICATION;
|
||||||
|
|
||||||
class ACM;
|
class ACM;
|
||||||
|
|
||||||
class CDCAsyncOper
|
class CDCAsyncOper
|
||||||
|
@ -170,6 +191,7 @@ public:
|
||||||
uint8_t GetLineCoding(LINE_CODING *dataptr);
|
uint8_t GetLineCoding(LINE_CODING *dataptr);
|
||||||
uint8_t SetControlLineState(uint8_t state);
|
uint8_t SetControlLineState(uint8_t state);
|
||||||
uint8_t SendBreak(uint16_t duration);
|
uint8_t SendBreak(uint16_t duration);
|
||||||
|
uint8_t GetNotif( uint16_t *bytes_rcvd, uint8_t *dataptr );
|
||||||
|
|
||||||
// Methods for recieving and sending data
|
// Methods for recieving and sending data
|
||||||
uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
|
uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
|
||||||
|
|
|
@ -132,10 +132,10 @@ uint8_t PL2303::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<0xFF, 0, 0, CP_MASK_COMPARE_CLASS> confDescrParser(this);
|
ConfigDescParser<0xFF, 0, 0, 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)
|
||||||
|
|
46
examples/HID/USBHIDJoystick/USBHIDJoystick.pde
Normal file
46
examples/HID/USBHIDJoystick/USBHIDJoystick.pde
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
#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 "hidjoystickrptparser.h"
|
||||||
|
|
||||||
|
#include <printhex.h>
|
||||||
|
#include <message.h>
|
||||||
|
#include <hexdump.h>
|
||||||
|
#include <parsetools.h>
|
||||||
|
|
||||||
|
USB Usb;
|
||||||
|
USBHub Hub(&Usb);
|
||||||
|
HIDUniversal Hid(&Usb);
|
||||||
|
JoystickEvents JoyEvents;
|
||||||
|
JoystickReportParser Joy(&JoyEvents);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin( 115200 );
|
||||||
|
Serial.println("Start");
|
||||||
|
|
||||||
|
if (Usb.Init() == -1)
|
||||||
|
Serial.println("OSC did not start.");
|
||||||
|
|
||||||
|
delay( 200 );
|
||||||
|
|
||||||
|
if (!Hid.SetReportParser(0, &Joy))
|
||||||
|
ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
Usb.Task();
|
||||||
|
}
|
||||||
|
|
95
examples/HID/USBHIDJoystick/hidjoystickrptparser.cpp
Normal file
95
examples/HID/USBHIDJoystick/hidjoystickrptparser.cpp
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#include "hidjoystickrptparser.h"
|
||||||
|
|
||||||
|
JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
|
||||||
|
joyEvents(evt),
|
||||||
|
oldHat(0xDE),
|
||||||
|
oldButtons(0)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<RPT_GEMEPAD_LEN; i++)
|
||||||
|
oldPad[i] = 0xD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
|
||||||
|
{
|
||||||
|
bool match = true;
|
||||||
|
|
||||||
|
// Checking if there are changes in report since the method was last called
|
||||||
|
for (uint8_t i=0; i<RPT_GEMEPAD_LEN; i++)
|
||||||
|
if (buf[i] != oldPad[i])
|
||||||
|
{
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calling Game Pad event handler
|
||||||
|
if (!match && joyEvents)
|
||||||
|
{
|
||||||
|
joyEvents->OnGamePadChanged((const GamePadEventData*)buf);
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<RPT_GEMEPAD_LEN; i++) oldPad[i] = buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t hat = (buf[5] & 0xF);
|
||||||
|
|
||||||
|
// Calling Hat Switch event handler
|
||||||
|
if (hat != oldHat && joyEvents)
|
||||||
|
{
|
||||||
|
joyEvents->OnHatSwitch(hat);
|
||||||
|
oldHat = hat;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t buttons = (0x0000 | buf[6]);
|
||||||
|
buttons <<= 4;
|
||||||
|
buttons |= (buf[5] >> 4);
|
||||||
|
uint16_t changes = (buttons ^ oldButtons);
|
||||||
|
|
||||||
|
// Calling Button Event Handler for every button changed
|
||||||
|
if (changes)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<0x0C; i++)
|
||||||
|
{
|
||||||
|
uint16_t mask = (0x0001 << i);
|
||||||
|
|
||||||
|
if (((mask & changes) > 0) && joyEvents)
|
||||||
|
if ((buttons & mask) > 0)
|
||||||
|
joyEvents->OnButtonDn(i+1);
|
||||||
|
else
|
||||||
|
joyEvents->OnButtonUp(i+1);
|
||||||
|
}
|
||||||
|
oldButtons = buttons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
|
||||||
|
{
|
||||||
|
Serial.print("X: ");
|
||||||
|
PrintHex<uint8_t>(evt->X);
|
||||||
|
Serial.print("\tY: ");
|
||||||
|
PrintHex<uint8_t>(evt->Y);
|
||||||
|
Serial.print("\tZ: ");
|
||||||
|
PrintHex<uint8_t>(evt->Z1);
|
||||||
|
Serial.print("\tZ: ");
|
||||||
|
PrintHex<uint8_t>(evt->Z2);
|
||||||
|
Serial.print("\tRz: ");
|
||||||
|
PrintHex<uint8_t>(evt->Rz);
|
||||||
|
Serial.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickEvents::OnHatSwitch(uint8_t hat)
|
||||||
|
{
|
||||||
|
Serial.print("Hat Switch: ");
|
||||||
|
PrintHex<uint8_t>(hat);
|
||||||
|
Serial.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickEvents::OnButtonUp(uint8_t but_id)
|
||||||
|
{
|
||||||
|
Serial.print("Up: ");
|
||||||
|
Serial.println(but_id, DEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickEvents::OnButtonDn(uint8_t but_id)
|
||||||
|
{
|
||||||
|
Serial.print("Dn: ");
|
||||||
|
Serial.println(but_id, DEC);
|
||||||
|
}
|
54
examples/HID/USBHIDJoystick/hidjoystickrptparser.h
Normal file
54
examples/HID/USBHIDJoystick/hidjoystickrptparser.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#if !defined(__HIDJOYSTICKRPTPARSER_H__)
|
||||||
|
#define __HIDJOYSTICKRPTPARSER_H__
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include "avrpins.h"
|
||||||
|
#include "max3421e.h"
|
||||||
|
#include "usbhost.h"
|
||||||
|
#include "usb_ch9.h"
|
||||||
|
#include "Usb.h"
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >=100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "printhex.h"
|
||||||
|
#include "hexdump.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "confdescparser.h"
|
||||||
|
#include "hid.h"
|
||||||
|
|
||||||
|
struct GamePadEventData
|
||||||
|
{
|
||||||
|
uint8_t X, Y, Z1, Z2, Rz;
|
||||||
|
};
|
||||||
|
|
||||||
|
class JoystickEvents
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void OnGamePadChanged(const GamePadEventData *evt);
|
||||||
|
virtual void OnHatSwitch(uint8_t hat);
|
||||||
|
virtual void OnButtonUp(uint8_t but_id);
|
||||||
|
virtual void OnButtonDn(uint8_t but_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RPT_GEMEPAD_LEN 5
|
||||||
|
|
||||||
|
class JoystickReportParser : public HIDReportParser
|
||||||
|
{
|
||||||
|
JoystickEvents *joyEvents;
|
||||||
|
|
||||||
|
uint8_t oldPad[RPT_GEMEPAD_LEN];
|
||||||
|
uint8_t oldHat;
|
||||||
|
uint16_t oldButtons;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JoystickReportParser(JoystickEvents *evt);
|
||||||
|
|
||||||
|
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __HIDJOYSTICKRPTPARSER_H__
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
#include <avrpins.h>
|
#include <avrpins.h>
|
||||||
|
@ -18,9 +19,47 @@
|
||||||
|
|
||||||
#include "pgmstrings.h"
|
#include "pgmstrings.h"
|
||||||
|
|
||||||
|
class HIDUniversal2 : public HIDUniversal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HIDUniversal2(USB *usb) : HIDUniversal(usb) {};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual uint8_t OnInitSuccessful();
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t HIDUniversal2::OnInitSuccessful()
|
||||||
|
{
|
||||||
|
uint8_t rcode;
|
||||||
|
|
||||||
|
HexDumper<USBReadParser, uint16_t, uint16_t> Hex;
|
||||||
|
ReportDescParser Rpt;
|
||||||
|
|
||||||
|
if (rcode = GetReportDescr(0, &Hex))
|
||||||
|
goto FailGetReportDescr1;
|
||||||
|
|
||||||
|
if (rcode = GetReportDescr(0, &Rpt))
|
||||||
|
goto FailGetReportDescr2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
FailGetReportDescr1:
|
||||||
|
USBTRACE("GetReportDescr1:");
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
FailGetReportDescr2:
|
||||||
|
USBTRACE("GetReportDescr2:");
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
Fail:
|
||||||
|
Serial.println(rcode, HEX);
|
||||||
|
Release();
|
||||||
|
return rcode;
|
||||||
|
}
|
||||||
|
|
||||||
USB Usb;
|
USB Usb;
|
||||||
USBHub Hub(&Usb);
|
USBHub Hub(&Usb);
|
||||||
HIDUniversal Hid(&Usb);
|
HIDUniversal2 Hid(&Usb);
|
||||||
UniversalReportParser Uni;
|
UniversalReportParser Uni;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
|
|
|
@ -260,7 +260,7 @@ void print_hex(int v, int num_places)
|
||||||
void press_any_key()
|
void press_any_key()
|
||||||
{
|
{
|
||||||
Notify(PSTR("\r\nPress any key to continue..."));
|
Notify(PSTR("\r\nPress any key to continue..."));
|
||||||
while( Serial.available() == 0 ); //wait for input
|
while( Serial.available() <= 0 ); //wait for input
|
||||||
Serial.read(); //empty input buffer
|
Serial.read(); //empty input buffer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
16
hid.h
16
hid.h
|
@ -1,3 +1,19 @@
|
||||||
|
/* 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__
|
||||||
|
|
||||||
|
|
|
@ -1555,11 +1555,8 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t size = ((**pp) & DATA_SIZE_MASK);
|
uint8_t size = ((**pp) & DATA_SIZE_MASK);
|
||||||
|
|
||||||
itemPrefix = (**pp);
|
itemPrefix = (**pp);
|
||||||
itemSize = 1 + ((size == DATA_SIZE_4) ? 4 : size);
|
itemSize = 1 + ((size == DATA_SIZE_4) ? 4 : size);
|
||||||
|
|
||||||
//PrintItemTitle(itemPrefix);
|
|
||||||
}
|
}
|
||||||
(*pp) ++;
|
(*pp) ++;
|
||||||
(*pcntdn) --;
|
(*pcntdn) --;
|
||||||
|
@ -1572,8 +1569,6 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn)
|
||||||
if (!pcntdn)
|
if (!pcntdn)
|
||||||
return enErrorIncomplete;
|
return enErrorIncomplete;
|
||||||
case 1:
|
case 1:
|
||||||
//USBTRACE2("\r\niSz:",itemSize);
|
|
||||||
|
|
||||||
theBuffer.valueSize = itemSize;
|
theBuffer.valueSize = itemSize;
|
||||||
valParser.Initialize(&theBuffer);
|
valParser.Initialize(&theBuffer);
|
||||||
itemParseState = 2;
|
itemParseState = 2;
|
||||||
|
@ -1596,11 +1591,9 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn)
|
||||||
break;
|
break;
|
||||||
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE):
|
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE):
|
||||||
rptSize = data;
|
rptSize = data;
|
||||||
//PrintByteValue(data);
|
|
||||||
break;
|
break;
|
||||||
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT):
|
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT):
|
||||||
rptCount = data;
|
rptCount = data;
|
||||||
//PrintByteValue(data);
|
|
||||||
break;
|
break;
|
||||||
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):
|
case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):
|
||||||
rptId = data;
|
rptId = data;
|
||||||
|
@ -1613,8 +1606,6 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn)
|
||||||
break;
|
break;
|
||||||
case (TYPE_GLOBAL | TAG_GLOBAL_USAGEPAGE):
|
case (TYPE_GLOBAL | TAG_GLOBAL_USAGEPAGE):
|
||||||
SetUsagePage(data);
|
SetUsagePage(data);
|
||||||
//PrintUsagePage(data);
|
|
||||||
//PrintByteValue(data);
|
|
||||||
break;
|
break;
|
||||||
case (TYPE_MAIN | TAG_MAIN_OUTPUT):
|
case (TYPE_MAIN | TAG_MAIN_OUTPUT):
|
||||||
case (TYPE_MAIN | TAG_MAIN_FEATURE):
|
case (TYPE_MAIN | TAG_MAIN_FEATURE):
|
||||||
|
@ -1628,7 +1619,6 @@ 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;
|
||||||
|
@ -1648,58 +1638,15 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
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:");
|
|
||||||
//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)
|
if (bit_offset)
|
||||||
*p >>= bit_offset;
|
*p >>= bit_offset;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
// 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 each field in field array defined by rptCount
|
||||||
for (uint8_t field=0; field<rptCount; field++, usage++)
|
for (uint8_t field=0; field<rptCount; field++, usage++)
|
||||||
{
|
{
|
||||||
|
@ -1711,7 +1658,6 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
} result;
|
} result;
|
||||||
|
|
||||||
result.dwResult = 0;
|
result.dwResult = 0;
|
||||||
|
|
||||||
uint8_t mask = 0;
|
uint8_t mask = 0;
|
||||||
|
|
||||||
if (print_usemin_usemax)
|
if (print_usemin_usemax)
|
||||||
|
@ -1726,28 +1672,13 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
bits_left -= bits_to_copy)
|
bits_left -= bits_to_copy)
|
||||||
{
|
{
|
||||||
bits_to_copy = (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)
|
|
||||||
//{
|
|
||||||
// result.dwResult = (uint32_t)*p;
|
|
||||||
// bits_of_byte = 8;
|
|
||||||
// p ++;
|
|
||||||
// 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:");
|
|
||||||
//PrintHex<uint8_t>(8 - bits_of_byte);
|
|
||||||
|
|
||||||
mask = 0;
|
mask = 0;
|
||||||
|
|
||||||
for (uint8_t j=bits_to_copy; j; j--)
|
for (uint8_t j=bits_to_copy; j; j--)
|
||||||
|
@ -1756,136 +1687,21 @@ void ReportDescParser2::OnInputItem(uint8_t itm)
|
||||||
mask |= 1;
|
mask |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Serial.print(" msk:");
|
|
||||||
//PrintHex<uint8_t>(mask);
|
|
||||||
|
|
||||||
result.bResult[0] = (result.bResult[0] | (val & mask));
|
result.bResult[0] = (result.bResult[0] | (val & mask));
|
||||||
|
|
||||||
//Serial.print(" res:");
|
|
||||||
//Serial.print(": ");
|
|
||||||
//PrintHex<uint32_t>(result.dwResult);
|
|
||||||
|
|
||||||
//Serial.print(" b2c:");
|
|
||||||
//PrintHex<uint8_t>(bits_to_copy);
|
|
||||||
|
|
||||||
bits_of_byte -= bits_to_copy;
|
bits_of_byte -= bits_to_copy;
|
||||||
|
|
||||||
//Serial.print(" bob:");
|
|
||||||
//PrintHex<uint8_t>(bits_of_byte);
|
|
||||||
|
|
||||||
if (bits_of_byte < 1)
|
if (bits_of_byte < 1)
|
||||||
{
|
{
|
||||||
bits_of_byte = 8;
|
bits_of_byte = 8;
|
||||||
p ++;
|
p ++;
|
||||||
}
|
}
|
||||||
//Serial.println("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintByteValue(result.dwResult);
|
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);
|
||||||
|
|
|
@ -34,11 +34,8 @@ e-mail : support@circuitsathome.com
|
||||||
#include "printhex.h"
|
#include "printhex.h"
|
||||||
#include "hexdump.h"
|
#include "hexdump.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
||||||
#include "confdescparser.h"
|
#include "confdescparser.h"
|
||||||
//#include "hidusagestr.h"
|
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
//#include "..\ptp\simplefifo.h"
|
|
||||||
|
|
||||||
class ReportDescParserBase : public USBReadParser
|
class ReportDescParserBase : public USBReadParser
|
||||||
{
|
{
|
||||||
|
|
|
@ -232,16 +232,8 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||||
|
|
||||||
USBTRACE("HU configured\r\n");
|
USBTRACE("HU configured\r\n");
|
||||||
|
|
||||||
{
|
OnInitSuccessful();
|
||||||
HexDumper<USBReadParser, uint16_t, uint16_t> Hex;
|
|
||||||
ReportDescParser Rpt;
|
|
||||||
|
|
||||||
if (rcode = GetReportDescr(0, &Hex))
|
|
||||||
goto FailGetReportDescr;
|
|
||||||
|
|
||||||
if (rcode = GetReportDescr(0, &Rpt))
|
|
||||||
goto FailGetReportDescr;
|
|
||||||
}
|
|
||||||
bPollEnable = true;
|
bPollEnable = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define __HIDUNIVERSAL_H__
|
#define __HIDUNIVERSAL_H__
|
||||||
|
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
#include "hidescriptorparser.h"
|
//#include "hidescriptorparser.h"
|
||||||
|
|
||||||
class HIDUniversal : public HID
|
class HIDUniversal : public HID
|
||||||
{
|
{
|
||||||
|
@ -54,6 +54,7 @@ protected:
|
||||||
|
|
||||||
// HID implementation
|
// HID implementation
|
||||||
virtual HIDReportParser* GetReportParser(uint8_t id);
|
virtual HIDReportParser* GetReportParser(uint8_t id);
|
||||||
|
virtual uint8_t OnInitSuccessful() { return 0; };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HIDUniversal(USB *p);
|
HIDUniversal(USB *p);
|
||||||
|
|
Loading…
Reference in a new issue