1
0
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:
Cristian Maglie 2013-05-15 18:06:25 +02:00
parent b97fdb451f
commit 05b0fc5f0b
3 changed files with 156 additions and 36 deletions

View File

@ -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 */) {

View File

@ -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;
};

View File

@ -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);
}