Upgraded hid interface
This commit is contained in:
@ -1,7 +1,6 @@
|
||||
#include "ergodox.hpp"
|
||||
|
||||
|
||||
|
||||
Ergodox::Ergodox(
|
||||
unsigned short vendor_id,
|
||||
unsigned short product_id,
|
||||
@ -64,6 +63,9 @@ Ergodox::~Ergodox() {
|
||||
Try to open this keyboard's hid device.
|
||||
Throws a runtime error if device is already open,
|
||||
or if we can't find a device with the given params.
|
||||
|
||||
If we successfully open a device, this method sends a
|
||||
CMD_HELLO packet.
|
||||
*/
|
||||
void Ergodox::open() {
|
||||
if (handle != NULL) {
|
||||
@ -94,6 +96,10 @@ void Ergodox::open() {
|
||||
hid_free_enumeration(devs);
|
||||
throw std::runtime_error("Could not open hid device");
|
||||
}
|
||||
|
||||
hid_set_nonblocking(handle, 1);
|
||||
|
||||
write(CMD_HELLO, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -108,14 +114,64 @@ void Ergodox::close() {
|
||||
/*
|
||||
Send data to Ergodox.
|
||||
|
||||
@param cmd Command byte
|
||||
@param data Data to send
|
||||
@param length How many bytes to send
|
||||
@returns Actual number of bytes written, or -1 on error.
|
||||
@returns data_len Data length. Must be shorter than packet_size.
|
||||
*/
|
||||
int Ergodox::write(uint8_t* data, size_t length) const {
|
||||
int Ergodox::write(uint8_t cmd, const uint8_t* data, uint8_t data_len) const {
|
||||
if (handle == NULL) {
|
||||
throw std::runtime_error("Cannot write, device is not open!");
|
||||
}
|
||||
|
||||
return hid_write(handle, data, length);
|
||||
if (data_len > packet_size) {
|
||||
throw std::runtime_error("Data length exceeds packet size");
|
||||
}
|
||||
|
||||
if (data == NULL) {
|
||||
data = {0x00};
|
||||
}
|
||||
|
||||
uint8_t packet[packet_size];
|
||||
packet[0] = 0x00; // Report number. Not seen by keyboard.
|
||||
packet[1] = cmd; // First byte is always command
|
||||
|
||||
// Copy data into rest of packet
|
||||
std::copy(data, data + data_len, packet + 2);
|
||||
|
||||
return hid_write(handle, packet, packet_size + 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Read data from Ergodox into read_buf. If a CMD_SEND_STATE packet is received, process it and return false.
|
||||
|
||||
@returns True if a new command was received, false otherwise.
|
||||
*/
|
||||
bool Ergodox::read() {
|
||||
if (handle == NULL) {
|
||||
throw std::runtime_error("Cannot write, device is not open!");
|
||||
}
|
||||
ssize_t res;
|
||||
res = hid_read(handle, read_buf, packet_size);
|
||||
|
||||
if (res == 0) {
|
||||
return false;
|
||||
} else if (res < 0) {
|
||||
throw std::runtime_error("Read failed.");
|
||||
}
|
||||
|
||||
switch(read_buf[0]) {
|
||||
|
||||
// If keyboard sends a state packet, parse it.
|
||||
case CMD_SEND_STATE:
|
||||
if (animation_mode != read_buf[1]) {
|
||||
wprintf(L"Mode set to %#x\n", read_buf[1]);
|
||||
animation_mode = read_buf[1];
|
||||
}
|
||||
|
||||
// Main code should not parse state packets.
|
||||
return false;
|
||||
}
|
||||
|
||||
return res > 0;
|
||||
}
|
Reference in New Issue
Block a user