mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-30 19:52:13 +01:00
Update Bridge library
This commit is contained in:
parent
b97fdb451f
commit
05b0fc5f0b
@ -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 */) {
|
||||
|
@ -24,17 +24,13 @@
|
||||
|
||||
class BridgeClass: public Stream {
|
||||
public:
|
||||
BridgeClass(Stream &_stream) : index(0), stream(_stream), started(false) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
BridgeClass(Stream &_stream);
|
||||
void begin();
|
||||
uint8_t runCommand(String &command);
|
||||
|
||||
bool commandIsRunning(uint8_t handle);
|
||||
|
||||
unsigned int commandExitValue(uint8_t handle);
|
||||
|
||||
// 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); }
|
||||
|
||||
// Print methods
|
||||
// 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 (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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user