Skip to content

Commit 05b0fc5

Browse files
committed
Update Bridge library
1 parent b97fdb4 commit 05b0fc5

File tree

3 files changed

+154
-34
lines changed

3 files changed

+154
-34
lines changed

hardware/arduino/avr/libraries/Bridge/Bridge.cpp

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,23 @@
1818

1919
#include "Bridge.h"
2020

21+
BridgeClass::BridgeClass(Stream &_stream) : index(0), stream(_stream), started(false) {
22+
// Empty
23+
}
24+
2125
void BridgeClass::begin() {
2226
if (started)
2327
return;
2428
started = true;
2529

2630
// TODO: A more robust restart
31+
32+
// Wait for Atheros bootloader to finish startup
33+
do {
34+
dropAll();
35+
delay(1100);
36+
} while (available()>0);
37+
2738
// Bridge startup:
2839
// - If the bridge is not running starts it safely
2940
print(CTRL_C);
@@ -88,7 +99,7 @@ unsigned int BridgeClass::readCommandOutput(uint8_t handle,
8899
}
89100

90101
void BridgeClass::writeCommandInput(uint8_t handle,
91-
uint8_t *buff, unsigned int size) {
102+
const uint8_t *buff, unsigned int size) {
92103
// TODO: do it in a more efficient way
93104
uint8_t *tmp = new uint8_t[size+2];
94105
tmp[0] = 'I';
@@ -98,6 +109,49 @@ void BridgeClass::writeCommandInput(uint8_t handle,
98109
delete[] tmp;
99110
}
100111

112+
unsigned int BridgeClass::readMessage(uint8_t *buff, unsigned int size) {
113+
uint8_t tmp[] = { 'm' };
114+
return transfer(tmp, 1, buff, size);
115+
}
116+
117+
void BridgeClass::writeMessage(const uint8_t *buff, unsigned int size) {
118+
// TODO: do it in a more efficient way
119+
uint8_t *tmp = new uint8_t[size+1];
120+
tmp[0] = 'M';
121+
memcpy(tmp+1, buff, size);
122+
transfer(tmp, size+1);
123+
delete[] tmp;
124+
}
125+
126+
unsigned int BridgeClass::messageAvailable() {
127+
uint8_t tmp[] = { 'n' };
128+
uint8_t res[2];
129+
transfer(tmp, 1, res, 2);
130+
return (res[0] << 8) + res[1];
131+
}
132+
133+
void BridgeClass::put(const char *key, const char *value) {
134+
// TODO: do it in a more efficient way
135+
String cmd = "D";
136+
cmd += key;
137+
cmd += "\xFE";
138+
cmd += value;
139+
transfer((uint8_t*)cmd.c_str(), cmd.length());
140+
}
141+
142+
unsigned int BridgeClass::get(const char *key, uint8_t *value, unsigned int maxlen) {
143+
// TODO: do it in a more efficient way
144+
unsigned int l = strlen(key);
145+
uint8_t *tmp = new uint8_t[l+1];
146+
tmp[0] = 'd';
147+
memcpy(tmp+1, key, strlen(key));
148+
l = transfer(tmp, l+1, value, maxlen);
149+
if (l<maxlen)
150+
value[l] = 0; // Zero-terminate string
151+
delete[] tmp;
152+
return l;
153+
}
154+
101155
void BridgeClass::crcUpdate(uint8_t c) {
102156
CRC = CRC ^ c;
103157
CRC = (CRC >> 8) + (CRC << 8);
@@ -116,7 +170,7 @@ bool BridgeClass::crcCheck(uint16_t _CRC) {
116170
return CRC == _CRC;
117171
}
118172

119-
uint8_t BridgeClass::transfer(uint8_t *buff, uint8_t len,
173+
uint8_t BridgeClass::transfer(const uint8_t *buff, uint8_t len,
120174
uint8_t *rxbuff, uint8_t rxlen)
121175
{
122176
for ( ; ; delay(100), dropAll() /* Delay for retransmission */) {

hardware/arduino/avr/libraries/Bridge/Bridge.h

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,49 @@
2424

2525
class BridgeClass: public Stream {
2626
public:
27-
BridgeClass(Stream &_stream) : index(0), stream(_stream), started(false) {
28-
// Empty
29-
}
30-
27+
BridgeClass(Stream &_stream);
3128
void begin();
29+
30+
// Methods to handle processes on the linux side
3231
uint8_t runCommand(String &command);
33-
3432
bool commandIsRunning(uint8_t handle);
35-
3633
unsigned int commandExitValue(uint8_t handle);
37-
3834
void cleanCommand(uint8_t handle);
3935

4036
unsigned int commandOutputAvailable(uint8_t handle);
4137
unsigned int readCommandOutput(uint8_t handle, uint8_t *buff, unsigned int size);
4238
unsigned int readCommandOutput(uint8_t handle, char *buff, unsigned int size)
4339
{ return readCommandOutput(handle, reinterpret_cast<uint8_t *>(buff), size); }
4440

45-
void writeCommandInput(uint8_t handle, uint8_t *buff, unsigned int size);
46-
void writeCommandInput(uint8_t handle, char *buff, unsigned int size)
47-
{ writeCommandInput(handle, reinterpret_cast<uint8_t *>(buff), size); }
41+
void writeCommandInput(uint8_t handle, const uint8_t *buff, unsigned int size);
42+
void writeCommandInput(uint8_t handle, const char *buff, unsigned int size)
43+
{ writeCommandInput(handle, reinterpret_cast<const uint8_t *>(buff), size); }
44+
45+
// Methods to handle mailbox messages
46+
unsigned int readMessage(uint8_t *buffer, unsigned int size);
47+
void writeMessage(const uint8_t *buffer, unsigned int size);
48+
unsigned int messageAvailable();
49+
50+
// Methods to handle key/value datastore
51+
void put(const char *key, const char *value);
52+
unsigned int get(const char *key, uint8_t *buff, unsigned int size);
53+
unsigned int get(const char *key, char *value, unsigned int maxlen)
54+
{ get(key, reinterpret_cast<uint8_t *>(value), maxlen); }
4855

49-
// Print methods
56+
// Print methods (proxy to "stream" object) [CM: are these really needed?]
5057
size_t write(uint8_t c) { return stream.write(c); }
5158
size_t write(const uint8_t *buffer, size_t size)
5259
{ return stream.write(buffer, size); }
5360

54-
// Stream methods
61+
// Stream methods (proxy to "stream" object) [CM: are these really needed?]
5562
int available() { return stream.available(); }
5663
int read() { return stream.read(); }
5764
int peek() { return stream.peek(); }
5865
void flush() { stream.flush(); }
5966

60-
uint8_t transfer(uint8_t *buff, uint8_t len, uint8_t *rxbuff=NULL, uint8_t rxlen=0);
67+
// Trasnfer a frame (with error correction and response)
68+
uint8_t transfer(const uint8_t *buff, uint8_t len,
69+
uint8_t *rxbuff=NULL, uint8_t rxlen=0);
6170
private:
6271
uint8_t index;
6372
int timedRead(unsigned int timeout);
@@ -72,7 +81,6 @@ class BridgeClass: public Stream {
7281

7382
private:
7483
static const char CTRL_C = 3;
75-
static const char CMD_RECV = 0x00;
7684
Stream &stream;
7785
bool started;
7886
};
Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,90 @@
11

22
#include <Bridge.h>
33

4-
void brk() {
5-
Bridge.print((char)3);
6-
}
7-
84
void setup() {
95
pinMode(13,OUTPUT);
106
digitalWrite(13, LOW);
117
Bridge.begin();
128
digitalWrite(13, HIGH);
13-
14-
delay(2000);
15-
int handle = Bridge.beginCommand("curl");
16-
Bridge.commandAddEscapedParam("http://arduino.cc/asciilogo.txt");
17-
Bridge.endCommand();
18-
19-
while (Bridge.commandIsRunning(handle))
20-
delay(250);
21-
22-
int size = Bridge.commandOutputSize(handle);
23-
char buff[20];
24-
Bridge.readCommandOutput(handle, 0, size, buff);
25-
buff[size]=0;
26-
Bridge.print(buff);brk();
279
}
2810

2911
void loop() {
12+
while (Bridge.messageAvailable()) {
13+
uint8_t buff[64];
14+
int l = Bridge.readMessage(buff, 64);
15+
process(buff, l);
16+
}
17+
delay(100); // Poll every 0.100s
18+
}
19+
20+
void process(uint8_t buff[], int l) {
21+
// "DWppv" -> digitalWrite(pp, v)
22+
// "DRpp" -> digitalRead(pp) -> "Dpp0" / "Dpp1"
23+
// "AWppvvv" -> analogWrite(pp, vvv)
24+
// "ARpp" -> analogRead(pp) -> "App0000" - "App1023"
25+
// "PIpp" -> pinMode(pp, INPUT)
26+
// "POpp" -> pinMode(pp, OUTPUT)
27+
28+
// Sanity check
29+
if (l<4 || l>7)
30+
return;
31+
if (buff[2]<'0' || buff[2]>'9')
32+
return;
33+
if (buff[3]<'0' || buff[3]>'9')
34+
return;
35+
char cmd0 = buff[0];
36+
char cmd1 = buff[1];
37+
int pin = (buff[2]-'0')*10 + (buff[3]-'0');
38+
if (pin<0 || pin>13)
39+
return;
40+
41+
// Command selection
42+
if (l==5 && cmd0=='D' && cmd1=='W') {
43+
char c = buff[4];
44+
if (c=='0' || c=='1')
45+
digitalWrite(pin, c-'0');
46+
} else if (l==4 && cmd0=='D' && cmd1=='R') {
47+
reportDigitalRead(pin, true, true);
48+
} else if (l==7 && cmd0=='A' && cmd1=='W') {
49+
analogWrite(pin, buff[4]);
50+
} else if (l==4 && cmd0=='A' && cmd1=='R') {
51+
reportAnalogRead(pin);
52+
} else if (l==4 && cmd0=='P' && cmd1=='I') {
53+
pinMode(pin, INPUT);
54+
} else if (l==4 && cmd0=='P' && cmd1=='O') {
55+
pinMode(pin, OUTPUT);
56+
}
57+
}
58+
59+
void reportDigitalRead(int pin, boolean raw, boolean dataset) {
60+
// "Dpp0" - "Dpp1"
61+
// 0 1 2 3
62+
uint8_t buff[] = { 'D', '0', '0', '0' };
63+
buff[1] += pin/10;
64+
buff[2] += pin%10;
65+
if (digitalRead(pin) == HIGH)
66+
buff[3] = '1';
67+
if (raw)
68+
Bridge.writeMessage(buff, 4);
69+
if (dataset) {
70+
char *val = "0";
71+
val[0] = buff[3];
72+
buff[3] = 0;
73+
Bridge.put((const char *)buff, val);
74+
}
3075
}
3176

77+
void reportAnalogRead(int pin) {
78+
// "App0000" - "App1023"
79+
// 0 1 2 3 4 5 6
80+
uint8_t buff[] = { 'A', '0', '0', '0', '0', '0', '0' };
81+
buff[1] += pin/10;
82+
buff[2] += pin%10;
3283

84+
int v = analogRead(pin);
85+
buff[6] += v%10; v /= 10;
86+
buff[5] += v%10; v /= 10;
87+
buff[4] += v%10; v /= 10;
88+
buff[3] += v;
89+
Bridge.writeMessage(buff, 7);
90+
}

0 commit comments

Comments
 (0)