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.vid.0=0x2341
leonardoExtended.pid.0=0x0036
leonardoExtended.vid.1=0x2341
leonardoExtended.pid.1=0x8036
leonardoExtended.upload.tool=arduino:avrdude
leonardoExtended.upload.protocol=avr109
leonardoExtended.upload.maximum_size=28672

View file

@ -33,135 +33,134 @@ HIDBridge_::HIDBridge_(void){
// 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)
{
if (!debug)
return;
debug->println("Softserial");
debug->println(error);
}
void HIDBridge_::readSerial(void)
{
static NHP_Read_Data_t n = { 0 };
uint8_t error = 0x00;
// read as long as the Serial is available
// but do not block forever
rx_buffer_index_t i = 0; //TODO availabel -> read -1
while (Serial.available()) {
// read in new Serial byte and process with NHP protocol
uint8_t b = Serial.read();
bool newInput = NHPread(b, &n);
for (rx_buffer_index_t i = 0; i < SERIAL_RX_BUFFER_SIZE; i++){
// read in new Serial byte
int b = Serial.read();
if (b < 0)
break;
// process with NHP protocol
bool newInput = NHPread(b, &nhp_read);
// proceed new valid NHP input
if (newInput) {
if (n.mode == NHP_ADDRESS) {
switch (n.address) {
if (nhp_read.mode == NHP_ADDRESS) {
switch (nhp_read.address) {
// received a control address command
case HIDBRIDGE_ADDRESS_CONTROL:
// acknowledge/request
if (n.data == HIDBRIDGE_CONTROL_ISREADY)
if (nhp_read.data == HIDBRIDGE_CONTROL_ISREADY)
isReady = true;
// pause
else if (n.data == HIDBRIDGE_CONTROL_NOTREADY)
else if (nhp_read.data == HIDBRIDGE_CONTROL_NOTREADY)
isReady = false;
// not
else
err(HID_BRIDGE_ERR_CONTROL);
err(HIDBRIDGE_ERR_CONTROL);
break;
// received HID out report TODO
default:
err(HID_BRIDGE_ERR_ADDRESS);
err(HIDBRIDGE_ERR_ADDRESS);
break;
}
}
// received HID out report TODO
else if (n.mode == NHP_COMMAND) {
error = 4;
else if (nhp_read.mode == NHP_COMMAND) {
err(HIDBRIDGE_ERR_COMMAND);
}
}
// NHP reading error
else if (n.errorLevel) {
error = 2;
else if (nhp_read.errorLevel) {
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)
{
// try to wait for a new request/acknowledge
uint32_t currentMillis = millis();
do{
// check for new state information
// maybe the host sended a pause signal
readSerial();
// check for timeout //TODO move 1 up?
// check for timeout
if ((millis() - currentMillis) > HIDBRIDGE_TX_TIMEOUT) {
err(1);
return false;
err(HIDBRIDGE_ERR_TIMEOUT);
break;
}
}
// try to wait for a new request/acknowledge
while (!isReady)
} while (!isReady); //TODO andn no error in readSerial?
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 HID_SendReport(uint8_t reportID, const void* data, int len)
void HIDBridge_::SendReport(uint8_t reportID, const void* data, int len)
{
// check the latest request/acknowledge, pause, error
if (!HIDBridge.waitForReady()){
HIDBridge.err(0);
// check if stream pointer is set
if (!HIDStream){
err(HIDBRIDGE_ERR_NO_SPTR);
return;
}
// check the latest request/acknowledge,a pause, error
if (!waitForReady()){
err(HIDBRIDGE_ERR_NOT_RDY);
return;
}
// 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
// the rest (if any, e.g. with 2 byte) is filled with random bytes
NHP_Write_Data_t n;
for (int i = 0; i < len; i += 4) {
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
Serial.write(NHPwriteCommand(0));
HIDStream->write(NHPwriteCommand(0));
// 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
#include <Arduino.h>
#include <SoftwareSerial.h>
#include "NHP.h"
//================================================================================
@ -38,16 +39,20 @@ THE SOFTWARE.
#define HIDBRIDGE_TX_TIMEOUT 1000
#define HIDBRIDGE_BAUD 2000000
#define HIDBRIDGE_ADDRESS_CONTROL 0
#define HIDBRIDGE_CONTROL_ISREADY 0
#define HIDBRIDGE_CONTROL_NOTREADY 1
#define HID_BRIDGE_ERR_TIMEOUT 0
#define HID_BRIDGE_ERR_NHP_ERR 1
#define HID_BRIDGE_ERR_COMMAND 2
#define HID_BRIDGE_ERR_ADDRESS 3
#define HID_BRIDGE_ERR_CONTROL 4
#define HIDBRIDGE_ERR_TIMEOUT 0
#define HIDBRIDGE_ERR_NHP_ERR 1
#define HIDBRIDGE_ERR_COMMAND 2
#define HIDBRIDGE_ERR_ADDRESS 3
#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_{
public:
HIDBridge_(void);
bool begin(void);
inline void debugStream(Stream* s){
debug = s;
}
bool begin(Stream &s);
bool begin(Stream* s);
void readSerial(void);
bool waitForReady(void);
bool isReady;
void task(void);
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;