HID Bridge update

This commit is contained in:
Nico 2015-02-16 16:07:31 +01:00
parent 4cfa0c6964
commit 619bdf633b
3 changed files with 84 additions and 72 deletions

View file

@ -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

View file

@ -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);
} }

View file

@ -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;