Skip to content

Commit e0dec90

Browse files
committed
Initial commit
1 parent c8a862a commit e0dec90

File tree

4 files changed

+181
-56
lines changed

4 files changed

+181
-56
lines changed

src/HID/HID.cpp

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,44 @@ void HID_::AppendDescriptor(HIDSubDescriptor *node)
8787
descriptorSize += node->length;
8888
}
8989

90+
int HID_::SetFeature(uint8_t id, const void* data, int len)
91+
{
92+
if(!rootReport) {
93+
static HIDReport report(id, data, len);
94+
rootReport = &report;
95+
} else {
96+
HIDReport* current;
97+
int i=0;
98+
for ( current = rootReport; current; current = current->next, i++) {
99+
if(current->id == id) {
100+
return i;
101+
}
102+
// check if we are on the last report
103+
if(i+1 == reportCount)
104+
break;
105+
}
106+
static HIDReport report(id, data, len);
107+
current->next = &report;
108+
}
109+
110+
reportCount++;
111+
return reportCount;
112+
}
113+
114+
bool HID_::LockFeature(uint8_t id, bool lock) {
115+
if(rootReport) {
116+
HIDReport* current;
117+
for(current = rootReport;current; current=current->next) {
118+
if(current->id == id) {
119+
current->lock = lock;
120+
return true;
121+
}
122+
}
123+
}
124+
return false;
125+
}
126+
127+
90128
int HID_::SendReport(uint8_t id, const void* data, int len)
91129
{
92130
auto ret = USB_Send(HID_TX, &id, 1);
@@ -97,18 +135,34 @@ int HID_::SendReport(uint8_t id, const void* data, int len)
97135
}
98136

