diff options
Diffstat (limited to 'libraries/Bridge')
-rw-r--r-- | libraries/Bridge/Bridge.cpp | 58 | ||||
-rw-r--r-- | libraries/Bridge/Bridge.h | 36 | ||||
-rw-r--r-- | libraries/Bridge/examples/Bridge/Bridge.ino | 94 |
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 |