You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
262 lines
6.7 KiB
C++
262 lines
6.7 KiB
C++
#include "GoBLE.h"
|
|
|
|
_GoBLE Goble;
|
|
|
|
/*
|
|
The following constants tell, for each accelerometer
|
|
axis, which values are returned when the axis measures
|
|
zero acceleration.
|
|
*/
|
|
|
|
_GoBLE::_GoBLE() {
|
|
initRecvDataPack();
|
|
|
|
_joystickX = 127;
|
|
_joystickY = 127;
|
|
for (int i = 0; i < MAXBUTTONID; i++) {
|
|
_button[i] = RELEASED;
|
|
}
|
|
|
|
for (int i = 0; i < 20; i++) bleQueue.push(0x00);
|
|
for (int i = 0; i < 20; i++) bleQueue.pop();
|
|
|
|
|
|
}
|
|
|
|
|
|
boolean _GoBLE::available() {
|
|
/*
|
|
function introduction:
|
|
push the new valid data to the data buffer package
|
|
throw away the invalid byte
|
|
parse the data package when the command length is matching the protocol
|
|
*/
|
|
|
|
if (Serial.available()) bleDataReceiver();
|
|
/*
|
|
if (DEBUGDATARAW) {
|
|
Serial.println("GoBLE availalbe -> new data package!");
|
|
for (int i = 0; i < rDataPack.commandLength; i++) {
|
|
Serial.print(bleQueue.pop(), HEX);
|
|
}
|
|
Serial.println();
|
|
}
|
|
|
|
if (DEBUGPARSER) {
|
|
Serial.print("GoBLE availalbe -> bleQueue Counter: ");
|
|
Serial.print(bleQueue.count());
|
|
Serial.println();
|
|
}
|
|
*/
|
|
if (rDataPack.commandFlag && bleQueue.count() == rDataPack.commandLength) {
|
|
|
|
rDataPack.parseState = bleDataPackageParser();
|
|
|
|
if (rDataPack.parseState == PARSESUCCESS) {
|
|
updateJoystickVal();
|
|
updateButtonState();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
int _GoBLE::readJoystickX() {
|
|
return _joystickX;
|
|
}
|
|
int _GoBLE::readJoystickY() {
|
|
return _joystickY;
|
|
}
|
|
|
|
boolean _GoBLE::readSwitchUp() {
|
|
return _button[SWITCH_UP];
|
|
}
|
|
|
|
boolean _GoBLE::readSwitchDown() {
|
|
return _button[SWITCH_DOWN];
|
|
}
|
|
|
|
boolean _GoBLE::readSwitchLeft() {
|
|
return _button[SWITCH_LEFT];
|
|
}
|
|
|
|
boolean _GoBLE::readSwitchRight() {
|
|
return _button[SWITCH_RIGHT];
|
|
}
|
|
|
|
boolean _GoBLE::readSwitchSelect() {
|
|
return _button[SWITCH_SELECT];
|
|
}
|
|
|
|
boolean _GoBLE::readSwitchStart() {
|
|
return _button[SWITCH_START];
|
|
}
|
|
|
|
// Private functions
|
|
|
|
int _GoBLE::bleDataPackageParser() {
|
|
/*
|
|
0x10 - Parse success
|
|
0x11 - Wrong header charactors
|
|
0x12 - Wrong button number
|
|
0x13 - Check Sum Error
|
|
*/
|
|
byte calculateSum = 0;
|
|
|
|
rDataPack.header1 = bleQueue.pop(), calculateSum += rDataPack.header1;
|
|
rDataPack.header2 = bleQueue.pop(), calculateSum += rDataPack.header2;
|
|
|
|
if (rDataPack.header1 != DEFAULTHEADER1) return 0x11;
|
|
if (rDataPack.header2 != DEFAULTHEADER2) return 0x11;
|
|
|
|
rDataPack.address = bleQueue.pop(), calculateSum += rDataPack.address;
|
|
|
|
rDataPack.latestDigitalButtonNumber = rDataPack.digitalButtonNumber;
|
|
rDataPack.digitalButtonNumber = bleQueue.pop(), calculateSum += rDataPack.digitalButtonNumber;
|
|
|
|
int digitalButtonLength = rDataPack.digitalButtonNumber;
|
|
|
|
|
|
if (DEBUGCHECKSUM) {
|
|
Serial.print("Parser -> digitalButtonLength: ");
|
|
Serial.println(digitalButtonLength);
|
|
}
|
|
if (digitalButtonLength > MAXBUTTONNUMBER) return 0x12;
|
|
|
|
rDataPack.joystickPosition = bleQueue.pop(), calculateSum += rDataPack.joystickPosition;
|
|
|
|
// read button data package - dynamic button payload length
|
|
for (int buttonPayloadPointer = 0; buttonPayloadPointer < digitalButtonLength; buttonPayloadPointer++) {
|
|
rDataPack.buttonPayload[buttonPayloadPointer] = bleQueue.pop();
|
|
calculateSum += rDataPack.buttonPayload[buttonPayloadPointer];
|
|
}
|
|
// read 4 byte joystick data package
|
|
for (int i = 0; i < 4; i++) rDataPack.joystickPayload[i] = bleQueue.pop(), calculateSum += rDataPack.joystickPayload[i];
|
|
|
|
rDataPack.checkSum = bleQueue.pop();
|
|
|
|
if (DEBUGCHECKSUM) {
|
|
Serial.print("Parser -> sum calculation: ");
|
|
Serial.println(calculateSum);
|
|
|
|
Serial.print("Parser -> checkSum byte value: ");
|
|
Serial.println(rDataPack.checkSum);
|
|
}
|
|
|
|
// check sum and update the parse state value
|
|
// if the checksum byte is not correct, return 0x12
|
|
|
|
rDataPack.commandFlag = false;
|
|
|
|
if (rDataPack.checkSum == calculateSum) return PARSESUCCESS;
|
|
else return 0x13;
|
|
}
|
|
|
|
void _GoBLE::bleDataReceiver() {
|
|
|
|
byte inputByte = Serial.read();
|
|
|
|
if (DEBUGDATARECEIVER) {
|
|
Serial.print("bleDataReceiver -> new data:");
|
|
Serial.println(inputByte, HEX);
|
|
}
|
|
|
|
// throw the trash data and restore the useful data to the queue buffer
|
|
if (inputByte == DEFAULTHEADER1 || rDataPack.commandFlag == true) {
|
|
bleQueue.push(inputByte);
|
|
rDataPack.commandFlag = true;
|
|
|
|
// auto adjust the command length based on the button command value
|
|
if (bleQueue.count() == PACKBUTTONSIGN) {
|
|
// max button input at one moment should less than 6 buttons
|
|
if (inputByte > 0 && inputByte < MAXBUTTONNUMBER) {
|
|
|
|
// default command length + button number
|
|
rDataPack.commandLength = DEFAULTPACKLENGTH + inputByte;
|
|
if (DEBUGDATARECEIVER) Serial.print("bleDataReceiver -> Command Length:"), Serial.println(rDataPack.commandLength);
|
|
}
|
|
else rDataPack.commandLength = DEFAULTPACKLENGTH;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void _GoBLE::initRecvDataPack() {
|
|
rDataPack.commandFlag = false;
|
|
rDataPack.commandLength = DEFAULTPACKLENGTH;
|
|
rDataPack.parseState = PARSESUCCESS;
|
|
|
|
rDataPack.digitalButtonNumber = 0;
|
|
rDataPack.latestDigitalButtonNumber = 0;
|
|
}
|
|
|
|
void _GoBLE::updateJoystickVal() {
|
|
_joystickX = rDataPack.joystickPayload[0];
|
|
_joystickY = rDataPack.joystickPayload[1];
|
|
}
|
|
|
|
void _GoBLE::updateButtonState() {
|
|
|
|
if (rDataPack.digitalButtonNumber == 0 && rDataPack.latestDigitalButtonNumber != 0) {
|
|
for (int i = 0; i < MAXBUTTONID; i++) {
|
|
if (_button[i] == PRESSED) {
|
|
if (DEBUGUPDATEBUTTON) {
|
|
Serial.print("updateButtonState -> clear Pressed button number: ");
|
|
Serial.println(i);
|
|
}
|
|
_button[i] = RELEASED;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < rDataPack.digitalButtonNumber; i++) _button[rDataPack.buttonPayload[i]] = PRESSED;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
unsigned int _GoBLE::readChannel(byte channel) {
|
|
|
|
digitalWrite(MUX_ADDR_PINS[0], (channel & 1) ? HIGH : LOW);
|
|
digitalWrite(MUX_ADDR_PINS[1], (channel & 2) ? HIGH : LOW);
|
|
digitalWrite(MUX_ADDR_PINS[2], (channel & 4) ? HIGH : LOW);
|
|
digitalWrite(MUX_ADDR_PINS[3], (channel & 8) ? HIGH : LOW);
|
|
// workaround to cope with lack of pullup resistor on joystick switch
|
|
if (channel == CH_JOYSTICK_SW) {
|
|
pinMode(MUX_COM_PIN, INPUT_PULLUP);
|
|
unsigned int joystickSwitchState = (digitalRead(MUX_COM_PIN) == HIGH) ? 1023 : 0;
|
|
digitalWrite(MUX_COM_PIN, LOW);
|
|
return joystickSwitchState;
|
|
}
|
|
else
|
|
return analogRead(MUX_COM_PIN);
|
|
|
|
}
|
|
|
|
|
|
boolean _GoBLE::readButton(byte ch) {
|
|
if (ch >= SWITCH_1 && ch <= SWITCH_5) {
|
|
ch;
|
|
}
|
|
|
|
switch(ch) {
|
|
|
|
}
|
|
|
|
unsigned int val = readChannel(ch);
|
|
return (val > 512) ? HIGH : LOW;
|
|
}
|
|
|
|
boolean _GoBLE::readJoystickButton() {
|
|
if (readChannel(CH_JOYSTICK_SW) == 1023) {
|
|
return HIGH;
|
|
} else if (readChannel(CH_JOYSTICK_SW) == 0) {
|
|
return LOW;
|
|
}
|
|
}
|
|
|
|
*/
|
|
|