99137
bool HID_::setup(USBSetup& setup)
100-
{
138+
{
101139
if (pluggedInterface != setup.wIndex) {
102140
return false;
103141
}
104142

105143
uint8_t request = setup.bRequest;
106144
uint8_t requestType = setup.bmRequestType;
107-
145+
108146
if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
109-
{
147+
{
110148
if (request == HID_GET_REPORT) {
111-
// TODO: HID_GetReport();
149+
150+
if(setup.wValueH == HID_REPORT_TYPE_FEATURE)
151+
{
152+
153+
HIDReport* current;
154+
for(current=rootReport; current; current=current->next) {
155+
156+
if(current->id == setup.wValueL) {
157+
if(USB_SendControl(0, &(current->id), 1)<0 ||
158+
USB_SendControl(0, current->data, current->length)<0)
159+
return false;
160+
161+
break;
162+
}
163+
}
164+
165+
}
112166
return true;
113167
}
114168
if (request == HID_GET_PROTOCOL) {
@@ -121,7 +175,7 @@ bool HID_::setup(USBSetup& setup)
121175
}
122176

123177
if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
124-
{
178+
{
125179
if (request == HID_SET_PROTOCOL) {
126180
// The USB Host tells us if we are in boot or report mode.
127181
// This only works with a real boot compatible device.
@@ -133,7 +187,7 @@ bool HID_::setup(USBSetup& setup)
133187
return true;
134188
}
135189
if (request == HID_SET_REPORT)
136-
{
190+
{
137191
//uint8_t reportID = setup.wValueL;
138192
//uint16_t length = setup.wLength;
139193
//uint8_t data[length];

src/HID/HID.h

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
#include <stdint.h>
2323
#include <Arduino.h>
24-
#include "PluggableUSB.h"
24+
#include <HardwareSerial.h>
25+
#include <PluggableUSB.h>
2526

2627
#if defined(USBCON)
2728

@@ -88,10 +89,21 @@ typedef struct
8889
EndpointDescriptor out; //added
8990
} HIDDescriptor;
9091

92+
class HIDReport {
93+
public:
94+
HIDReport *next = NULL;
95+
HIDReport(uint8_t i, const void *d, uint8_t l) : id(i), data(d), length(l) {}
96+
97+
uint8_t id;
98+
const void* data;
99+
uint16_t length;
100+
bool lock;
101+
};
102+
91103
class HIDSubDescriptor {
92104
public:
93105
HIDSubDescriptor *next = NULL;
94-
HIDSubDescriptor(const void *d, const uint16_t l) : data(d), length(l) { }
106+
HIDSubDescriptor(const void *d, uint16_t l) : data(d), length(l) { }
95107

96108
const void* data;
97109
const uint16_t length;
@@ -100,26 +112,40 @@ class HIDSubDescriptor {
100112
class HID_ : public PluggableUSBModule
101113
{
102114
public:
103-
HID_(void);
104-
int begin(void);
105-
int SendReport(uint8_t id, const void* data, int len);
106-
void AppendDescriptor(HIDSubDescriptor* node);
107-
115+
HID_(void);
116+
int begin(void);
117+
int SendReport(uint8_t id, const void* data, int len);
118+
int SetFeature(uint8_t id, const void* data, int len);
119+
bool LockFeature(uint8_t id, bool lock);
120+
121+
void AppendDescriptor(HIDSubDescriptor* node);
122+
123+
void setSerial(Serial_& serial) {
124+
dbg = &serial;
125+
}
126+
108127
protected:
109-
// Implementation of the PluggableUSBModule
110-
int getInterface(uint8_t* interfaceCount);
111-
int getDescriptor(USBSetup& setup);
112-
bool setup(USBSetup& setup);
113-
uint8_t getShortName(char* name);
114-
128+
// Implementation of the PluggableUSBModule
129+
int getInterface(uint8_t* interfaceCount);
130+
int getDescriptor(USBSetup& setup);
131+
bool setup(USBSetup& setup);
132+
uint8_t getShortName(char* name);
133+
115134
private:
116-
uint8_t epType[2];
117-
118-
HIDSubDescriptor* rootNode;
119-
uint16_t descriptorSize;
120-
121-
uint8_t protocol;
122-
uint8_t idle;
135+
uint8_t epType[2];
136+
137+
HIDSubDescriptor* rootNode;
138+
uint16_t descriptorSize;
139+
140+
uint8_t protocol;
141+
uint8_t idle;
142+
143+
// Buffer pointers to hold the feature data
144+
HIDReport* rootReport;
145+
uint16_t reportCount;
146+
147+
Serial_ *dbg;
148+
123149
};
124150

125151
// Replacement for global singleton.

src/HIDPowerDevice.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
6363
0x81,0x23, // INPUT (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Bitfield)
6464
0x09,0x66, // USAGE (RemainingCapacity)
6565
0xB1,0xA3, // FEATURE (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Volatile, Bitfield)
66+
0x85,HID_PD_RELSTATEOFCHARGE, // REPORT_ID (25)
67+
0x09,0x64, // USAGE (RelativeStateOfCharge)
68+
0x81,0x23, // INPUT (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Bitfield)
69+
0x09,0x64, // USAGE (RelativeStateOfCharge)
70+
0xB1,0xA3, // FEATURE (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Volatile, Bitfield)
71+
0x85,HID_PD_ABSSTATEOFCHARGE, // REPORT_ID (25)
72+
0x09,0x65, // USAGE (RelativeStateOfCharge)
73+
0x81,0x23, // INPUT (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Bitfield)
74+
0x09,0x65, // USAGE (RelativeStateOfCharge)
75+
0xB1,0xA3, // FEATURE (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Volatile, Bitfield)
6676
0x85,HID_PD_CPCTYGRANULARITY1,// REPORT_ID (16)
6777
0x09,0x8D, // USAGE (CapacityGranularity1)
6878
0xB1,0x22, // FEATURE (Data, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Nonvolatile, Bitfield)
@@ -85,6 +95,9 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
8595
0x85,HID_PD_REMNCAPACITYLIMIT,// REPORT_ID (17)
8696
0x09,0x29, // USAGE (RemainingCapacityLimit)
8797
0xB1,0xA2, // FEATURE (Data, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Volatile, Bitfield)
98+
0x85,HID_PD_AVERAGECURRENT, // REPORT_ID (27)
99+
0x09,0x62, // USAGE (AverageCurrent)
100+
0xB1,0xA2, // FEATURE (Data, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Volatile, Bitfield)
88101
0x85,HID_PD_MANUFACTUREDATE, // REPORT_ID (9)
89102
0x09,0x85, // USAGE (ManufacturerDate)
90103
0x75,0x10, // REPORT_SIZE (16)
@@ -93,11 +106,22 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
93106
0x85,HID_PD_RUNTIMETOEMPTY, // REPORT_ID (13)
94107
0x09,0x68, // USAGE (RunTimeToEmpty)
95108
0x27,0xFF,0xFF,0x00,0x00, // LOGICAL_MAXIMUM (65534)
96-
0x66,0x01,0x10, // UNIT (??)
109+
0x66,0x01,0x10, // UNIT (Seconds)
97110
0x55,0x00, // UNIT_EXPONENT (0)
98111
0x81,0xA3, // INPUT (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Bitfield)
99112
0x09,0x68, // USAGE (RunTimeToEmpty)
100113
0xB1,0xA3, // FEATURE (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Volatile, Bitfield)
114+
0x85,HID_PD_AVERAGETIME2FULL, // REPORT_ID (26)
115+
0x09,0x6A, // USAGE (AverageTimeToFull)
116+
0x81,0xA3, // INPUT (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Bitfield)
117+
0x09,0x6A, // USAGE (AverageTimeToFull)
118+
0xB1,0xA3, // FEATURE (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Volatile, Bitfield)
119+
0x05,0x84, // USAGE_PAGE (Power Device)
120+
0x85,HID_PD_AVERAGETIME2EMPTY,// REPORT_ID (28)
121+
0x09,0x69, // USAGE (AverageTimeToEmpty)
122+
0x81,0xA3, // INPUT (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Bitfield)
123+
0x09,0x69, // USAGE (AverageTimeToEmpty)
124+
0xB1,0xA3, // FEATURE (Constant, Variable, Absolute, No Wrap, Linear, No Preferred, No Null Position, Volatile, Bitfield)
101125
0x05,0x84, // USAGE_PAGE (Power Device)
102126
0x85,HID_PD_DELAYBE4SHUTDOWN, // REPORT_ID (18)
103127
0x09,0x57, // USAGE (DelayBeforeShutdown)
@@ -234,33 +258,38 @@ HIDPowerDevice_::HIDPowerDevice_(void)
234258

235259
void HIDPowerDevice_::begin(void)
236260
{
261+
HID().begin();
237262
}
238263

239-
void HIDPowerDevice_::end(void)
264+
void HIDPowerDevice_::setSerial(Serial_& serial)
240265
{
266+
HID().setSerial(serial);
241267
}
242268

243-
void HIDPowerDevice_::sendDate(uint8_t id, uint16_t year, uint8_t month, uint8_t day)
269+
270+
void HIDPowerDevice_::end(void)
244271
{
245-
uint16_t bval = (year - 1980)*512 + month * 32 + day;
246-
HID().SendReport(id, &bval, sizeof(bval));
247272
}
248273

249-
void HIDPowerDevice_::sendInt32(uint8_t id, uint32_t bval)
274+
int HIDPowerDevice_::sendDate(uint8_t id, uint16_t year, uint8_t month, uint8_t day)
250275
{
251-
HID().SendReport(id, &bval, sizeof(bval));
276+
uint16_t bval = (year - 1980)*512 + month * 32 + day;
277+
return HID().SendReport(id, &bval, sizeof(bval));
252278
}
253279

254-
void HIDPowerDevice_::sendInt16(uint8_t id, uint16_t bval)
280+
int HIDPowerDevice_::sendInt16(uint8_t id, uint16_t bval)
255281
{
256-
HID().SendReport(id, &bval, sizeof(bval));
282+
return HID().SendReport(id, &bval, sizeof(bval));
257283
}
258284

259-
void HIDPowerDevice_::sendByte(uint8_t id, uint8_t bval)
285+
int HIDPowerDevice_::sendByte(uint8_t id, uint8_t bval)
260286
{
261-
HID().SendReport(id, &bval, sizeof(bval));
287+
return HID().SendReport(id, &bval, sizeof(bval));
262288
}
263289

290+
int HIDPowerDevice_::setFeature(uint8_t id, const void *data, int len) {
291+
return HID().SetFeature(id, data, len);
292+
}
264293

265294
HIDPowerDevice_ PowerDevice;
266295

src/HIDPowerDevice.h

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,45 +39,61 @@
3939
//================================================================================
4040
//================================================================================
4141

42-
#define HID_PD_IPRODUCT 0x01
43-
#define HID_PD_SERIAL 0x02
44-
#define HID_PD_MANUFACTURER 0x03
42+
#define HID_PD_IPRODUCT 0x01 // FEATURE ONLY
43+
#define HID_PD_SERIAL 0x02 // FEATURE ONLY
44+
#define HID_PD_MANUFACTURER 0x03 // FEATURE ONLY
4545

46-
#define HID_PD_RECHARGEABLE 0x06
47-
#define HID_PD_PRESENTSTATUS 0x07
46+
#define HID_PD_RECHARGEABLE 0x06 // FEATURE ONLY
47+
#define HID_PD_PRESENTSTATUS 0x07 // INPUT OR FEATURE(required by Windows)
4848
#define HID_PD_REMAINTIMELIMIT 0x08
4949
#define HID_PD_MANUFACTUREDATE 0x09
50-
#define HID_PD_CONFIGVOLTAGE 0x0A
51-
#define HID_PD_VOLTAGE 0x0B
52-
#define HID_PD_REMAININGCAPACITY 0x0C
53-
#define HID_PD_RUNTIMETOEMPTY 0x0D
54-
#define HID_PD_FULLCHRGECAPACITY 0x0E
50+
#define HID_PD_CONFIGVOLTAGE 0x0A // 10 FEATURE ONLY
51+
#define HID_PD_VOLTAGE 0x0B // 11 INPUT (NA) OR FEATURE(implemented)
52+
#define HID_PD_REMAININGCAPACITY 0x0C // 12 INPUT OR FEATURE(required by Windows)
53+
#define HID_PD_RUNTIMETOEMPTY 0x0D
54+
#define HID_PD_FULLCHRGECAPACITY 0x0E // 14 INPUT OR FEATURE
5555
#define HID_PD_WARNCAPACITYLIMIT 0x0F
5656
#define HID_PD_CPCTYGRANULARITY1 0x10
5757
#define HID_PD_REMNCAPACITYLIMIT 0x11
58-
#define HID_PD_DELAYBE4SHUTDOWN 0x12
58+
#define HID_PD_DELAYBE4SHUTDOWN 0x12 // 18 FEATURE ONLY
5959
#define HID_PD_DELAYBE4REBOOT 0x13
60-
#define HID_PD_AUDIBLEALARMCTRL 0x14
61-
#define HID_PD_CURRENT 0x15
60+
#define HID_PD_AUDIBLEALARMCTRL 0x14 // 20 FEATURE ONLY
61+
#define HID_PD_CURRENT 0x15 // 21 FEATURE ONLY
6262
#define HID_PD_CAPACITYMODE 0x16
6363
#define HID_PD_DESIGNCAPACITY 0x17
6464
#define HID_PD_CPCTYGRANULARITY2 0x18
65+
#define HID_PD_RELSTATEOFCHARGE 0x19 // INPUT OR FEATURE
66+
#define HID_PD_AVERAGETIME2FULL 0x1A
67+
#define HID_PD_AVERAGECURRENT 0x1B
68+
#define HID_PD_AVERAGETIME2EMPTY 0x1C
69+
#define HID_PD_ABSSTATEOFCHARGE 0x1E // INPUT OR FEATURE
70+
71+
72+
#define PRESENTSTATUS_CHARGING 0x00
73+
#define PRESENTSTATUS_DISCHARGING 0x01
74+
#define PRESENTSTATUS_ACPRESENT 0x02
75+
#define PRESENTSTATUS_BATTPRESENT 0x03
76+
77+
6578

6679

6780
class HIDPowerDevice_
6881
{
6982
private:
70-
// KeyReport _keyReport;
71-
//void sendReport(KeyReport* keys);
83+
7284
public:
7385
HIDPowerDevice_(void);
7486
void begin(void);
87+
void setSerial(Serial_& serial);
88+
7589
void end(void);
7690

77-
void sendDate(uint8_t id, uint16_t year, uint8_t month, uint8_t day);
78-
void sendByte(uint8_t id, uint8_t bval);
79-
void sendInt16(uint8_t id, uint16_t bval);
80-
void sendInt32(uint8_t id, uint32_t bval);
91+
int sendDate(uint8_t id, uint16_t year, uint8_t month, uint8_t day);
92+
int sendByte(uint8_t id, uint8_t bval);
93+
int sendInt16(uint8_t id, uint16_t bval);
94+
95+
int setFeature(uint8_t id, const void* data, int len);
96+
8197
};
8298

8399
extern HIDPowerDevice_ PowerDevice;

0 commit comments

Comments
 (0)