aboutsummaryrefslogtreecommitdiff
path: root/libraries/Bridge
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/Bridge')
-rw-r--r--libraries/Bridge/Bridge.cpp58
-rw-r--r--libraries/Bridge/Bridge.h36
-rw-r--r--libraries/Bridge/examples/Bridge/Bridge.ino94
3 files changed, 154 insertions, 34 deletions
diff --git a/libraries/Bridge/Bridge.cpp b/libraries/Bridge/Bridge.cpp
index 637b1aa..440cde0 100644
--- a/libraries/Bridge/Bridge.cpp
+++ b/libraries/Bridge/Bridge.cpp
@@ -18,12 +18,23 @@
#include "Bridge.h"
+BridgeClass::BridgeClass(Stream &_stream) : index(0), stream(_stream), started(false) {
+ // Empty
+}
+
void BridgeClass::begin() {
if (started)
return;
started = true;
// TODO: A more robust restart
+
+ // Wait for Atheros bootloader to finish startup
+ do {
+ dropAll();
+ delay(1100);
+ } while (available()>0);
+
// Bridge startup:
// - If the bridge is not running starts it safely
print(CTRL_C);
@@ -88,7 +99,7 @@ unsigned int BridgeClass::readCommandOutput(uint8_t handle,
}
void BridgeClass::writeCommandInput(uint8_t handle,
- uint8_t *buff, unsigned int size) {
+ const uint8_t *buff, unsigned int size) {
// TODO: do it in a more efficient way
uint8_t *tmp = new uint8_t[size+2];
tmp[0] = 'I';
@@ -98,6 +109,49 @@ void BridgeClass::writeCommandInput(uint8_t handle,
delete[] tmp;
}
+unsigned int BridgeClass::readMessage(uint8_t *buff, unsigned int size) {
+ uint8_t tmp[] = { 'm' };
+ return transfer(tmp, 1, buff, size);
+}
+
+void BridgeClass::writeMessage(const uint8_t *buff, unsigned int size) {
+ // TODO: do it in a more efficient way
+ uint8_t *tmp = new uint8_t[size+1];
+ tmp[0] = 'M';
+ memcpy(tmp+1, buff, size);
+ transfer(tmp, size+1);
+ delete[] tmp;
+}
+
+unsigned int BridgeClass::messageAvailable() {
+ uint8_t tmp[] = { 'n' };
+ uint8_t res[2];
+ transfer(tmp, 1, res, 2);
+ return (res[0] << 8) + res[1];
+}
+
+void BridgeClass::put(const char *key, const char *value) {
+ // TODO: do it in a more efficient way
+ String cmd = "D";
+ cmd += key;
+ cmd += "\xFE";
+ cmd += value;
+ transfer((uint8_t*)cmd.c_str(), cmd.length());
+}
+
+unsigned int BridgeClass::get(const char *key, uint8_t *value, unsigned int maxlen) {
+ // TODO: do it in a more efficient way
+ unsigned int l = strlen(key);
+ uint8_t *tmp = new uint8_t[l+1];
+ tmp[0] = 'd';
+ memcpy(tmp+1, key, strlen(key));
+ l = transfer(tmp, l+1, value, maxlen);
+ if (l<maxlen)
+ value[l] = 0; // Zero-terminate string
+ delete[] tmp;
+ return l;
+}
+
void BridgeClass::crcUpdate(uint8_t c) {
CRC = CRC ^ c;
CRC = (CRC >> 8) + (CRC << 8);
@@ -116,7 +170,7 @@ bool BridgeClass::crcCheck(uint16_t _CRC) {
return CRC == _CRC;
}
-uint8_t BridgeClass::transfer(uint8_t *buff, uint8_t len,
+uint8_t BridgeClass::transfer(const uint8_t *buff, uint8_t len,
uint8_t *rxbuff, uint8_t rxlen)
{
for ( ; ; delay(100), dropAll() /* Delay for retransmission */) {
diff --git a/libraries/Bridge/Bridge.h b/libraries/Bridge/Bridge.h
index 0740d4f..f85fa07 100644
--- a/libraries/Bridge/Bridge.h
+++ b/libraries/Bridge/Bridge.h
@@ -24,17 +24,13 @@
class BridgeClass: public Stream {
public:
- BridgeClass(Stream &_stream) : index(0), stream(_stream), started(false) {
- // Empty
- }
-
+ BridgeClass(Stream &_stream);
void begin();
+
+ // Methods to handle processes on the linux side
uint8_t runCommand(String &command);
-
bool commandIsRunning(uint8_t handle);
-
unsigned int commandExitValue(uint8_t handle);
-
void cleanCommand(uint8_t handle);
unsigned int commandOutputAvailable(uint8_t handle);
@@ -42,22 +38,35 @@ public:
unsigned int readCommandOutput(uint8_t handle, char *buff, unsigned int size)
{ return readCommandOutput(handle, reinterpret_cast<uint8_t *>(buff), size); }
- void writeCommandInput(uint8_t handle, uint8_t *buff, unsigned int size);
- void writeCommandInput(uint8_t handle, char *buff, unsigned int size)
- { writeCommandInput(handle, reinterpret_cast<uint8_t *>(buff), size); }
+ void writeCommandInput(uint8_t handle, const uint8_t *buff, unsigned int size);
+ void writeCommandInput(uint8_t handle, const char *buff, unsigned int size)
+ { writeCommandInput(handle, reinterpret_cast<const uint8_t *>(buff), size); }
+
+ // Methods to handle mailbox messages
+ unsigned int readMessage(uint8_t *buffer, unsigned int size);
+ void writeMessage(const uint8_t *buffer, unsigned int size);
+ unsigned int messageAvailable();
+
+ // Methods to handle key/value datastore
+ void put(const char *key, const char *value);
+ unsigned int get(const char *key, uint8_t *buff, unsigned int size);
+ unsigned int get(const char *key, char *value, unsigned int maxlen)
+ { get(key, reinterpret_cast<uint8_t *>(value), maxlen); }
- // Print methods
+ // Print methods (proxy to "stream" object) [CM: are these really needed?]
size_t write(uint8_t c) { return stream.write(c); }
size_t write(const uint8_t *buffer, size_t size)
{ return stream.write(buffer, size); }
- // Stream methods
+ // Stream methods (proxy to "stream" object) [CM: are these really needed?]
int available() { return stream.available(); }
int read() { return stream.read(); }
int peek() { return stream.peek(); }
void flush() { stream.flush(); }
- uint8_t transfer(uint8_t *buff, uint8_t len, uint8_t *rxbuff=NULL, uint8_t rxlen=0);
+ // Trasnfer a frame (with error correction and response)
+ uint8_t transfer(const uint8_t *buff, uint8_t len,
+ uint8_t *rxbuff=NULL, uint8_t rxlen=0);
private:
uint8_t index;
int timedRead(unsigned int timeout);
@@ -72,7 +81,6 @@ private:
private:
static const char CTRL_C = 3;
- static const char CMD_RECV = 0x00;
Stream &stream;
bool started;
};
diff --git a/libraries/Bridge/examples/Bridge/Bridge.ino b/libraries/Bridge/examples/Bridge/Bridge.ino
index 848cc4e..c4f71db 100644
--- a/libraries/Bridge/examples/Bridge/Bridge.ino
+++ b/libraries/Bridge/examples/Bridge/Bridge.ino
@@ -1,32 +1,90 @@
#include <Bridge.h>
-void brk() {
- Bridge.print((char)3);
-}
-
void setup() {
pinMode(13,OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
-
- delay(2000);
- int handle = Bridge.beginCommand("curl");
- Bridge.commandAddEscapedParam("http://arduino.cc/asciilogo.txt");
- Bridge.endCommand();
-
- while (Bridge.commandIsRunning(handle))
- delay(250);
-
- int size = Bridge.commandOutputSize(handle);
- char buff[20];
- Bridge.readCommandOutput(handle, 0, size, buff);
- buff[size]=0;
- Bridge.print(buff);brk();
}
void loop() {
+ while (Bridge.messageAvailable()) {
+ uint8_t buff[64];
+ int l = Bridge.readMessage(buff, 64);
+ process(buff, l);
+ }
+ delay(100); // Poll every 0.100s
+}
+
+void process(uint8_t buff[], int l) {
+ // "DWppv" -> digitalWrite(pp, v)
+ // "DRpp" -> digitalRead(pp) -> "Dpp0" / "Dpp1"
+ // "AWppvvv" -> analogWrite(pp, vvv)
+ // "ARpp" -> analogRead(pp) -> "App0000" - "App1023"
+ // "PIpp" -> pinMode(pp, INPUT)
+ // "POpp" -> pinMode(pp, OUTPUT)
+
+ // Sanity check
+ if (l<4 || l>7)
+ return;
+ if (buff[2]<'0' || buff[2]>'9')
+ return;
+ if (buff[3]<'0' || buff[3]>'9')
+ return;
+ char cmd0 = buff[0];
+ char cmd1 = buff[1];
+ int pin = (buff[2]-'0')*10 + (buff[3]-'0');
+ if (pin<0 || pin>13)
+ return;
+
+ // Command selection
+ if (l==5 && cmd0=='D' && cmd1=='W') {
+ char c = buff[4];
+ if (c=='0' || c=='1')
+ digitalWrite(pin, c-'0');
+ } else if (l==4 && cmd0=='D' && cmd1=='R') {
+ reportDigitalRead(pin, true, true);
+ } else if (l==7 && cmd0=='A' && cmd1=='W') {
+ analogWrite(pin, buff[4]);
+ } else if (l==4 && cmd0=='A' && cmd1=='R') {
+ reportAnalogRead(pin);
+ } else if (l==4 && cmd0=='P' && cmd1=='I') {
+ pinMode(pin, INPUT);
+ } else if (l==4 && cmd0=='P' && cmd1=='O') {
+ pinMode(pin, OUTPUT);
+ }
+}
+
+void reportDigitalRead(int pin, boolean raw, boolean dataset) {
+ // "Dpp0" - "Dpp1"
+ // 0 1 2 3
+ uint8_t buff[] = { 'D', '0', '0', '0' };
+ buff[1] += pin/10;
+ buff[2] += pin%10;
+ if (digitalRead(pin) == HIGH)
+ buff[3] = '1';
+ if (raw)
+ Bridge.writeMessage(buff, 4);
+ if (dataset) {
+ char *val = "0";
+ val[0] = buff[3];
+ buff[3] = 0;
+ Bridge.put((const char *)buff, val);
+ }
}
+void reportAnalogRead(int pin) {
+ // "App0000" - "App1023"
+ // 0 1 2 3 4 5 6
+ uint8_t buff[] = { 'A', '0', '0', '0', '0', '0', '0' };
+ buff[1] += pin/10;
+ buff[2] += pin%10;
+ int v = analogRead(pin);
+ buff[6] += v%10; v /= 10;
+ buff[5] += v%10; v /= 10;
+ buff[4] += v%10; v /= 10;
+ buff[3] += v;
+ Bridge.writeMessage(buff, 7);
+} \ No newline at end of file