HID Bridge update
This commit is contained in:
parent
4cfa0c6964
commit
619bdf633b
3 changed files with 84 additions and 72 deletions
|
|
@ -5,10 +5,6 @@ menu.usbcore=USB Core
|
||||||
##############################################################
|
##############################################################
|
||||||
|
|
||||||
leonardoExtended.name=Arduino Leonardo HID-Project
|
leonardoExtended.name=Arduino Leonardo HID-Project
|
||||||
leonardoExtended.vid.0=0x2341
|
|
||||||
leonardoExtended.pid.0=0x0036
|
|
||||||
leonardoExtended.vid.1=0x2341
|
|
||||||
leonardoExtended.pid.1=0x8036
|
|
||||||
leonardoExtended.upload.tool=arduino:avrdude
|
leonardoExtended.upload.tool=arduino:avrdude
|
||||||
leonardoExtended.upload.protocol=avr109
|
leonardoExtended.upload.protocol=avr109
|
||||||
leonardoExtended.upload.maximum_size=28672
|
leonardoExtended.upload.maximum_size=28672
|
||||||
|
|
|
||||||
|
|
@ -33,135 +33,134 @@ HIDBridge_::HIDBridge_(void){
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HIDBridge_::begin(void)
|
bool HIDBridge_::begin(Stream &s)
|
||||||
{
|
{
|
||||||
|
begin((Stream*)&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HIDBridge_::begin(Stream* s)
|
||||||
|
{
|
||||||
|
HIDStream = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void HIDBridge_::err(uint8_t error)
|
void HIDBridge_::err(uint8_t error)
|
||||||
{
|
{
|
||||||
|
if (!debug)
|
||||||
|
return;
|
||||||
|
debug->println("Softserial");
|
||||||
|
debug->println(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HIDBridge_::readSerial(void)
|
void HIDBridge_::readSerial(void)
|
||||||
{
|
{
|
||||||
static NHP_Read_Data_t n = { 0 };
|
|
||||||
uint8_t error = 0x00;
|
|
||||||
|
|
||||||
// read as long as the Serial is available
|
// read as long as the Serial is available
|
||||||
// but do not block forever
|
// but do not block forever
|
||||||
rx_buffer_index_t i = 0; //TODO availabel -> read -1
|
for (rx_buffer_index_t i = 0; i < SERIAL_RX_BUFFER_SIZE; i++){
|
||||||
while (Serial.available()) {
|
// read in new Serial byte
|
||||||
// read in new Serial byte and process with NHP protocol
|
int b = Serial.read();
|
||||||
uint8_t b = Serial.read();
|
if (b < 0)
|
||||||
bool newInput = NHPread(b, &n);
|
break;
|
||||||
|
|
||||||
|
// process with NHP protocol
|
||||||
|
bool newInput = NHPread(b, &nhp_read);
|
||||||
|
|
||||||
// proceed new valid NHP input
|
// proceed new valid NHP input
|
||||||
if (newInput) {
|
if (newInput) {
|
||||||
if (n.mode == NHP_ADDRESS) {
|
if (nhp_read.mode == NHP_ADDRESS) {
|
||||||
switch (n.address) {
|
switch (nhp_read.address) {
|
||||||
// received a control address command
|
// received a control address command
|
||||||
case HIDBRIDGE_ADDRESS_CONTROL:
|
case HIDBRIDGE_ADDRESS_CONTROL:
|
||||||
// acknowledge/request
|
// acknowledge/request
|
||||||
if (n.data == HIDBRIDGE_CONTROL_ISREADY)
|
if (nhp_read.data == HIDBRIDGE_CONTROL_ISREADY)
|
||||||
isReady = true;
|
isReady = true;
|
||||||
|
|
||||||
// pause
|
// pause
|
||||||
else if (n.data == HIDBRIDGE_CONTROL_NOTREADY)
|
else if (nhp_read.data == HIDBRIDGE_CONTROL_NOTREADY)
|
||||||
isReady = false;
|
isReady = false;
|
||||||
|
|
||||||
// not
|
// not
|
||||||
else
|
else
|
||||||
err(HID_BRIDGE_ERR_CONTROL);
|
err(HIDBRIDGE_ERR_CONTROL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
// received HID out report TODO
|
// received HID out report TODO
|
||||||
default:
|
default:
|
||||||
err(HID_BRIDGE_ERR_ADDRESS);
|
err(HIDBRIDGE_ERR_ADDRESS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// received HID out report TODO
|
// received HID out report TODO
|
||||||
else if (n.mode == NHP_COMMAND) {
|
else if (nhp_read.mode == NHP_COMMAND) {
|
||||||
error = 4;
|
err(HIDBRIDGE_ERR_COMMAND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NHP reading error
|
// NHP reading error
|
||||||
else if (n.errorLevel) {
|
else if (nhp_read.errorLevel) {
|
||||||
error = 2;
|
err(HIDBRIDGE_ERR_NHP_ERR);
|
||||||
|
// do not change isReady state because of a possible full buffer
|
||||||
|
// which causes NHP corruption
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not block forever
|
|
||||||
if (++i >= SERIAL_RX_BUFFER_SIZE)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error){
|
|
||||||
err(error);
|
|
||||||
isReady = false; // revert
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool HIDBridge_::waitForReady(void)
|
bool HIDBridge_::waitForReady(void)
|
||||||
{
|
{
|
||||||
|
// try to wait for a new request/acknowledge
|
||||||
uint32_t currentMillis = millis();
|
uint32_t currentMillis = millis();
|
||||||
do{
|
do{
|
||||||
// check for new state information
|
// check for new state information
|
||||||
// maybe the host sended a pause signal
|
// maybe the host sended a pause signal
|
||||||
readSerial();
|
readSerial();
|
||||||
|
|
||||||
// check for timeout //TODO move 1 up?
|
// check for timeout
|
||||||
if ((millis() - currentMillis) > HIDBRIDGE_TX_TIMEOUT) {
|
if ((millis() - currentMillis) > HIDBRIDGE_TX_TIMEOUT) {
|
||||||
err(1);
|
err(HIDBRIDGE_ERR_TIMEOUT);
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (!isReady); //TODO andn no error in readSerial?
|
||||||
// try to wait for a new request/acknowledge
|
|
||||||
while (!isReady)
|
|
||||||
|
|
||||||
return isReady;
|
return isReady;
|
||||||
|
|
||||||
//if (!isReady) { //TODO remove?
|
|
||||||
// // try to wait for a new request/acknowledge
|
|
||||||
// uint32_t currentMillis = millis();
|
|
||||||
// while (!isReady) {
|
|
||||||
// readSerial();
|
|
||||||
// // check for timeout //TODO move 1 up?
|
|
||||||
// if ((millis() - currentMillis) > HIDBRIDGE_TX_TIMEOUT) {
|
|
||||||
// err(1);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// overwrites the HID_SendReport function which is empty/not used on a 328/2560
|
void HIDBridge_::SendReport(uint8_t reportID, const void* data, int len)
|
||||||
void HID_SendReport(uint8_t reportID, const void* data, int len)
|
|
||||||
{
|
{
|
||||||
// check the latest request/acknowledge, pause, error
|
// check if stream pointer is set
|
||||||
if (!HIDBridge.waitForReady()){
|
if (!HIDStream){
|
||||||
HIDBridge.err(0);
|
err(HIDBRIDGE_ERR_NO_SPTR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the latest request/acknowledge,a pause, error
|
||||||
|
if (!waitForReady()){
|
||||||
|
err(HIDBRIDGE_ERR_NOT_RDY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin transfer with reportID as command
|
// begin transfer with reportID as command
|
||||||
Serial.write(NHPwriteCommand(reportID));
|
HIDStream->write(NHPwriteCommand(reportID));
|
||||||
|
|
||||||
// send data in 4 byte packets with the address of the reportID
|
// send data in 4 byte packets with the address of the reportID
|
||||||
// the rest (if any, e.g. with 2 byte) is filled with random bytes
|
// the rest (if any, e.g. with 2 byte) is filled with random bytes
|
||||||
NHP_Write_Data_t n;
|
NHP_Write_Data_t n;
|
||||||
for (int i = 0; i < len; i += 4) {
|
for (int i = 0; i < len; i += 4) {
|
||||||
NHPwriteAddress(reportID, UINT32_AT_OFFSET(data, i), &n);
|
NHPwriteAddress(reportID, UINT32_AT_OFFSET(data, i), &n);
|
||||||
Serial.write(n.writeBuffer, n.writeLength);
|
HIDStream->write(n.writeBuffer, n.writeLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// end transfer with zero command
|
// end transfer with zero command
|
||||||
Serial.write(NHPwriteCommand(0));
|
HIDStream->write(NHPwriteCommand(0));
|
||||||
|
|
||||||
// need a request/acknowledge next time again
|
// need a request/acknowledge next time again
|
||||||
HIDBridge.isReady = false;
|
isReady = false;
|
||||||
|
|
||||||
|
err(42);
|
||||||
|
}
|
||||||
|
|
||||||
|
// overwrites the HID_SendReport function which is empty/not used on a 328/2560
|
||||||
|
void HID_SendReport(uint8_t reportID, const void* data, int len)
|
||||||
|
{
|
||||||
|
HIDBridge.SendReport(reportID, data, len);
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +25,7 @@ THE SOFTWARE.
|
||||||
#define HIDBRIDGE_H
|
#define HIDBRIDGE_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <SoftwareSerial.h>
|
||||||
#include "NHP.h"
|
#include "NHP.h"
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
@ -38,16 +39,20 @@ THE SOFTWARE.
|
||||||
|
|
||||||
#define HIDBRIDGE_TX_TIMEOUT 1000
|
#define HIDBRIDGE_TX_TIMEOUT 1000
|
||||||
|
|
||||||
|
#define HIDBRIDGE_BAUD 2000000
|
||||||
|
|
||||||
#define HIDBRIDGE_ADDRESS_CONTROL 0
|
#define HIDBRIDGE_ADDRESS_CONTROL 0
|
||||||
|
|
||||||
#define HIDBRIDGE_CONTROL_ISREADY 0
|
#define HIDBRIDGE_CONTROL_ISREADY 0
|
||||||
#define HIDBRIDGE_CONTROL_NOTREADY 1
|
#define HIDBRIDGE_CONTROL_NOTREADY 1
|
||||||
|
|
||||||
#define HID_BRIDGE_ERR_TIMEOUT 0
|
#define HIDBRIDGE_ERR_TIMEOUT 0
|
||||||
#define HID_BRIDGE_ERR_NHP_ERR 1
|
#define HIDBRIDGE_ERR_NHP_ERR 1
|
||||||
#define HID_BRIDGE_ERR_COMMAND 2
|
#define HIDBRIDGE_ERR_COMMAND 2
|
||||||
#define HID_BRIDGE_ERR_ADDRESS 3
|
#define HIDBRIDGE_ERR_ADDRESS 3
|
||||||
#define HID_BRIDGE_ERR_CONTROL 4
|
#define HIDBRIDGE_ERR_CONTROL 4
|
||||||
|
#define HIDBRIDGE_ERR_NOT_RDY 5
|
||||||
|
#define HIDBRIDGE_ERR_NO_SPTR 6
|
||||||
|
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
@ -58,15 +63,27 @@ THE SOFTWARE.
|
||||||
class HIDBridge_{
|
class HIDBridge_{
|
||||||
public:
|
public:
|
||||||
HIDBridge_(void);
|
HIDBridge_(void);
|
||||||
|
inline void debugStream(Stream* s){
|
||||||
bool begin(void);
|
debug = s;
|
||||||
|
}
|
||||||
|
bool begin(Stream &s);
|
||||||
|
bool begin(Stream* s);
|
||||||
void readSerial(void);
|
void readSerial(void);
|
||||||
bool waitForReady(void);
|
bool waitForReady(void);
|
||||||
bool isReady;
|
bool isReady;
|
||||||
void task(void);
|
void task(void);
|
||||||
void err(uint8_t error);
|
void err(uint8_t error);
|
||||||
|
|
||||||
inline void write(void){} // TODO
|
// public to access via HID_SendReport
|
||||||
|
void SendReport(uint8_t reportID, const void* data, int len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Stream* debug;
|
||||||
|
Stream* HIDStream; //TODO template?
|
||||||
|
|
||||||
|
NHP_Read_Data_t nhp_read;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HIDBridge_ HIDBridge;
|
extern HIDBridge_ HIDBridge;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue