diff --git a/examples/APRS-Beacon/1200.wav b/examples/APRS-Beacon/1200.wav new file mode 100755 index 0000000..de71193 Binary files /dev/null and b/examples/APRS-Beacon/1200.wav differ diff --git a/examples/APRS-Beacon/2200.wav b/examples/APRS-Beacon/2200.wav new file mode 100755 index 0000000..2c7d9a0 Binary files /dev/null and b/examples/APRS-Beacon/2200.wav differ diff --git a/examples/ChromeHAMShield/background.js b/examples/ChromeHAMShield/background.js new file mode 100755 index 0000000..a800665 --- /dev/null +++ b/examples/ChromeHAMShield/background.js @@ -0,0 +1,8 @@ +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create("window.html", { + "bounds": { + "width": 400, + "height": 500 + } + }); +}); \ No newline at end of file diff --git a/examples/ChromeHAMShield/manifest.json b/examples/ChromeHAMShield/manifest.json new file mode 100755 index 0000000..11f79c9 --- /dev/null +++ b/examples/ChromeHAMShield/manifest.json @@ -0,0 +1,10 @@ +{ + "name": "", + "description": "HAMShield", + "version": "1.0.0", + "app": { + "background": { + "scripts": ["background.js"] + } + } + } \ No newline at end of file diff --git a/examples/ChromeHAMShield/project.ps b/examples/ChromeHAMShield/project.ps new file mode 100755 index 0000000..7b341aa --- /dev/null +++ b/examples/ChromeHAMShield/project.ps @@ -0,0 +1 @@ +chromeApp \ No newline at end of file diff --git a/examples/ChromeHAMShield/styles.css b/examples/ChromeHAMShield/styles.css new file mode 100755 index 0000000..ab5f11c --- /dev/null +++ b/examples/ChromeHAMShield/styles.css @@ -0,0 +1 @@ +body{} \ No newline at end of file diff --git a/examples/ChromeHAMShield/window.html b/examples/ChromeHAMShield/window.html new file mode 100755 index 0000000..d6bfb7c --- /dev/null +++ b/examples/ChromeHAMShield/window.html @@ -0,0 +1,13 @@ + + +
+ + +; must be a valid CDCSS code No
+CDCSS Out H; must be a valid CDCSS code No
+Print tones I Prints out all configured tones and codes, coma delimited in format: CTCSS In, CTCSS Out, CDCSS In, CDCSS Out No
+Power level P; Set the power amp level, 0 = lowest, 255 = highest No
+Enable Offset R; 1 turns on repeater offset mode, 0 turns off repeater offset mode No
+Squelch S; Set the squelch level No
+TX Offset T; The absolute frequency of the repeater offset to transmit on in KHz No
+Volume V; Set the volume level of the receiver No
+Reset X Reset all settings to default No
+Sleep Z Sleep radio No
+Filters @; Set bit to enable, clear bit to disable: 0 = pre/de-emphasis, 1 = high pass filter, 2 = low pass filter (default: ascii 7, all enabled) No
+Vox mode $; 0 = vox off, >= 1 audio sensitivity. lower value more sensitive No
+Mic Channel *; Set the voice channel. 0 = signal from mic or arduino, 1 = internal tone generator No
+RSSI ? Respond with the current receive level in - dBm (no sign provided on numerical response) No
+Tone Gen % (notes) To send a tone, use the following format: Single tone: %1,,; Dual tone: %2,,,; DTMF: %3,,; No
+Voice Level ^ Respond with the current voice level (VSSI)
+
+
+Responses:
+
+Condition ASCII Description
+------------ ---------- -----------------------------------------------------------------
+Startup *; Startup and shield connection status
+Success !; Generic success message for command that returns no value
+Error X; Indicates an error code. The numerical value is the type of error
+Value :; In response to a query
+Status #; Unsolicited status message
+Debug Msg @; 32 character debug message
+
+*/
+
+#include "Wire.h"
+#include "HAMShield.h"
+
+int state;
+int txcount = 0;
+long timer = 0;
+long freq = 144390;
+long tx = 0;
+char cmdbuff[32] = "";
+int temp = 0;
+int repeater = 0;
+float ctcssin = 0;
+float ctcssout = 0;
+int cdcssin = 0;
+int cdcssout = 0;
+
+
+HAMShield radio;
+
+
+
+void setup() {
+ Serial.begin(115200);
+ Serial.print(";;;;;;;;;;;;;;;;;;;;;;;;;;");
+ Wire.begin();
+ int result = radio.testConnection();
+ Serial.print("*");
+ Serial.print(result,DEC);
+ Serial.print(";");
+ radio.initialize(); // initializes automatically for UHF 12.5kHz channel
+ Serial.print("*START;");
+ radio.frequency(freq);
+ radio.setVolume1(0xF);
+ radio.setVolume2(0xF);
+ radio.setModeReceive();
+ radio.setTxSourceMic();
+ radio.setRfPower(255); // 30 is 0.5V, which corresponds to 29 dBm out (see RF6886 datasheet)
+ radio.setSQLoThresh(80);
+ radio.setSQOn();
+}
+
+void loop() {
+
+ if(Serial.available()) {
+
+ int text = Serial.read();
+
+ switch (state) {
+
+ case 10:
+ if(text == 32) { timer = millis();}
+ break;
+
+ case 0:
+ switch(text) {
+
+ case 32: // space - transmit
+ if(repeater == 1) { radio.frequency(tx); }
+ radio.setRX(0);
+ radio.setTX(1);
+ state = 10;
+ Serial.print("#TX,ON;");
+ timer = millis();
+ break;
+
+ case 63: // ? - RSSI
+ Serial.print(":");
+ Serial.print(radio.readRSSI(),DEC);
+ Serial.print(";");
+ break;
+
+ case 65: // A - CTCSS In
+ getValue();
+ ctcssin = atof(cmdbuff);
+ radio.setCtcss(ctcssin);
+ break;
+
+ case 66: // B - CTCSS Out
+ break;
+
+ case 67: // C - CTCSS Enable
+ break;
+
+ case 68: // D - CDCSS Enable
+ break;
+
+ case 70: // F - frequency
+ getValue();
+ freq = atol(cmdbuff);
+ if(radio.frequency(freq) == true) { Serial.print("@"); Serial.print(freq,DEC); Serial.print(";!;"); } else { Serial.print("X1;"); }
+ break;
+
+ case 80: // P - power level
+ getValue();
+ temp = atol(cmdbuff);
+ radio.setRfPower(temp);
+ break;
+
+ case 82: // R - repeater offset mode
+ getValue();
+ temp = atol(cmdbuff);
+ if(temp == 0) { repeater = 0; }
+ if(temp == 1) { repeater = 1; }
+ break;
+
+ case 83: // S - squelch
+ getValue();
+ temp = atol(cmdbuff);
+ radio.setSQLoThresh(temp);
+ break;
+
+ case 84: // T - transmit offset
+ getValue();
+ tx = atol(cmdbuff);
+ break;
+
+
+ case 94: // ^ - VSSI (voice) level
+ Serial.print(":");
+ Serial.print(radio.readVSSI(),DEC);
+ Serial.print(";");
+ }
+ break;
+ }
+
+ }
+ if(state == 10) {
+ if(millis() > (timer + 500)) { Serial.print("#TX,OFF;");radio.setRX(1); radio.setTX(0); if(repeater == 1) { radio.frequency(freq); } state = 0; txcount = 0; }
+ }
+}
+
+void getValue() {
+ int p = 0;
+ char temp;
+ for(;;) {
+ if(Serial.available()) {
+ temp = Serial.read();
+ if(temp == 59) { cmdbuff[p] = 0; Serial.print("@");
+ for(int x = 0; x < 32; x++) { Serial.print(cmdbuff[x]); }
+ return;
+ }
+ cmdbuff[p] = temp;
+ p++;
+ if(p == 32) {
+ Serial.print("@");
+ for(int x = 0; x < 32; x++) {
+ Serial.print(cmdbuff[x]);
+ }
+
+ cmdbuff[0] = 0;
+
+ Serial.print("X0;"); return; } // some sort of alignment issue? lets not feed junk into whatever takes this string in
+ }
+ }
+}
+
diff --git a/examples/SignalTest/SignalTest.ino b/examples/SignalTest/SignalTest.ino
new file mode 100755
index 0000000..11bb298
--- /dev/null
+++ b/examples/SignalTest/SignalTest.ino
@@ -0,0 +1,140 @@
+/*
+
+Plays back the current signal strength level and morses out it's call sign at the end.
+
+
+*/
+
+#define DOT 100
+#define CALLSIGN "1ZZ9ZZ/B"
+
+/* Standard libraries and variable init */
+
+#include
+#include
+#include
+
+HAMShield radio;
+int16_t rssi;
+int peak = -150;
+char sig[8];
+
+
+/* Audio samples */
+
+const unsigned char minus[] PROGMEM = {
+130, 130, 130, 132, 134, 134, 135, 139, 141, 140, 141, 143, 141, 139, 139, 138, 135, 131, 129, 126, 122, 119, 117, 114, 111, 110, 110, 108, 107, 107, 107, 107, 108, 109, 110, 111, 113, 115, 116, 119, 121, 124, 126, 128, 129, 131, 133, 135, 135, 137, 138, 138, 137, 137, 137, 135, 134, 135, 134, 128, 126, 127, 124, 119, 120, 119, 113, 113, 120, 119, 117, 123, 129, 128, 131, 140, 143, 145, 153, 158, 158, 163, 168, 169, 168, 170, 168, 164, 161, 157, 149, 142, 136, 128, 121, 116, 109, 103, 100, 97, 92, 91, 92, 93, 93, 95, 99, 102, 105, 107, 110, 113, 117, 119, 120, 122, 125, 126, 128, 127, 126, 130, 131, 125, 123, 129, 126, 118, 117, 120, 113, 112, 117, 112, 101, 103, 108, 102, 98, 102, 102, 105, 121, 129, 128, 137, 160, 171, 172, 178, 185, 186, 189, 194, 192, 190, 192, 190, 181, 175, 167, 157, 148, 141, 130, 119, 112, 106, 99, 95, 91, 86, 84, 84, 85, 86, 89, 92, 95, 100, 106, 111, 116, 121, 126, 130, 134, 137, 139, 139, 139, 137, 134, 131, 125, 120, 115, 108, 101, 95, 90, 84, 80, 78, 75, 73, 75, 77, 77, 80, 83, 87, 91, 97, 100, 103, 112, 119, 118, 119, 125, 127, 123, 129, 135, 135, 142, 152, 153, 151, 165, 175, 179, 185, 194, 192, 193, 199, 199, 197, 197, 194, 183, 176, 167, 158, 151, 147, 138, 128, 119, 110, 102, 99, 97, 94, 93, 92, 87, 87, 91, 95, 104, 111, 115, 118, 122, 127, 133, 142, 149, 152, 156, 157, 159, 159, 161, 161, 161, 158, 151, 144, 139, 131, 124, 119, 111, 103, 94, 86, 78, 74, 71, 69, 69, 68, 66, 66, 69, 73, 77, 83, 86, 91, 96, 101, 104, 110, 109, 108, 107, 117, 118, 127, 144, 144, 143, 151, 171, 172, 186, 198, 205, 201, 205, 203, 198, 196, 192, 183, 169, 159, 143, 137, 129, 125, 115, 111, 100, 91, 85, 83, 80, 78, 79, 79, 80, 81, 85, 89, 95, 100, 109, 111, 116, 112, 109, 101, 108, 115, 146, 200, 224, 235, 230, 216, 180, 145, 125, 112, 112, 118, 118, 119, 118, 123, 133, 150, 166, 164, 161, 144, 126, 112, 108, 113, 119, 128, 130, 124, 124, 123, 126, 132, 137, 135, 129, 125, 118, 120, 126, 132, 139, 143, 141, 138, 135, 134, 132, 131, 130, 128, 128, 128, 130, 130, 129, 126, 123, 118, 115, 114, 115, 113, 113, 111, 109, 107, 107, 109, 109, 108, 108, 111, 115, 118, 114, 114, 107, 107, 106, 110, 115, 116, 114, 115, 109, 101, 89, 96, 105, 136, 201, 230, 247, 212, 159, 97, 62, 74, 112, 173, 199, 202, 174, 134, 107, 102, 119, 141, 153, 149, 129, 117, 112, 124, 140, 148, 146, 131, 116, 103, 103, 110, 117, 124, 128, 131, 135, 141, 146, 144, 139, 127, 119, 116, 119, 130, 139, 144, 142, 136, 131, 129, 130, 130, 130, 125, 120, 116, 117, 119, 121, 121, 117, 113, 109, 109, 110, 113, 111, 113, 111, 113, 113, 113, 113, 116, 116, 115, 110, 104, 101, 105, 114, 121, 123, 117, 110, 85, 83, 84, 115, 139, 206, 250, 241, 211, 132, 83, 50, 90, 143, 201, 219, 185, 148, 112, 108, 121, 143, 147, 139, 131, 124, 129, 136, 135, 131, 123, 124, 128, 135, 129, 118, 103, 97, 105, 123, 141, 149, 149, 140, 131, 124, 121, 119, 123, 128, 136, 143, 148, 145, 138, 131, 127, 128, 132, 133, 131, 127, 120, 116, 115, 118, 121, 125, 126, 121, 115, 112, 108, 107, 109, 112, 111, 109, 109, 111, 114, 115, 110, 109, 111, 115, 116, 112, 108, 97, 100, 101, 109, 110, 116, 108, 177, 255, 236, 180, 111, 87, 86, 142, 174, 166, 152, 148, 155, 156, 154, 121, 104, 119, 142, 148, 142, 131, 117, 120, 135, 136, 131, 128, 123, 116, 119, 115, 110, 112, 120, 129, 138, 146, 142, 135, 128, 125, 126, 128, 129, 132, 139, 144, 143, 137, 132, 133, 137, 137, 131, 123, 119, 116, 114, 113, 115, 120, 123, 120, 112, 106, 104, 106, 107, 104, 102, 105, 109, 113, 111, 110, 109, 109, 107, 108, 112, 114, 108, 100, 101, 99, 105, 97, 113, 129, 201, 246, 201, 165, 163, 175, 139, 120, 115, 134, 156, 154, 140, 147, 171, 161, 140, 131, 131, 130, 127, 114, 112, 127, 136, 125, 121, 130, 136, 129, 120, 117, 120, 120, 111, 107, 118, 136, 139, 138, 145, 152, 152, 145, 136, 132, 131, 130, 127, 130, 136, 134, 127, 125, 126, 122, 115, 110, 109, 110, 110, 106, 105, 106, 105, 102, 102, 101, 98, 100, 104, 103, 104, 108, 105, 104, 105, 106, 105, 108, 109, 109, 109, 110, 110, 107, 107, 117, 134, 145, 148, 155, 173, 178, 179, 182, 186, 186, 186, 184, 177, 176, 173, 168, 159, 151, 141, 137, 132, 124, 118, 119, 120, 117, 114, 112, 113, 112, 112, 110, 111, 112, 112, 113, 114, 116, 120, 126, 130, 131, 134, 138, 142, 144, 147, 148, 149, 148, 147, 145, 142, 138, 134, 129, 124, 119, 115, 110, 105, 100, 96, 93, 91, 88, 88, 89, 88, 87, 87, 87, 88, 90, 90, 92, 93, 95, 95, 97, 98, 100, 100, 101, 105, 116, 132, 136, 143, 158, 175, 177, 183, 193, 198, 200, 201, 197, 187, 184, 178, 167, 158, 151, 140, 133, 128, 120, 115, 119, 119, 116, 117, 116, 113, 112, 110, 108, 110, 110, 112, 115, 123, 129, 134, 142, 148, 154, 155, 154, 151, 151, 144, 137, 132, 127, 123, 118, 114, 111, 114, 111, 109, 107, 104, 101, 97, 91, 90, 89, 82, 72, 75, 77, 75, 71, 73, 78, 81, 83, 82, 94, 92, 97, 120, 166, 182, 182, 195, 217, 220, 196, 185, 177, 178, 159, 143, 133, 141, 145, 143, 142, 144, 149, 147, 144, 140, 145, 140, 132, 126, 126, 124, 119, 113, 111, 115, 115, 114, 117, 126, 134, 141, 146, 153, 160, 158, 155, 153, 149, 143, 137, 131, 127, 124, 118, 114, 114, 113, 108, 108, 109, 107, 104, 102, 96, 93, 89, 85, 81, 74, 74, 70, 69, 70, 75, 74, 76, 81, 86, 100, 130, 157, 160, 183, 207, 205, 187, 184, 182, 173, 167, 154, 147, 150, 150, 140, 139, 142, 145, 143, 140, 138, 140, 138, 132, 132, 131, 130, 129, 128, 124, 125, 127, 127, 126, 126, 127, 132, 134, 131, 134, 137, 141, 143, 144, 144, 146, 145, 137, 129, 121, 114, 109, 101, 93, 90, 88, 85, 80, 76, 75, 79, 79, 77, 72, 73, 69, 67, 64, 73, 86, 119, 156, 166, 185, 201, 210, 196, 193, 178, 171, 169, 161, 157, 152, 154, 148, 148, 137, 139, 140, 134, 128, 129, 126, 127, 130, 125, 128, 130, 132, 129, 128, 124, 126, 132, 126, 123, 127, 131, 133, 136, 139, 140, 143, 139, 135, 132, 127, 122, 115, 112, 106, 100, 97, 91, 85, 80, 79, 79, 78, 72, 72, 67, 70, 67, 66, 71, 92, 133, 162, 178, 173, 188, 196, 195, 179, 165, 158, 158, 166, 154, 142, 136, 150, 153, 148, 139, 139, 142, 141, 137, 134, 138, 139, 143, 141, 136, 132, 132, 129, 124, 120, 122, 124, 127, 133, 134, 137, 140, 140, 138, 136, 131, 126, 122, 117, 109, 101, 93, 89, 87, 84, 80, 79, 79, 77, 74, 68, 68, 69, 65, 67, 103, 141, 150, 151, 162, 173, 179, 175, 157, 156, 165, 173, 168, 165, 153, 159, 168, 160, 151, 149, 150, 147, 148, 142, 138, 140, 148, 142, 135, 131, 131, 127, 125, 122, 120, 121, 121, 122, 121, 122, 125, 129, 125, 123, 122, 121, 116, 110, 104, 101, 100, 95, 92, 91, 90, 88, 85, 82, 83, 84, 82, 81, 101, 129, 136, 132, 136, 144, 149, 151, 147, 148, 159, 166, 162, 158, 155, 158, 163, 162, 153, 152, 157, 158, 154, 152, 148, 148, 146, 136, 130, 129, 128, 121, 120, 119, 120, 121, 120, 118, 119, 121, 120, 118, 118, 121, 122, 119, 114, 110, 110, 112, 108, 108, 105, 104, 104, 103, 100, 102, 102, 98, 98, 98, 97, 101, 119, 129, 130, 131, 138, 141, 146, 146, 145, 148, 154, 156, 155, 154, 151, 151, 150, 148, 145, 146, 144, 144, 141, 141, 138, 137, 135, 132, 130, 129, 128, 124, 123, 120, 121, 120, 120, 118, 121, 121, 120, 124, 120, 119, 119, 120, 119, 117, 114, 114, 116, 117, 115, 117, 114, 120, 115, 115, 111, 116, 120, 118, 122, 118, 122, 123, 125, 121, 125, 125, 129, 129, 133, 130, 137, 134, 138, 138, 139, 142, 141, 144, 138, 141, 138, 141, 137, 137, 135, 137, 136, 134, 131, 131, 132, 131, 129, 128, 127, 129, 124, 125, 125, 124, 126, 122, 126, 121, 125, 117, 123, 123, 122, 125, 124, 125, 120, 123, 120, 122, 120, 123, 126, 126, 126, 124, 129, 129, 127, 126, 131, 129, 130, 126, 127, 131, 127, 130, 125, 129, 127, 125, 127, 130, 128, 126, 130, 131, 130, 126, 129, 127, 131, 126, 126, 129, 130, 130, 126, 130, 124, 132, 130, 130, 132, 126, 131, 125, 128, 126, 126, 129, 126, 129, 126, 131, 128, 127, 127, 128, 127, 128, 129, 127, 124, 129, 126, 127, 130, 129, 130, 129, 126, 128, 128, 127, 130, 122, 132, 121, 130, 125, 131, 125, 128, 129, 128, 130, 122, 131, 122, 133, 125, 129, 123, 130, 125, 130, 122, 127, 129, 125, 132, 124, 129, 129, 130, 125, 128, 127, 132, 127, 129, 125, 130, 128, 126, 128, 125, 129, 126, 129, 127, 129, 128, 127, 128, 124, 130, 128, 127, 128, 128, 130, 127, 130, 123, 132, 122, 132, 123, 126, 128, 124, 134, 120, 134, 118, 138, 124, 127, 125, 125, 132, 125, 129, 122, 134, 126, 132, 123, 130, 126, 131, 127, 127, 124, 130, 128, 128, 124, 126, 129, 127, 129, 125, 128, 125, 131, 123, 130, 123, 134, 127, 129, 126, 126, 130, 126, 126, 126, 128, 126, 130, 127, 127, 129, 129, 127, 130, 125, 131, 126, 130, 127, 127, 127, 128, 128, 126, 129, 124, 131, 124, 132, 125, 129, 127, 129, 128, 126, 130, 124, 134, 124, 130, 128, 129, 129, 126, 128, 128, 129, 130, 125, 126, 131, 126, 128, 125, 127, 129, 128, 129, 125, 128, 132, 123, 130, 125, 129, 126, 126, 126, 128, 127, 127, 124, 126, 129, 125, 129, 123, 132, 123, 129, 125, 128, 126, 127, 126, 125, 129, 123, 131, 125, 128, 126, 125, 129, 126, 129, 129, 126, 131, 125, 133, 124, 131, 126, 127, 129, 125, 130, 125, 134, 121, 134, 120, 134, 123, 129, 130, 123, 135, 121, 132, 123, 132, 124, 130, 126, 128, 131, 126, 128, 126, 127, 128, 129, 127, 127, 128, 131, 123, 131, 124, 132, 127, 124, 132, 121, 134, 125, 127, 129, 126, 128, 128, 129, 125, 127, 126, 128, 127, 126, 128, 128, 128, 125, 128, 128, 127, 128, 127, 129, 127, 130, 125, 126, 128, 126, 131, 123, 130, 127, 128, 129, 123, 129, 127, 129, 126, 128, 127, 127, 130, 125, 128, 129, 125, 129, 122, 127, 130, 124, 129, 125, 127, 130, 125, 127, 127, 126, 129, 126, 127, 129, 128, 126, 129, 124, 131, 126, 126, 131, 123, 129, 129, 125, 131, 125, 130, 127, 126, 129, 125, 130, 125, 130, 128, 127, 127, 128, 124, 129, 125, 132, 126, 128, 128, 125, 127, 128, 127, 127, 132, 123, 132, 125, 128, 127, 126, 129, 127, 125, 129, 126, 132, 126, 130, 126, 132, 125, 129, 130, 127, 133, 123, 131, 124, 132, 126, 134, 124, 131, 128, 127, 129, 122, 136, 124, 129, 127, 124, 127, 128, 128, 125, 133, 125, 129, 128, 124, 131, 123, 132, 124, 127, 129, 126, 131, 125, 130, 127, 131, 125, 129, 129, 128, 129, 125, 130, 127, 128, 126, 132, 127, 129, 128, 127, 129, 129, 126, 128, 126, 131, 129, 125, 127, 131, 128, 126, 129, 122, 136, 121, 131, 124, 129, 130, 121, 133, 124, 133, 124, 129, 125, 130, 127, 127, 134, 121, 132, 123, 133, 127, 125, 125, 133, 127, 123, 129, 130, 131, 123, 130, 125, 137, 116, 135, 120, 133, 129, 119, 136, 121, 138, 114, 131, 129, 129, 127, 126, 134, 119, 134, 120, 130, 128, 126, 122, 131, 126, 126, 129, 123, 140, 120, 136, 116, 135, 128, 124, 127, 127, 129, 131, 121, 131, 129, 125, 133, 120, 138, 116, 141, 112, 137, 126, 126, 124, 132, 126, 125, 126, 127, 136, 120, 136, 114, 143, 113, 133, 122, 130, 127, 128, 122, 124, 140, 118, 128, 127, 134, 124, 131, 120, 136, 129, 125, 122, 131, 131, 128, 121, 129, 134, 128, 124, 125, 139, 120, 134, 124, 127, 134, 124, 125, 124, 138, 124, 115, 145, 113, 131, 137, 116, 128, 126, 140, 103, 133, 133, 108, 138, 124, 114, 124, 139, 116, 122, 145, 124, 124, 146, 117, 134, 145, 120, 128, 132, 148, 116, 137, 135, 133, 132, 125, 140, 133, 135, 127, 147, 114, 136, 138, 114, 130, 125, 133, 107, 131, 130, 98, 135, 115, 113, 117, 107, 114, 104, 113,
+};
+
+const unsigned char zero[] PROGMEM = {
+123, 124, 123, 121, 122, 122, 121, 119, 117, 117, 117, 117, 114, 111, 112, 113, 112, 111, 111, 112, 116, 123, 134, 146, 154, 164, 176, 184, 189, 192, 194, 196, 197, 195, 189, 183, 175, 167, 156, 144, 132, 122, 113, 103, 95, 88, 86, 86, 86, 88, 88, 90, 92, 93, 93, 94, 96, 97, 98, 99, 98, 101, 98, 97, 99, 96, 93, 89, 88, 83, 80, 75, 75, 77, 80, 98, 113, 114, 128, 148, 165, 180, 192, 199, 213, 228, 228, 229, 229, 226, 224, 215, 197, 183, 174, 161, 144, 129, 116, 109, 105, 97, 92, 94, 99, 104, 108, 111, 120, 129, 134, 137, 138, 140, 141, 138, 131, 127, 125, 125, 118, 112, 107, 108, 105, 97, 99, 95, 101, 95, 97, 90, 92, 92, 83, 80, 73, 72, 67, 68, 60, 62, 59, 65, 70, 88, 104, 107, 123, 142, 162, 178, 193, 204, 222, 238, 241, 240, 240, 235, 230, 222, 206, 190, 177, 162, 145, 128, 115, 102, 101, 94, 93, 90, 95, 95, 105, 107, 115, 122, 131, 135, 136, 142, 141, 145, 138, 139, 131, 135, 123, 128, 112, 121, 103, 110, 100, 104, 101, 98, 101, 89, 100, 81, 93, 73, 87, 65, 82, 57, 74, 62, 60, 69, 54, 74, 74, 94, 97, 119, 128, 158, 166, 190, 196, 218, 231, 239, 240, 242, 241, 236, 230, 211, 198, 181, 167, 147, 136, 120, 114, 106, 100, 95, 93, 96, 102, 105, 116, 115, 127, 125, 132, 130, 133, 130, 131, 129, 125, 127, 122, 125, 117, 122, 113, 115, 106, 111, 102, 104, 98, 93, 90, 93, 83, 85, 85, 79, 86, 75, 83, 81, 81, 85, 79, 85, 94, 83, 98, 101, 126, 126, 140, 148, 157, 173, 183, 187, 192, 212, 210, 216, 204, 207, 200, 201, 182, 175, 166, 162, 147, 144, 133, 128, 129, 120, 118, 113, 121, 109, 123, 114, 123, 121, 122, 121, 122, 121, 124, 122, 125, 122, 119, 127, 115, 120, 115, 115, 116, 115, 105, 112, 101, 108, 100, 95, 101, 100, 101, 101, 95, 102, 102, 97, 89, 98, 103, 98, 106, 100, 107, 97, 110, 93, 113, 122, 129, 125, 140, 144, 151, 162, 158, 173, 173, 194, 172, 193, 182, 189, 186, 178, 165, 175, 165, 149, 149, 139, 146, 135, 129, 116, 130, 121, 130, 111, 125, 129, 128, 131, 117, 126, 135, 122, 130, 117, 117, 132, 119, 116, 108, 122, 121, 128, 93, 120, 114, 128, 100, 96, 124, 108, 107, 94, 91, 113, 109, 81, 108, 90, 114, 87, 104, 79, 109, 80, 97, 76, 87, 97, 63, 122, 61, 118, 59, 141, 104, 121, 135, 139, 177, 159, 188, 159, 233, 193, 208, 208, 228, 199, 208, 201, 173, 196, 166, 150, 148, 149, 120, 135, 120, 124, 120, 124, 127, 121, 145, 125, 143, 146, 149, 140, 149, 143, 137, 130, 113, 124, 82, 117, 67, 94, 83, 50, 103, 56, 72, 56, 72, 68, 34, 83, 28, 40, 53, 19, 35, 34, 116, 65, 110, 144, 156, 195, 184, 226, 220, 255, 233, 240, 250, 223, 228, 198, 189, 168, 153, 146, 112, 127, 111, 107, 109, 111, 116, 111, 130, 129, 145, 148, 159, 161, 165, 157, 167, 160, 132, 139, 129, 108, 102, 84, 68, 76, 57, 53, 49, 41, 58, 47, 29, 41, 54, 22, 0, 24, 33, 44, 68, 57, 101, 174, 130, 141, 231, 235, 207, 241, 255, 250, 239, 232, 221, 211, 190, 151, 145, 143, 114, 92, 107, 106, 91, 105, 119, 135, 149, 162, 181, 206, 218, 204, 205, 223, 199, 167, 163, 138, 106, 80, 51, 33, 8, 5, 6, 0, 0, 4, 0, 0, 0, 4, 32, 130, 98, 45, 217, 246, 142, 178, 255, 255, 209, 217, 220, 218, 201, 149, 134, 163, 137, 79, 91, 122, 111, 90, 107, 145, 164, 161, 181, 214, 218, 220, 222, 207, 192, 187, 160, 126, 110, 84, 51, 26, 23, 5, 0, 0, 0, 0, 0, 0, 0, 73, 149, 129, 108, 211, 255, 232, 216, 221, 244, 233, 203, 169, 141, 135, 131, 90, 62, 73, 86, 97, 90, 112, 166, 188, 192, 216, 237, 232, 226, 215, 190, 156, 139, 127, 91, 50, 34, 19, 0, 0, 0, 0, 0, 0, 0, 9, 152, 182, 81, 138, 255, 255, 209, 196, 251, 246, 183, 181, 152, 83, 94, 119, 76, 40, 75, 122, 122, 128, 184, 208, 191, 226, 255, 233, 186, 183, 187, 148, 93, 74, 66, 39, 23, 11, 0, 0, 9, 10, 0, 0, 12, 132, 196, 137, 129, 223, 255, 255, 208, 197, 205, 192, 185, 160, 87, 46, 88, 119, 81, 58, 102, 143, 156, 192, 224, 210, 203, 237, 249, 197, 151, 149, 132, 98, 77, 65, 42, 13, 19, 30, 8, 0, 0, 6, 3, 22, 94, 161, 171, 167, 194, 235, 252, 241, 226, 208, 175, 156, 163, 139, 88, 63, 68, 86, 96, 103, 138, 174, 184, 193, 227, 255, 241, 200, 168, 145, 122, 101, 88, 65, 23, 7, 19, 19, 10, 0, 0, 0, 15, 90, 191, 204, 158, 163, 215, 255, 252, 223, 204, 167, 139, 151, 139, 89, 64, 69, 79, 88, 114, 159, 181, 182, 204, 228, 229, 212, 191, 174, 133, 91, 87, 84, 63, 40, 23, 20, 14, 1, 0, 0, 0, 33, 144, 208, 190, 174, 199, 225, 224, 225, 228, 192, 139, 126, 132, 113, 87, 78, 88, 102, 116, 147, 181, 200, 210, 214, 214, 199, 171, 150, 129, 106, 81, 50, 33, 35, 33, 26, 17, 4, 0, 0, 23, 117, 198, 212, 194, 189, 201, 209, 212, 220, 201, 151, 118, 121, 120, 100, 88, 100, 120, 129, 143, 172, 199, 212, 213, 206, 196, 170, 138, 118, 104, 85, 62, 40, 24, 6, 0, 0, 7, 9, 3, 37, 125, 196, 208, 206, 219, 220, 205, 204, 221, 207, 156, 119, 109, 99, 91, 101, 122, 136, 147, 166, 193, 212, 212, 201, 194, 173, 138, 110, 89, 62, 36, 19, 8, 0, 0, 0, 0, 0, 22, 106, 187, 216, 219, 221, 227, 215, 193, 203, 209, 172, 130, 113, 108, 96, 93, 121, 146, 154, 167, 191, 206, 203, 198, 195, 173, 134, 105, 81, 53, 28, 15, 13, 3, 0, 0, 0, 0, 37, 145, 218, 222, 210, 213, 220, 211, 207, 218, 203, 155, 119, 111, 107, 99, 106, 130, 152, 168, 187, 205, 206, 191, 184, 178, 150, 111, 78, 52, 29, 14, 8, 3, 0, 0, 0, 0, 32, 137, 215, 233, 222, 210, 211, 209, 210, 218, 200, 155, 119, 104, 101, 103, 111, 129, 156, 177, 189, 200, 206, 198, 181, 167, 148, 113, 76, 45, 28, 22, 15, 6, 0, 0, 0, 0, 52, 167, 228, 224, 216, 216, 210, 201, 207, 216, 189, 136, 108, 101, 96, 97, 116, 147, 171, 187, 202, 209, 203, 191, 180, 161, 126, 89, 52, 19, 5, 3, 1, 0, 0, 0, 0, 41, 166, 248, 255, 238, 221, 203, 189, 192, 205, 186, 132, 101, 100, 96, 101, 134, 170, 185, 192, 206, 207, 182, 164, 160, 141, 106, 77, 41, 2, 0, 5, 13, 6, 0, 0, 0, 59, 201, 255, 255, 244, 218, 179, 156, 175, 192, 160, 122, 116, 104, 89, 121, 166, 184, 198, 219, 222, 194, 166, 155, 132, 107, 95, 68, 23, 0, 0, 7, 7, 8, 4, 0, 0, 121, 235, 255, 255, 240, 189, 150, 160, 190, 171, 133, 131, 118, 92, 118, 166, 182, 194, 218, 217, 190, 166, 152, 130, 110, 107, 73, 23, 8, 6, 5, 15, 24, 9, 0, 0, 110, 214, 247, 255, 243, 173, 146, 162, 180, 172, 155, 143, 112, 91, 120, 149, 169, 205, 221, 209, 195, 172, 144, 121, 115, 110, 83, 55, 34, 9, 1, 25, 24, 3, 0, 0, 40, 166, 233, 255, 255, 202, 157, 143, 153, 166, 164, 165, 140, 107, 114, 129, 146, 180, 212, 216, 200, 179, 154, 130, 116, 108, 94, 79, 58, 38, 23, 18, 20, 12, 2, 0, 5, 93, 169, 229, 255, 245, 193, 155, 135, 137, 151, 179, 167, 140, 140, 122, 130, 159, 181, 209, 210, 196, 176, 136, 120, 105, 91, 89, 74, 61, 40, 22, 20, 10, 11, 15, 0, 26, 108, 163, 230, 255, 240, 192, 160, 138, 131, 157, 180, 172, 162, 143, 127, 132, 151, 171, 196, 206, 195, 173, 149, 126, 100, 86, 71, 61, 51, 42, 37, 29, 33, 24, 18, 1, 0, 83, 139, 201, 255, 255, 232, 194, 163, 123, 137, 153, 157, 167, 157, 140, 121, 142, 152, 174, 199, 195, 186, 170, 143, 113, 105, 84, 77, 67, 58, 53, 42, 36, 17, 15, 10, 0, 11, 75, 131, 197, 253, 255, 232, 193, 154, 128, 146, 161, 169, 170, 156, 137, 131, 142, 152, 174, 190, 191, 185, 170, 146, 132, 112, 84, 71, 53, 44, 46, 48, 45, 40, 26, 0, 0, 3, 65, 124, 202, 252, 255, 239, 200, 154, 127, 136, 143, 165, 175, 167, 155, 147, 141, 144, 158, 168, 175, 181, 176, 166, 150, 131, 108, 84, 56, 41, 45, 48, 59, 52, 46, 18, 1, 0, 2, 66, 116, 200, 241, 255, 236, 204, 162, 137, 139, 137, 163, 165, 166, 163, 155, 147, 143, 157, 153, 168, 176, 168, 174, 164, 149, 126, 99, 64, 41, 34, 28, 46, 51, 60, 55, 42, 11, 0, 34, 56, 130, 195, 236, 255, 241, 211, 157, 147, 127, 136, 157, 159, 166, 167, 155, 147, 156, 154, 157, 170, 166, 164, 161, 150, 140, 124, 106, 79, 59, 38, 28, 36, 45, 52, 54, 54, 37, 21, 33, 56, 99, 158, 211, 240, 249, 232, 200, 174, 147, 135, 133, 139, 143, 152, 156, 158, 163, 164, 164, 163, 160, 153, 147, 138, 133, 123, 115, 102, 80, 62, 42, 34, 29, 35, 40, 47, 41, 29, 49, 58, 97, 147, 192, 223, 244, 239, 212, 200, 163, 151, 139, 129, 128, 128, 133, 132, 150, 150, 166, 173, 174, 173, 162, 155, 139, 133, 117, 113, 98, 83, 70, 51, 42, 34, 35, 34, 43, 46, 44, 55, 71, 89, 124, 163, 194, 224, 235, 228, 213, 191, 166, 147, 134, 125, 125, 126, 131, 142, 150, 161, 167, 166, 161, 152, 139, 129, 124, 119, 118, 120, 115, 110, 96, 80, 63, 45, 34, 26, 31, 35, 46, 48, 65, 82, 99, 135, 161, 192, 211, 224, 215, 207, 192, 166, 155, 138, 132, 130, 132, 133, 139, 146, 146, 154, 158, 158, 160, 157, 151, 146, 141, 130, 123, 113, 101, 94, 88, 82, 80, 76, 72, 68, 63, 55, 50, 53, 51, 60, 68, 91, 113, 138, 168, 189, 211, 215, 219, 205, 192, 174, 158, 146, 135, 134, 129, 132, 134, 141, 148, 153, 156, 159, 158, 151, 143, 132, 121, 111, 104, 99, 101, 104, 111, 118, 120, 121, 113, 103, 88, 76, 61, 54, 52, 48, 52, 50, 46, 47, 52, 53, 71, 92, 120, 154, 188, 213, 232, 247, 244, 243, 229, 211, 190, 167, 146, 126, 115, 106, 107, 111, 119, 129, 138, 146, 150, 155, 153, 151, 146, 137, 131, 123, 115, 109, 109, 108, 113, 118, 122, 125, 123, 119, 111, 100, 87, 79, 69, 64, 61, 64, 65, 67, 66, 59, 52, 47, 53, 53, 70, 91, 118, 153, 185, 210, 229, 242, 240, 237, 224, 206, 187, 166, 148, 132, 124, 118, 119, 123, 129, 138, 145, 151, 156, 157, 154, 150, 142, 134, 128, 123, 119, 119, 120,
+};
+
+const unsigned char one[] PROGMEM = {
+168, 161, 152, 142, 132, 126, 122, 121, 123, 125, 125, 124, 119, 112, 104, 97, 88, 78, 69, 56, 42, 32, 22, 15, 16, 20, 22, 25, 33, 53, 69, 84, 112, 138, 160, 182, 194, 201, 203, 200, 194, 189, 182, 174, 172, 169, 167, 165, 164, 167, 170, 172, 174, 173, 169, 162, 154, 144, 135, 129, 124, 123, 123, 124, 124, 123, 120, 115, 109, 101, 91, 82, 71, 59, 47, 35, 26, 23, 23, 24, 25, 25, 25, 38, 56, 72, 98, 127, 153, 177, 195, 205, 206, 203, 195, 185, 176, 167, 163, 162, 164, 166, 168, 169, 171, 174, 177, 177, 177, 174, 167, 159, 149, 138, 131, 125, 123, 123, 124, 123, 119, 113, 104, 94, 82, 72, 60, 46, 31, 16, 3, 0, 0, 0, 0, 0, 0, 0, 31, 63, 107, 161, 197, 221, 234, 228, 211, 201, 192, 186, 186, 184, 181, 179, 177, 172, 168, 176, 184, 196, 208, 207, 201, 186, 165, 144, 129, 121, 119, 122, 123, 119, 112, 102, 90, 81, 73, 60, 49, 33, 9, 0, 0, 0, 0, 0, 0, 0, 0, 15, 50, 96, 161, 210, 232, 246, 241, 219, 206, 196, 195, 194, 192, 188, 177, 170, 162, 159, 174, 193, 210, 226, 223, 209, 190, 164, 140, 125, 121, 123, 126, 125, 118, 106, 94, 85, 81, 75, 58, 33, 4, 0, 0, 0, 0, 0, 0, 0, 0, 34, 64, 97, 165, 214, 232, 241, 236, 204, 185, 181, 181, 187, 192, 190, 181, 171, 160, 152, 172, 198, 219, 235, 233, 213, 181, 156, 132, 121, 126, 128, 130, 124, 109, 104, 99, 97, 94, 73, 42, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 143, 235, 255, 255, 216, 185, 150, 147, 183, 212, 225, 204, 176, 146, 126, 132, 160, 206, 233, 249, 242, 216, 181, 151, 142, 137, 135, 136, 133, 126, 114, 111, 112, 108, 98, 75, 45, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 167, 226, 255, 244, 178, 143, 170, 186, 211, 245, 222, 171, 132, 123, 144, 183, 194, 189, 193, 186, 195, 206, 208, 200, 170, 150, 131, 125, 132, 130, 128, 117, 112, 105, 105, 102, 75, 39, 2, 0, 7, 12, 6, 0, 0, 0, 0, 0, 4, 156, 163, 174, 199, 195, 193, 211, 238, 209, 191, 190, 164, 172, 172, 162, 168, 169, 172, 191, 200, 204, 220, 211, 191, 182, 172, 156, 144, 135, 131, 130, 127, 117, 104, 98, 98, 85, 57, 34, 15, 10, 16, 5, 0, 0, 0, 0, 0, 0, 0, 135, 171, 135, 177, 178, 173, 211, 223, 227, 216, 210, 216, 195, 190, 176, 145, 161, 170, 172, 202, 196, 188, 209, 211, 200, 186, 162, 147, 144, 145, 142, 131, 124, 122, 113, 100, 88, 65, 36, 26, 23, 3, 0, 0, 0, 0, 0, 0, 0, 0, 27, 176, 111, 66, 185, 218, 219, 253, 208, 196, 238, 241, 222, 180, 154, 167, 180, 189, 178, 161, 172, 185, 192, 200, 198, 181, 173, 175, 160, 142, 139, 138, 134, 127, 119, 114, 108, 94, 78, 60, 34, 32, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 149, 67, 59, 171, 202, 167, 179, 197, 204, 213, 210, 206, 194, 184, 202, 208, 188, 180, 187, 186, 180, 180, 182, 180, 176, 173, 165, 155, 149, 146, 143, 138, 134, 132, 127, 118, 110, 100, 85, 69, 52, 33, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 18, 47, 105, 134, 143, 156, 172, 192, 209, 214, 219, 230, 235, 236, 235, 222, 208, 203, 197, 186, 180, 179, 173, 171, 169, 164, 158, 154, 150, 146, 143, 139, 136, 133, 129, 123, 118, 109, 97, 88, 72, 59, 47, 32, 15, 0, 0, 0, 0, 0, 0, 0, 0, 4, 27, 23, 55, 117, 138, 136, 162, 177, 184, 202, 225, 226, 230, 239, 245, 245, 226, 206, 204, 196, 177, 172, 171, 165, 166, 171, 157, 148, 153, 149, 142, 140, 139, 134, 133, 131, 125, 124, 114, 104, 100, 83, 69, 61, 52, 27, 5, 0, 0, 0, 0, 0, 0, 0, 0, 21, 28, 44, 86, 122, 133, 149, 174, 192, 205, 222, 234, 235, 238, 243, 240, 226, 211, 204, 199, 187, 177, 173, 169, 168, 166, 159, 153, 153, 148, 144, 143, 139, 136, 134, 128, 125, 119, 110, 103, 96, 80, 67, 57, 47, 38, 29, 18, 10, 2, 0, 0, 0, 0, 0, 0, 12, 8, 31, 83, 100, 118, 148, 169, 179, 203, 227, 242, 240, 254, 244, 255, 253, 191, 214, 198, 198, 184, 177, 177, 164, 163, 156, 159, 144, 149, 145, 142, 136, 136, 132, 129, 122, 118, 112, 104, 95, 83, 74, 67, 54, 41, 39, 27, 12, 1, 0, 0, 0, 0, 0, 3, 15, 22, 51, 98, 107, 128, 159, 177, 191, 222, 241, 240, 250, 255, 255, 250, 243, 228, 217, 210, 199, 193, 186, 177, 170, 169, 167, 157, 153, 155, 149, 144, 140, 138, 136, 131, 127, 123, 118, 114, 109, 103, 98, 92, 87, 81, 76, 72, 67, 64, 60, 57, 53, 52, 48, 49, 50, 49, 47, 55, 65, 70, 78, 88, 98, 107, 118, 119, 126, 132, 137, 140, 142, 150, 151, 151, 149, 153, 158, 159, 157, 157, 160, 161, 160, 158, 155, 156, 157, 156, 152, 148, 149, 149, 145, 141, 138, 136, 134, 133, 131, 130, 128, 127, 126, 124, 122, 122, 120, 118, 116, 115, 115, 115,
+};
+
+const unsigned char two[] PROGMEM = {
+104, 107, 113, 113, 115, 120, 120, 121, 125, 127, 122, 122, 130, 134, 129, 126, 129, 130, 126, 126, 130, 131, 130, 132, 135, 137, 139, 137, 133, 134, 137, 135, 132, 129, 130, 132, 131, 128, 125, 127, 128, 130, 129, 130, 132, 135, 133, 130, 131, 133, 133, 134, 134, 136, 135, 135, 134, 134, 131, 127, 127, 128, 126, 123, 125, 127, 129, 126, 125, 125, 129, 125, 126, 125, 128, 125, 128, 125, 127, 125, 126, 124, 124, 126, 126, 132, 126, 129, 123, 133, 126, 140, 128, 147, 114, 212, 212, 75, 161, 113, 146, 186, 160, 119, 144, 85, 110, 149, 82, 148, 106, 186, 140, 114, 84, 101, 84, 83, 103, 91, 141, 84, 133, 112, 100, 118, 141, 82, 188, 62, 166, 108, 72, 207, 32, 229, 46, 189, 109, 120, 167, 99, 184, 16, 131, 37, 118, 50, 148, 63, 111, 134, 76, 197, 56, 236, 72, 214, 97, 148, 161, 86, 186, 58, 213, 16, 194, 48, 122, 119, 41, 198, 46, 205, 53, 204, 111, 140, 171, 76, 209, 107, 181, 101, 191, 96, 142, 122, 108, 172, 54, 178, 80, 171, 101, 167, 130, 82, 191, 85, 177, 122, 150, 128, 124, 125, 103, 167, 76, 141, 139, 109, 141, 87, 156, 144, 100, 121, 126, 115, 181, 59, 115, 192, 117, 111, 148, 173, 104, 162, 77, 141, 115, 120, 125, 92, 165, 104, 108, 134, 116, 139, 146, 111, 131, 147, 135, 80, 161, 142, 140, 139, 77, 173, 121, 85, 120, 136, 150, 120, 115, 131, 126, 84, 132, 144, 128, 74, 151, 144, 89, 169, 133, 143, 104, 177, 97, 118, 144, 79, 161, 98, 114, 129, 128, 118, 111, 153, 130, 152, 152, 123, 155, 110, 141, 123, 104, 133, 138, 126, 96, 128, 116, 106, 106, 117, 136, 128, 105, 147, 175, 108, 108, 184, 153, 97, 127, 161, 130, 112, 106, 139, 167, 109, 104, 138, 156, 104, 105, 150, 142, 130, 107, 150, 176, 117, 125, 138, 135, 85, 110, 135, 64, 127, 112, 108, 96, 90, 137, 127, 121, 96, 158, 154, 97, 123, 161, 158, 123, 113, 185, 184, 118, 118, 148, 158, 107, 104, 109, 151, 150, 92, 120, 161, 150, 110, 133, 148, 145, 134, 95, 129, 154, 119, 101, 142, 155, 140, 132, 126, 176, 167, 119, 144, 180, 157, 132, 137, 132, 126, 113, 90, 108, 109, 82, 61, 60, 76, 56, 44, 52, 65, 57, 35, 40, 78, 62, 11, 29, 83, 59, 4, 13, 48, 73, 55, 61, 101, 164, 176, 179, 232, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 239, 197, 205, 195, 156, 126, 119, 127, 112, 81, 71, 92, 93, 67, 55, 72, 85, 63, 43, 47, 58, 45, 13, 0, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 36, 103, 195, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 212, 188, 188, 180, 166, 155, 151, 159, 161, 158, 153, 159, 161, 152, 144, 138, 131, 115, 96, 78, 55, 32, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 76, 83, 164, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 222, 206, 183, 157, 137, 138, 141, 145, 157, 166, 173, 176, 185, 191, 187, 186, 185, 180, 165, 146, 126, 89, 42, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 103, 117, 114, 180, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 214, 176, 155, 141, 134, 123, 122, 129, 143, 157, 165, 172, 174, 186, 193, 193, 190, 189, 184, 173, 151, 122, 83, 46, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 67, 113, 154, 222, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 237, 205, 172, 142, 113, 103, 110, 116, 116, 122, 132, 141, 154, 167, 175, 179, 185, 191, 192, 190, 183, 164, 132, 95, 59, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 78, 112, 173, 243, 255, 255, 255, 255, 255, 255, 255, 255, 255, 237, 204, 183, 163, 130, 102, 91, 95, 104, 111, 120, 126, 131, 139, 153, 169, 177, 178, 179, 184, 184, 178, 164, 139, 102, 63, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 82, 149, 219, 255, 255, 255, 255, 255, 255, 255, 255, 255, 241, 206, 179, 151, 122, 98, 90, 95, 101, 107, 114, 121, 133, 147, 157, 167, 178, 180, 183, 184, 183, 177, 158, 127, 86, 46, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 70, 141, 196, 254, 255, 255, 255, 255, 255, 255, 255, 255, 250, 210, 180, 154, 124, 97, 85, 86, 92, 97, 104, 109, 119, 133, 145, 156, 165, 174, 180, 185, 188, 189, 185, 166, 137, 104, 65, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 68, 137, 199, 255, 255, 255, 255, 255, 255, 255, 255, 255, 217, 189, 169, 140, 99, 80, 84, 93, 103, 108, 114, 126, 146, 158, 170, 177, 182, 192, 196, 194, 191, 185, 155, 114, 77, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 67, 115, 175, 236, 255, 255, 255, 255, 255, 255, 255, 255, 233, 189, 151, 133, 111, 83, 70, 82, 96, 117, 133, 143, 160, 176, 187, 194, 195, 192, 190, 191, 185, 178, 166, 141, 110, 78, 42, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 138, 150, 185, 236, 255, 255, 255, 255, 255, 255, 255, 228, 194, 178, 160, 148, 146, 130, 112, 116, 145, 165, 171, 170, 173, 189, 198, 194, 182, 172, 171, 173, 168, 153, 138, 131, 110, 79, 62, 44, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 108, 148, 146, 156, 186, 233, 255, 240, 216, 216, 245, 253, 228, 190, 179, 186, 186, 176, 161, 152, 155, 180, 193, 183, 179, 186, 192, 188, 175, 164, 160, 160, 150, 137, 127, 122, 114, 100, 92, 86, 75, 62, 53, 52, 46, 36, 24, 20, 20, 28, 30, 23, 15, 38, 56, 38, 19, 22, 50, 68, 70, 72, 101, 126, 138, 147, 161, 189, 207, 214, 217, 227, 248, 255, 240, 228, 226, 230, 225, 208, 190, 191, 200, 197, 186, 176, 177, 179, 170, 163, 157, 158, 155, 141, 133, 128, 124, 114, 107, 97, 86, 89, 84, 67, 58, 58, 60, 51, 43, 49, 65, 73, 75, 74, 75, 101, 118, 114, 114, 137, 149, 153, 149, 152, 171, 174, 177, 181, 180, 171, 174, 177, 178, 169, 161, 163, 170, 172, 156, 140, 137, 151, 148, 126, 111, 115, 118, 110, 91, 95, 92, 87, 105, 96, 89, 95, 107, 98, 99, 98, 107, 115, 88, 95, 134, 127, 106, 111, 118, 140, 144, 130, 126, 122, 137, 158, 149, 130, 141, 151, 165, 174, 146, 140, 148, 164, 163, 140, 131, 135, 147, 154, 132, 115, 118, 131, 141, 122, 103, 112, 134, 137, 119, 105, 116, 123, 123, 119, 107, 110, 127, 123, 114, 119, 122, 130, 122, 117, 128, 126, 121, 127, 133, 126, 126,
+};
+
+const unsigned char three[] PROGMEM = {
+131, 129, 126, 130, 123, 128, 128, 127, 124, 130, 128, 129, 134, 124, 130, 127, 125, 127, 127, 128, 129, 125, 128, 127, 127, 127, 126, 128, 124, 130, 126, 127, 127, 129, 127, 127, 127, 127, 126, 125, 128, 126, 125, 128, 129, 127, 126, 124, 129, 127, 128, 128, 127, 128, 130, 125, 129, 128, 128, 129, 128, 127, 123, 130, 123, 124, 134, 133, 120, 131, 128, 125, 124, 126, 127, 127, 130, 124, 130, 129, 130, 125, 128, 131, 131, 129, 131, 127, 127, 132, 124, 127, 126, 126, 130, 124, 126, 131, 128, 124, 125, 130, 133, 128, 123, 122, 130, 129, 123, 120, 129, 131, 124, 128, 128, 129, 127, 135, 128, 119, 114, 119, 130, 115, 127, 127, 122, 136, 128, 123, 115, 129, 124, 129, 124, 124, 130, 131, 132, 115, 124, 132, 135, 126, 142, 131, 134, 137, 159, 128, 114, 135, 133, 118, 111, 126, 106, 133, 126, 123, 111, 144, 145, 138, 135, 141, 140, 125, 128, 114, 123, 107, 133, 115, 113, 120, 131, 114, 120, 136, 128, 137, 131, 136, 123, 153, 134, 120, 123, 131, 126, 119, 123, 125, 129, 120, 132, 120, 126, 133, 149, 130, 128, 134, 125, 121, 125, 119, 116, 131, 126, 138, 127, 138, 125, 132, 122, 117, 130, 124, 127, 127, 130, 120, 138, 123, 137, 131, 116, 128, 136, 125, 120, 129, 123, 136, 126, 121, 127, 139, 128, 124, 125, 126, 129, 125, 132, 128, 133, 131, 137, 129, 116, 135, 116, 120, 125, 118, 117, 122, 132, 117, 130, 129, 131, 130, 134, 123, 120, 144, 133, 130, 125, 144, 141, 133, 133, 134, 139, 125, 143, 138, 140, 140, 140, 141, 128, 135, 129, 138, 132, 125, 129, 124, 125, 118, 111, 122, 116, 118, 99, 103, 133, 110, 98, 107, 104, 92, 105, 115, 91, 84, 105, 107, 98, 83, 104, 122, 120, 118, 119, 151, 157, 153, 164, 172, 172, 176, 173, 174, 173, 163, 162, 165, 159, 147, 143, 144, 140, 135, 130, 132, 131, 127, 126, 124, 123, 119, 117, 116, 113, 108, 108, 104, 98, 97, 92, 89, 94, 95, 91, 91, 96, 95, 87, 87, 97, 91, 76, 76, 102, 130, 136, 133, 131, 147, 163, 171, 175, 171, 177, 183, 180, 174, 163, 157, 156, 148, 142, 134, 134, 133, 128, 128, 131, 133, 135, 134, 132, 134, 135, 132, 131, 131, 133, 131, 133, 135, 136, 136, 135, 135, 136, 138, 137, 132, 129, 127, 124, 120, 111, 107, 100, 94, 90, 89, 88, 80, 72, 67, 64, 59, 54, 49, 59, 83, 111, 129, 137, 140, 141, 149, 164, 181, 194, 202, 202, 195, 184, 172, 161, 154, 150, 146, 138, 126, 114, 110, 113, 121, 126, 129, 129, 128, 126, 127, 131, 138, 143, 146, 148, 149, 147, 145, 143, 141, 141, 140, 138, 132, 124, 117, 110, 104, 99, 94, 89, 83, 74, 66, 58, 51, 42, 30, 27, 38, 67, 105, 136, 148, 145, 141, 148, 171, 198, 216, 220, 212, 201, 186, 172, 159, 153, 147, 136, 118, 99, 91, 95, 106, 113, 116, 119, 125, 135, 145, 153, 159, 162, 165, 165, 163, 159, 148, 136, 128, 128, 134, 137, 132, 120, 108, 98, 93, 91, 90, 85, 70, 53, 43, 39, 30, 15, 21, 60, 120, 159, 151, 128, 129, 174, 222, 238, 218, 190, 182, 187, 188, 174, 154, 137, 119, 103, 94, 97, 107, 110, 107, 107, 119, 136, 150, 155, 154, 157, 166, 175, 176, 164, 147, 134, 131, 132, 131, 127, 120, 116, 116, 121, 118, 105, 91, 82, 79, 75, 66, 52, 33, 14, 1, 19, 70, 127, 150, 123, 109, 143, 214, 253, 225, 181, 173, 210, 228, 195, 148, 126, 131, 130, 112, 97, 91, 95, 100, 107, 118, 128, 134, 141, 151, 160, 164, 164, 167, 165, 156, 148, 147, 144, 129, 113, 116, 132, 133, 119, 112, 122, 123, 111, 101, 107, 105, 84, 67, 68, 61, 38, 8, 38, 116, 111, 64, 76, 179, 214, 144, 128, 199, 255, 196, 150, 184, 210, 178, 127, 127, 134, 116, 95, 90, 101, 102, 104, 112, 125, 141, 148, 157, 162, 166, 169, 164, 162, 159, 154, 139, 127, 129, 126, 121, 115, 120, 121, 118, 116, 112, 106, 100, 99, 94, 82, 72, 58, 46, 27, 32, 103, 95, 53, 82, 172, 192, 120, 142, 213, 229, 178, 175, 220, 200, 160, 150, 157, 140, 110, 105, 103, 100, 95, 100, 110, 118, 130, 138, 147, 154, 161, 163, 160, 162, 161, 154, 144, 138, 136, 130, 126, 124, 126, 121, 117, 114, 110, 103, 101, 96, 84, 76, 73, 56, 45, 27, 55, 110, 59, 66, 138, 162, 119, 133, 211, 194, 169, 190, 218, 194, 166, 179, 177, 151, 131, 130, 128, 110, 101, 106, 108, 105, 107, 120, 123, 131, 140, 145, 149, 157, 163, 160, 161, 161, 155, 144, 143, 141, 132, 127, 127, 121, 116, 104, 102, 96, 89, 86, 80, 77, 74, 58, 58, 42, 56, 114, 48, 79, 151, 126, 106, 162, 194, 148, 180, 200, 201, 180, 183, 198, 170, 154, 153, 149, 123, 115, 120, 110, 103, 107, 115, 111, 121, 134, 136, 144, 153, 158, 159, 165, 160, 156, 152, 146, 139, 135, 131, 123, 118, 109, 107, 100, 85, 95, 85, 77, 74, 71, 67, 55, 44, 55, 110, 60, 65, 146, 131, 104, 151, 188, 152, 173, 198, 198, 181, 184, 199, 175, 157, 164, 158, 126, 128, 129, 113, 104, 114, 116, 111, 121, 133, 135, 141, 155, 157, 155, 162, 162, 148, 150, 145, 136, 130, 127, 115, 109, 102, 95, 86, 83, 79, 70, 69, 68, 60, 54, 48, 53, 112, 56, 77, 149, 111, 112, 164, 175, 141, 187, 198, 189, 182, 199, 200, 173, 169, 177, 158, 131, 145, 134, 112, 116, 123, 108, 112, 128, 129, 128, 149, 154, 149, 156, 163, 151, 147, 151, 144, 129, 130, 128, 109, 101, 98, 86, 76, 76, 66, 66, 59, 61, 52, 51, 39, 92, 81, 52, 137, 125, 106, 151, 178, 142, 176, 199, 185, 188, 195, 199, 179, 179, 174, 168, 144, 146, 141, 120, 118, 127, 113, 111, 124, 127, 129, 138, 148, 150, 151, 156, 160, 147, 151, 153, 137, 130, 141, 117, 108, 109, 97, 79, 84, 74, 65, 61, 61, 54, 49, 48, 45, 101, 55, 82, 135, 107, 112, 167, 157, 142, 191, 188, 183, 185, 205, 186, 181, 178, 177, 157, 147, 151, 130, 122, 126, 124, 114, 125, 130, 133, 140, 151, 154, 151, 157, 163, 152, 153, 156, 138, 135, 135, 119, 105, 104, 92, 77, 76, 70, 59, 53, 61, 47, 47, 40, 84, 78, 49, 128, 118, 96, 144, 165, 139, 167, 195, 176, 185, 198, 193, 181, 180, 178, 165, 149, 154, 143, 121, 128, 129, 110, 119, 133, 128, 132, 151, 148, 146, 161, 160, 151, 154, 156, 139, 135, 135, 113, 103, 103, 87, 76, 73, 69, 56, 54, 57, 51, 40, 69, 90, 57, 99, 130, 102, 125, 165, 146, 150, 189, 181, 170, 190, 192, 174, 176, 174, 168, 152, 147, 150, 131, 123, 134, 134, 121, 133, 146, 140, 143, 155, 156, 149, 153, 159, 147, 139, 146, 133, 118, 113, 104, 90, 80, 72, 69, 63, 57, 58, 59, 54, 56, 54, 85, 104, 71, 112, 148, 121, 123, 170, 164, 150, 184, 193, 181, 178, 186, 185, 171, 161, 174, 156, 141, 146, 143, 133, 126, 143, 138, 137, 151, 152, 149, 153, 157, 147, 142, 146, 135, 124, 128, 113, 102, 101, 90, 87, 81, 75, 74, 72, 67, 66, 68, 63, 66, 64, 79, 109, 89, 97, 140, 137, 121, 148, 169, 150, 156, 175, 171, 163, 167, 166, 161, 156, 152, 146, 141, 141, 136, 137, 136, 137, 136, 135, 139, 141, 139, 134, 133, 132, 135, 127, 124, 126, 121, 122, 124, 125, 123, 123, 122, 122, 125, 128, 127, 123, 124, 128, 126, 126, 127, 126, 128, 128, 127, 129, 128, 129, 126, 126, 130, 132, 126, 126, 129, 124, 129, 128, 129, 126, 126, 128, 127, 130, 126, 125, 127, 129, 128, 125, 125, 127, 129, 127, 128, 126, 125, 128, 124, 128, 129, 125, 126, 126, 125, 129, 129, 127, 129, 129, 128, 127, 127, 128, 129, 125, 127, 128, 128, 129, 129, 127, 127, 128, 130, 129, 125, 127, 130, 129, 126, 128, 128, 126, 129, 127, 124, 127, 129, 128, 127, 127, 129, 129, 125, 128, 132, 126, 127, 129, 126, 129, 127, 126, 130, 126, 129, 130, 126, 130, 129, 125, 129, 130, 128, 128, 125, 126, 130, 132, 125, 127, 130, 127, 128, 127, 126,
+};
+
+const unsigned char four[] PROGMEM = {
+125, 128, 125, 128, 127, 128, 130, 130, 124, 124, 129, 130, 130, 127, 127, 130, 125, 126, 129, 129, 130, 128, 129, 127, 129, 125, 125, 130, 129, 127, 125, 127, 126, 125, 128, 130, 130, 126, 125, 133, 123, 126, 127, 126, 129, 128, 132, 125, 132, 122, 126, 132, 122, 131, 126, 122, 132, 125, 121, 130, 122, 135, 127, 123, 131, 128, 127, 125, 129, 133, 123, 123, 130, 132, 128, 122, 131, 126, 128, 128, 124, 130, 132, 124, 127, 126, 127, 134, 130, 126, 124, 126, 135, 134, 124, 124, 123, 132, 130, 120, 128, 132, 122, 126, 127, 125, 128, 124, 122, 129, 131, 122, 123, 126, 127, 129, 129, 128, 128, 128, 130, 129, 132, 128, 129, 129, 126, 125, 127, 129, 122, 122, 129, 126, 127, 128, 127, 133, 124, 128, 129, 129, 135, 128, 125, 133, 134, 131, 128, 124, 121, 125, 129, 129, 132, 127, 128, 128, 129, 128, 129, 129, 132, 129, 128, 130, 126, 125, 127, 130, 124, 119, 128, 128, 127, 130, 126, 132, 127, 127, 130, 128, 134, 130, 125, 130, 134, 132, 129, 126, 122, 124, 128, 128, 132, 131, 122, 123, 128, 121, 126, 135, 128, 125, 127, 127, 128, 122, 131, 133, 130, 132, 129, 127, 122, 118, 122, 136, 130, 116, 133, 131, 127, 130, 118, 126, 126, 124, 128, 132, 129, 129, 125, 125, 127, 129, 130, 123, 132, 135, 127, 121, 133, 123, 125, 130, 122, 128, 132, 138, 132, 130, 114, 117, 130, 129, 129, 140, 131, 115, 123, 127, 134, 123, 119, 122, 123, 128, 138, 133, 131, 128, 114, 121, 119, 133, 139, 136, 127, 125, 132, 121, 126, 128, 136, 144, 159, 155, 127, 112, 113, 123, 135, 143, 137, 131, 129, 127, 119, 115, 118, 123, 124, 121, 120, 120, 124, 121, 116, 127, 131, 110, 91, 82, 80, 77, 77, 83, 88, 88, 90, 93, 98, 111, 131, 157, 184, 199, 204, 203, 194, 181, 169, 156, 146, 138, 135, 133, 129, 123, 117, 112, 107, 109, 113, 123, 136, 152, 164, 169, 177, 179, 174, 170, 164, 152, 140, 129, 117, 109, 105, 106, 105, 106, 108, 108, 108, 105, 101, 93, 90, 84, 77, 68, 62, 61, 57, 52, 46, 46, 57, 76, 101, 139, 176, 207, 219, 223, 219, 204, 183, 161, 144, 131, 125, 123, 124, 124, 123, 119, 115, 112, 115, 121, 133, 148, 166, 178, 183, 185, 181, 171, 158, 147, 134, 123, 116, 113, 112, 112, 113, 116, 116, 118, 119, 117, 113, 109, 102, 94, 87, 81, 77, 71, 63, 55, 47, 44, 45, 56, 78, 109, 147, 184, 217, 230, 231, 223, 205, 182, 158, 138, 123, 117, 116, 117, 119, 120, 117, 114, 111, 114, 119, 131, 145, 162, 176, 183, 185, 181, 172, 159, 146, 134, 124, 117, 114, 113, 114, 115, 117, 118, 119, 120, 119, 117, 112, 106, 98, 91, 85, 80, 75, 67, 60, 51, 45, 44, 48, 66, 93, 132, 169, 206, 229, 234, 230, 214, 192, 166, 143, 124, 114, 111, 111, 113, 116, 115, 113, 111, 111, 116, 126, 141, 158, 174, 186, 190, 185, 173, 156, 137, 121, 110, 105, 105, 108, 113, 120, 125, 131, 136, 138, 137, 136, 133, 129, 122, 115, 106, 95, 85, 75, 66, 58, 51, 45, 40, 39, 48, 67, 94, 129, 171, 210, 235, 245, 243, 227, 199, 168, 142, 121, 108, 104, 105, 108, 110, 110, 109, 108, 110, 115, 125, 140, 159, 176, 187, 190, 184, 172, 157, 141, 126, 112, 104, 101, 102, 107, 115, 124, 130, 134, 137, 138, 136, 131, 126, 119, 110, 99, 88, 78, 70, 62, 54, 47, 38, 33, 44, 65, 96, 134, 178, 219, 242, 246, 238, 217, 186, 155, 131, 114, 106, 104, 107, 111, 110, 110, 107, 104, 105, 114, 131, 151, 172, 189, 198, 195, 183, 165, 147, 129, 116, 108, 106, 105, 108, 112, 117, 121, 125, 128, 131, 134, 136, 138, 134, 127, 115, 103, 89, 77, 65, 55, 48, 41, 33, 31, 46, 72, 109, 150, 194, 232, 249, 248, 233, 208, 175, 144, 122, 109, 104, 104, 107, 108, 104, 101, 98, 100, 106, 122, 147, 172, 193, 203, 201, 186, 162, 140, 124, 116, 115, 118, 123, 122, 119, 114, 112, 114, 120, 129, 137, 144, 146, 144, 134, 121, 104, 86, 68, 54, 47, 47, 48, 48, 46, 52, 70, 98, 138, 180, 221, 243, 245, 231, 205, 172, 139, 119, 108, 107, 108, 109, 106, 98, 90, 88, 98, 119, 146, 175, 198, 210, 205, 188, 161, 134, 115, 109, 113, 122, 132, 138, 131, 117, 105, 102, 109, 123, 141, 157, 161, 155, 140, 121, 99, 80, 71, 68, 70, 70, 70, 62, 45, 30, 33, 58, 101, 155, 208, 248, 255, 239, 202, 163, 132, 114, 117, 128, 135, 129, 113, 93, 76, 72, 86, 119, 157, 187, 203, 202, 185, 162, 142, 132, 129, 129, 130, 128, 123, 115, 109, 109, 115, 125, 136, 146, 155, 158, 156, 151, 141, 126, 110, 95, 83, 76, 74, 76, 77, 77, 71, 64, 54, 45, 46, 65, 112, 162, 204, 221, 218, 200, 171, 153, 149, 156, 158, 146, 125, 101, 81, 80, 98, 128, 152, 163, 163, 158, 155, 157, 165, 172, 169, 154, 133, 114, 104, 107, 122, 135, 137, 129, 123, 122, 130, 145, 163, 170, 161, 145, 130, 119, 110, 102, 92, 81, 69, 65, 69, 76, 79, 74, 66, 54, 45, 49, 72, 122, 176, 210, 212, 193, 174, 161, 161, 168, 166, 150, 123, 100, 93, 98, 113, 129, 140, 141, 140, 146, 159, 174, 180, 175, 161, 143, 130, 124, 123, 120, 117, 118, 124, 130, 138, 147, 153, 153, 153, 156, 156, 149, 136, 123, 108, 96, 90, 85, 78, 71, 71, 75, 81, 83, 81, 74, 65, 58, 57, 69, 104, 147, 176, 181, 176, 180, 177, 175, 173, 163, 149, 138, 136, 132, 122, 119, 123, 130, 139, 148, 153, 154, 158, 164, 165, 159, 150, 143, 139, 137, 136, 137, 135, 133, 130, 131, 135, 139, 144, 147, 144, 138, 129, 120, 111, 107, 104, 96, 86, 82, 86, 85, 81, 83, 86, 87, 87, 86, 79, 74, 76, 76, 63, 54, 91, 137, 156, 155, 162, 176, 181, 188, 187, 170, 158, 164, 169, 156, 137, 128, 127, 132, 137, 141, 142, 148, 159, 162, 159, 155, 154, 155, 152, 148, 142, 140, 140, 137, 134, 132, 131, 131, 131, 128, 127, 128, 130, 126, 119, 111, 102, 92, 85, 90, 98, 98, 92, 90, 88, 88, 90, 89, 84, 83, 85, 84, 82, 86, 83, 91, 117, 139, 142, 144, 156, 163, 168, 170, 166, 160, 160, 159, 153, 145, 143, 142, 144, 149, 148, 145, 144, 146, 145, 145, 144, 142, 141, 138, 136, 134, 132, 132, 133, 133, 129, 125, 123, 125, 127, 127, 129, 130, 129, 129, 126, 125, 123, 121, 119, 117, 118, 120, 121, 124, 125, 127, 128, 130, 129, 127, 128, 125, 125, 124, 121, 124, 125, 124, 125, 123, 121, 121, 124, 124, 126, 129, 127, 126, 128, 125, 124, 123, 121, 124, 125, 123, 124, 124, 121, 121, 124, 124, 125, 128, 125, 127, 129, 126, 126, 125, 124, 125, 127, 127, 128, 129, 129, 131, 134, 134, 133, 134, 135, 139, 140, 140, 142, 140, 139, 139, 140, 138, 138, 139, 137, 134, 131, 129, 127, 127, 127, 126, 124, 123, 124, 122, 120, 121, 121, 121, 122, 121, 119, 117, 117, 117,
+};
+
+const unsigned char five[] PROGMEM = {
+130, 126, 127, 130, 130, 125, 128, 129, 129, 130, 128, 128, 127, 123, 126, 124, 123, 129, 126, 127, 130, 131, 128, 131, 132, 130, 126, 127, 128, 126, 128, 123, 127, 128, 127, 130, 128, 129, 130, 129, 127, 132, 131, 129, 127, 127, 128, 127, 120, 121, 124, 120, 124, 127, 129, 127, 132, 133, 130, 129, 132, 135, 131, 126, 125, 124, 125, 125, 129, 129, 124, 129, 128, 133, 133, 128, 129, 129, 130, 127, 125, 127, 125, 127, 124, 120, 123, 121, 120, 127, 132, 132, 134, 137, 138, 132, 129, 129, 121, 119, 117, 116, 123, 124, 127, 128, 130, 139, 134, 134, 139, 136, 134, 129, 125, 127, 128, 122, 120, 122, 116, 115, 115, 118, 124, 132, 140, 139, 140, 136, 131, 132, 126, 124, 121, 121, 116, 112, 117, 118, 117, 122, 135, 144, 148, 145, 136, 122, 115, 112, 115, 119, 126, 130, 128, 129, 133, 139, 143, 145, 141, 130, 122, 122, 126, 130, 137, 141, 140, 140, 140, 138, 137, 136, 135, 133, 133, 132, 131, 131, 133, 134, 133, 133, 134, 133, 129, 124, 118, 108, 103, 102, 101, 99, 100, 99, 95, 92, 89, 86, 81, 80, 86, 87, 109, 168, 220, 240, 225, 189, 126, 75, 69, 85, 110, 133, 155, 147, 142, 151, 162, 165, 162, 150, 119, 99, 98, 110, 124, 140, 150, 145, 139, 136, 132, 128, 127, 125, 123, 123, 128, 132, 135, 137, 134, 129, 126, 124, 124, 125, 127, 125, 121, 117, 115, 113, 112, 113, 115, 115, 112, 105, 91, 76, 67, 63, 71, 89, 122, 194, 250, 255, 219, 157, 87, 45, 53, 87, 128, 157, 169, 160, 154, 156, 154, 145, 130, 112, 97, 99, 117, 141, 155, 159, 150, 137, 127, 122, 121, 122, 124, 126, 129, 134, 138, 137, 133, 128, 123, 120, 121, 125, 128, 129, 130, 128, 123, 121, 119, 115, 112, 113, 112, 110, 103, 93, 81, 75, 72, 76, 85, 122, 192, 238, 238, 193, 129, 65, 49, 76, 121, 160, 177, 169, 147, 141, 140, 140, 134, 124, 109, 104, 117, 137, 154, 159, 151, 135, 123, 119, 120, 122, 125, 128, 131, 133, 135, 135, 133, 130, 126, 123, 122, 125, 128, 130, 130, 128, 125, 120, 120, 122, 122, 119, 117, 116, 111, 102, 88, 74, 66, 65, 75, 93, 127, 195, 239, 230, 181, 116, 60, 50, 89, 133, 165, 175, 164, 145, 142, 143, 140, 133, 123, 110, 107, 121, 139, 153, 157, 148, 131, 121, 117, 120, 125, 129, 130, 132, 133, 133, 133, 131, 128, 126, 127, 129, 131, 131, 126, 120, 116, 116, 121, 124, 125, 125, 118, 109, 106, 98, 88, 79, 76, 74, 81, 92, 111, 174, 226, 228, 187, 127, 68, 55, 91, 135, 168, 177, 163, 142, 138, 134, 133, 133, 129, 120, 120, 129, 139, 146, 146, 140, 132, 127, 124, 127, 129, 131, 130, 129, 129, 129, 130, 131, 130, 128, 126, 127, 128, 128, 128, 126, 122, 120, 118, 118, 115, 115, 116, 112, 108, 97, 86, 74, 71, 71, 83, 99, 138, 195, 218, 200, 155, 106, 72, 87, 123, 158, 172, 164, 145, 133, 134, 133, 133, 132, 132, 129, 131, 136, 140, 143, 140, 132, 128, 129, 129, 131, 133, 130, 127, 127, 127, 128, 129, 130, 130, 132, 132, 130, 127, 125, 124, 123, 123, 120, 112, 104, 103, 110, 120, 118, 103, 88, 74, 68, 66, 82, 94, 140, 211, 233, 206, 151, 92, 57, 86, 129, 166, 179, 168, 145, 134, 133, 132, 134, 131, 129, 129, 137, 139, 140, 138, 135, 130, 131, 135, 133, 133, 129, 126, 124, 127, 128, 130, 131, 132, 131, 129, 128, 127, 127, 127, 126, 123, 118, 109, 107, 108, 109, 111, 112, 103, 93, 84, 81, 76, 78, 86, 103, 172, 226, 223, 177, 120, 69, 66, 110, 153, 172, 169, 156, 138, 137, 138, 135, 128, 128, 130, 138, 144, 143, 139, 136, 132, 131, 135, 136, 132, 126, 124, 123, 126, 130, 132, 131, 130, 129, 128, 127, 126, 126, 124, 122, 121, 117, 114, 113, 109, 108, 110, 108, 98, 87, 81, 80, 81, 89, 101, 128, 183, 220, 206, 158, 102, 66, 76, 119, 157, 171, 169, 157, 142, 136, 134, 129, 128, 132, 134, 137, 140, 138, 136, 136, 135, 135, 136, 135, 130, 126, 124, 125, 128, 130, 130, 129, 130, 133, 133, 129, 122, 118, 118, 121, 121, 115, 108, 107, 107, 110, 105, 94, 88, 80, 73, 71, 86, 103, 150, 212, 229, 190, 134, 94, 77, 99, 130, 148, 151, 155, 154, 151, 146, 134, 125, 123, 129, 134, 137, 138, 139, 139, 140, 138, 136, 134, 132, 129, 125, 124, 124, 126, 129, 130, 130, 129, 127, 128, 131, 132, 125, 117, 112, 105, 103, 110, 115, 113, 110, 103, 95, 85, 79, 74, 75, 93, 127, 186, 223, 208, 161, 117, 92, 94, 114, 129, 142, 157, 169, 165, 153, 135, 121, 121, 129, 135, 137, 138, 137, 139, 141, 139, 134, 132, 131, 129, 128, 127, 127, 127, 127, 127, 128, 130, 130, 130, 127, 121, 116, 114, 111, 106, 104, 103, 101, 99, 95, 91, 89, 87, 85, 87, 107, 153, 187, 179, 158, 149, 139, 125, 117, 111, 118, 141, 163, 163, 155, 147, 140, 138, 138, 130, 125, 132, 142, 145, 141, 139, 137, 137, 134, 131, 127, 126, 128, 127, 126, 128, 130, 131, 132, 130, 125, 121, 120, 114, 112, 111, 107, 101, 104, 109, 101, 85, 80, 82, 84, 85, 89, 104, 133, 183, 210, 192, 154, 131, 120, 112, 109, 113, 128, 156, 174, 166, 153, 144, 140, 134, 130, 126, 128, 135, 140, 142, 142, 141, 140, 137, 133, 130, 128, 128, 128, 128, 128, 128, 129, 132, 131, 128, 125, 123, 118, 112, 105, 102, 100, 99, 98, 98, 92, 83, 78, 81, 82, 81, 94, 126, 171, 188, 182, 168, 155, 141, 125, 109, 105, 123, 143, 155, 155, 158, 160, 159, 150, 136, 127, 129, 130, 130, 133, 139, 143, 143, 140, 136, 135, 132, 128, 126, 127, 126, 126, 127, 128, 128, 128, 125, 118, 115, 115, 111, 103, 98, 93, 94, 97, 84, 64, 74, 87, 77, 81, 112, 157, 188, 194, 179, 170, 159, 135, 106, 98, 113, 132, 141, 144, 154, 164, 166, 154, 143, 141, 140, 133, 127, 127, 135, 137, 134, 136, 139, 140, 134, 130, 130, 132, 131, 127, 124, 125, 127, 124, 120, 119, 118, 117, 111, 104, 100, 95, 91, 81, 76, 77, 78, 75, 76, 94, 120, 154, 175, 182, 180, 175, 159, 135, 119, 112, 117, 123, 129, 136, 147, 157, 162, 158, 155, 151, 146, 137, 128, 126, 130, 129, 127, 132, 137, 137, 135, 135, 135, 136, 132, 128, 126, 126, 124, 121, 117, 115, 114, 112, 104, 99, 100, 99, 96, 88, 75, 67, 70, 65, 71, 87, 132, 182, 194, 183, 190, 196, 169, 140, 116, 114, 119, 118, 110, 120, 138, 149, 155, 161, 173, 181, 176, 157, 146, 140, 133, 119, 116, 120, 130, 137, 135, 138, 148, 151, 141, 137, 134, 122, 111, 106, 97, 91, 94, 93, 91, 93, 97, 90, 82, 73, 71, 70, 70, 76, 98, 150, 177, 175, 178, 195, 191, 169, 144, 126, 130, 129, 116, 108, 124, 138, 143, 148, 157, 166, 173, 168, 152, 146, 147, 140, 125, 119, 122, 127, 129, 128, 131, 142, 147, 145, 142, 134, 126, 115, 100, 90, 90, 87, 80, 78, 82, 83, 77, 69, 69, 69, 78, 88, 113, 153, 175, 177, 178, 190, 185, 172, 154, 139, 134, 136, 124, 113, 119, 129, 134, 137, 145, 151, 162, 162, 158, 158, 160, 154, 144, 137, 132, 131, 129, 126, 123, 126, 127, 127, 121, 117, 114, 111, 105, 101, 99, 96, 97, 97, 92, 84, 76, 72, 68, 67, 73, 96, 136, 151, 154, 162, 181, 186, 182, 170, 155, 158, 156, 145, 125, 120, 120, 122, 121, 118, 121, 133, 148, 151, 152, 156, 161, 162, 159, 150, 142, 141, 140, 132, 121, 117, 114, 112, 109, 105, 105, 108, 109, 108, 108, 109, 111, 110, 106, 100, 95, 92, 90, 89, 91, 104, 120, 126, 129, 135, 143, 147, 151, 151, 149, 150, 151, 149, 145, 141, 136, 135, 138, 138, 137, 138, 140, 140, 141, 140, 140, 140, 138, 135, 134, 133, 129, 125, 123, 123, 123, 124, 122, 121, 122, 123, 124, 122, 120, 119, 119, 119, 119, 119, 119, 120, 121, 123, 123, 124, 124, 125, 127, 127, 127, 128, 128, 127, 127, 128, 128, 127, 130, 131, 132, 134, 134, 134, 135, 136, 134, 135, 134, 134, 135, 134, 132, 131, 132, 131, 132, 130, 131, 132, 130, 130, 131, 130, 127, 125, 125, 126, 124, 122, 121, 122, 121, 122, 123, 122, 122, 123, 125,
+};
+
+const unsigned char six[] PROGMEM = {
+116, 134, 134, 134, 121, 137, 127, 135, 128, 132, 119, 131, 122, 113, 125, 114, 131, 123, 120, 126, 133, 137, 128, 138, 139, 136, 154, 117, 143, 134, 128, 130, 112, 116, 112, 118, 104, 122, 125, 140, 117, 137, 136, 133, 142, 126, 141, 118, 132, 112, 122, 123, 102, 120, 128, 130, 142, 129, 135, 151, 138, 133, 137, 145, 138, 122, 111, 123, 121, 123, 106, 122, 119, 151, 132, 130, 151, 153, 144, 124, 133, 122, 136, 110, 109, 98, 121, 101, 96, 108, 135, 128, 130, 133, 145, 154, 131, 126, 114, 134, 106, 104, 96, 107, 111, 109, 111, 135, 141, 162, 163, 169, 184, 186, 176, 165, 163, 159, 150, 125, 135, 124, 133, 127, 135, 136, 143, 137, 137, 142, 132, 128, 114, 84, 76, 64, 35, 33, 31, 24, 2, 7, 9, 12, 11, 0, 99, 221, 166, 148, 240, 255, 247, 240, 211, 221, 255, 205, 128, 155, 166, 110, 83, 88, 84, 121, 139, 103, 123, 192, 205, 181, 212, 221, 224, 218, 197, 162, 157, 137, 88, 79, 83, 64, 56, 57, 49, 55, 53, 36, 58, 59, 35, 18, 18, 2, 0, 0, 0, 150, 171, 75, 125, 255, 255, 215, 217, 211, 255, 233, 148, 106, 162, 138, 59, 43, 91, 112, 133, 125, 138, 203, 231, 205, 195, 228, 213, 183, 164, 160, 141, 126, 98, 96, 107, 104, 98, 117, 133, 141, 134, 138, 138, 114, 91, 84, 76, 43, 17, 0, 0, 0, 0, 0, 110, 186, 89, 121, 255, 255, 193, 230, 253, 242, 187, 148, 120, 130, 105, 32, 44, 101, 97, 86, 141, 175, 199, 208, 214, 225, 225, 197, 175, 185, 164, 114, 106, 110, 86, 73, 96, 107, 107, 117, 123, 129, 133, 118, 107, 106, 101, 62, 43, 39, 1, 0, 0, 49, 112, 69, 89, 202, 228, 174, 199, 255, 238, 193, 201, 199, 166, 134, 116, 101, 92, 82, 87, 104, 117, 135, 157, 175, 184, 190, 198, 206, 197, 176, 165, 149, 124, 103, 94, 93, 83, 87, 98, 108, 105, 109, 117, 119, 115, 116, 110, 100, 81, 63, 63, 48, 29, 47, 102, 93, 71, 113, 170, 151, 137, 187, 208, 181, 176, 199, 188, 155, 148, 152, 132, 118, 119, 121, 123, 130, 137, 144, 151, 159, 161, 158, 162, 162, 147, 143, 138, 127, 114, 111, 112, 106, 106, 109, 113, 115, 121, 122, 122, 123, 123, 120, 119, 114, 110, 106, 103, 102, 100, 102, 103, 108, 110, 114, 118, 119, 127, 130, 129, 129, 134, 136, 131, 134, 134, 136, 135, 136, 139, 138, 139, 137, 140, 141, 142, 142, 141, 141, 140, 135, 134, 134, 132, 129, 129, 126, 124, 124, 124, 125, 125, 124, 124, 127, 127, 125, 127, 127, 125, 124, 124, 123, 124, 123, 123, 124, 124, 125, 126, 129, 129, 130, 129, 130, 130, 130, 129, 128, 127, 126, 126, 125, 127, 127, 127, 128, 128, 128, 129, 129, 128, 128, 128, 128, 128, 128, 128, 127, 127, 127, 127, 127, 128, 128, 128, 129, 128, 129, 128, 128, 128, 127, 127, 127, 126, 126, 126, 126, 126, 126, 127, 127, 128, 128, 128, 128, 128, 128, 128, 128, 127, 127, 127, 126, 127, 127, 127, 127, 128, 128, 129, 129, 129, 129, 129, 129, 128, 128, 128, 127, 127, 127, 126, 127, 127, 127, 128, 128, 128, 128, 129, 129, 128, 128, 128, 128, 126, 126, 127, 127, 126, 126, 127, 127, 127, 127, 128, 129, 129, 129, 128, 128, 128, 127, 127, 126, 125, 126, 126, 126, 126, 127, 128, 129, 128, 127, 129, 129, 128, 129, 127, 125, 125, 126, 128, 126, 125, 130, 131, 125, 123, 127, 134, 135, 120, 124, 150, 148, 121, 105, 122, 141, 134, 115, 113, 130, 135, 122, 118, 126, 133, 131, 126, 127, 136, 133, 127, 136, 132, 118, 110, 122, 131, 127, 112, 118, 135, 138, 126, 129, 142, 146, 141, 122, 117, 125, 134, 119, 113, 117, 124, 129, 122, 114, 133, 139, 120, 132, 132, 141, 131, 117, 132, 131, 130, 117, 124, 122, 123, 123, 121, 137, 121, 125, 135, 131, 128, 122, 132, 132, 140, 120, 132, 124, 135, 142, 110, 127, 118, 152, 119, 129, 112, 145, 139, 117, 125, 113, 150, 128, 126, 112, 126, 141, 133, 112, 122, 130, 151, 115, 119, 129, 144, 129, 116, 125, 136, 137, 114, 131, 119, 146, 120, 125, 127, 125, 139, 113, 123, 139, 137, 118, 116, 133, 133, 127, 113, 122, 146, 127, 122, 111, 135, 153, 108, 118, 124, 150, 131, 111, 118, 138, 143, 118, 115, 127, 150, 116, 126, 121, 132, 136, 120, 126, 126, 138, 130, 121, 121, 129, 129, 118, 130, 128, 137, 125, 126, 134, 132, 131, 109, 136, 135, 126, 122, 123, 131, 131, 126, 119, 130, 132, 125, 128, 123, 128, 126, 130, 126, 127, 123, 130, 134, 123, 124, 130, 134, 127, 126, 123, 137, 120, 128, 132, 130, 126, 129, 129, 122, 132, 128, 123, 136, 118, 128, 141, 118, 126, 128, 136, 124, 130, 127, 129, 116, 143, 110, 136, 130, 115, 144, 114, 131, 121, 132, 128, 129, 121, 144, 106, 145, 117, 127, 133, 123, 138, 116, 142, 112, 140, 107, 146, 121, 121, 142, 116, 138, 119, 140, 118, 126, 137, 121, 140, 107, 144, 121, 122, 133, 123, 129, 136, 121, 131, 129, 122, 141, 112, 143, 113, 143, 113, 145, 109, 131, 134, 107, 147, 116, 136, 117, 139, 115, 131, 138, 108, 152, 97, 153, 117, 130, 130, 117, 141, 110, 160, 86, 171, 90, 165, 92, 159, 108, 138, 130, 112, 148, 90, 175, 69, 185, 78, 170, 95, 152, 110, 138, 127, 116, 147, 108, 159, 91, 159, 101, 142, 119, 127, 131, 124, 131, 130, 125, 137, 114, 143, 108, 148, 111, 129, 138, 110, 154, 101, 147, 114, 135, 126, 127, 129, 125, 134, 115, 136, 119, 136, 126, 124, 132, 119, 139, 117, 144, 111, 146, 116, 129, 135,
+};
+
+const unsigned char seven[] PROGMEM = {
+134, 123, 132, 124, 127, 126, 123, 125, 124, 134, 123, 133, 124, 135, 125, 127, 126, 124, 132, 123, 130, 128, 134, 127, 131, 125, 125, 125, 129, 125, 127, 129, 128, 128, 128, 131, 130, 135, 126, 132, 127, 130, 119, 129, 121, 125, 127, 123, 132, 120, 134, 123, 130, 124, 130, 127, 128, 132, 126, 130, 126, 128, 123, 128, 125, 126, 129, 128, 130, 129, 128, 133, 132, 129, 130, 131, 128, 126, 123, 123, 126, 124, 123, 128, 131, 129, 128, 133, 136, 132, 134, 124, 125, 126, 124, 121, 117, 125, 123, 124, 124, 129, 134, 135, 129, 130, 130, 128, 123, 117, 118, 119, 126, 119, 111, 113, 119, 116, 118, 121, 125, 136, 138, 134, 136, 147, 145, 142, 137, 133, 134, 130, 126, 126, 135, 134, 131, 137, 143, 148, 147, 147, 146, 149, 145, 135, 129, 130, 132, 127, 120, 119, 126, 128, 121, 112, 115, 118, 114, 102, 96, 92, 90, 77, 59, 52, 60, 58, 49, 46, 55, 64, 59, 49, 52, 117, 170, 215, 229, 218, 223, 231, 209, 156, 137, 121, 127, 123, 111, 106, 124, 153, 162, 163, 169, 184, 184, 170, 144, 126, 119, 110, 93, 92, 102, 122, 134, 132, 133, 140, 143, 133, 120, 116, 129, 133, 137, 140, 143, 146, 146, 144, 137, 139, 140, 133, 121, 118, 114, 110, 100, 90, 85, 84, 75, 59, 52, 58, 63, 54, 51, 57, 67, 61, 52, 50, 101, 161, 211, 233, 220, 223, 230, 214, 161, 136, 120, 126, 123, 110, 104, 118, 150, 160, 161, 167, 181, 183, 173, 146, 125, 118, 111, 92, 92, 101, 121, 138, 137, 136, 141, 145, 133, 118, 109, 115, 121, 133, 146, 151, 153, 159, 159, 154, 152, 146, 139, 126, 116, 109, 104, 95, 87, 84, 78, 74, 72, 77, 77, 74, 71, 68, 60, 52, 48, 47, 44, 51, 97, 179, 241, 239, 226, 220, 212, 187, 147, 109, 97, 116, 131, 131, 130, 153, 176, 190, 183, 172, 161, 140, 122, 103, 99, 108, 118, 121, 133, 152, 167, 173, 164, 155, 140, 123, 98, 85, 88, 99, 125, 140, 160, 181, 188, 182, 172, 161, 143, 133, 125, 115, 108, 103, 96, 94, 92, 84, 78, 78, 73, 68, 66, 67, 57, 49, 51, 42, 42, 43, 54, 93, 181, 255, 241, 201, 194, 202, 180, 137, 99, 86, 112, 141, 137, 125, 143, 181, 196, 183, 159, 145, 144, 139, 118, 102, 109, 123, 128, 129, 135, 143, 156, 160, 146, 128, 116, 106, 98, 97, 109, 128, 152, 171, 178, 175, 167, 160, 151, 139, 126, 119, 117, 112, 106, 102, 95, 85, 79, 76, 79, 82, 81, 73, 66, 62, 53, 47, 49, 55, 76, 126, 195, 237, 233, 216, 201, 187, 167, 138, 104, 89, 108, 132, 139, 137, 146, 162, 177, 181, 167, 143, 134, 139, 136, 119, 107, 111, 125, 138, 143, 139, 135, 137, 139, 137, 129, 122, 120, 132, 148, 155, 151, 145, 147, 150, 144, 134, 126, 123, 122, 122, 117, 110, 103, 97, 93, 84, 73, 65, 67, 71, 72, 73, 73, 71, 73, 73, 65, 73, 120, 184, 216, 212, 200, 191, 182, 172, 157, 134, 116, 119, 131, 135, 132, 134, 139, 146, 156, 164, 158, 144, 139, 138, 136, 135, 130, 124, 124, 131, 135, 128, 118, 116, 117, 117, 116, 119, 132, 142, 143, 140, 138, 140, 141, 141, 137, 135, 135, 133, 127, 120, 116, 114, 110, 110, 109, 104, 99, 97, 97, 98, 102, 101, 100, 95, 90, 89, 93, 98, 106, 120, 132, 140, 145, 154, 158, 159, 161, 161, 159, 156, 154, 152, 146, 142, 139, 135, 132, 129, 127, 125, 127, 130, 133, 136, 141, 145, 144, 138, 133, 129, 126, 120, 115, 112, 115, 122, 125, 125, 125, 130, 135, 138, 140, 140, 140, 136, 131, 129, 128, 126, 123, 118, 116, 115, 114, 113, 113, 111, 108, 108, 107, 108, 108, 105, 99, 94, 90, 92, 103, 112, 119, 124, 128, 130, 134, 144, 153, 154, 153, 151, 153, 150, 152, 152, 147, 143, 142, 143, 139, 137, 136, 137, 138, 135, 131, 128, 129, 130, 128, 126, 124, 125, 124, 123, 124, 124, 124, 122, 122, 120, 126, 131, 130, 129, 130, 135, 136, 134, 138, 135, 126, 126, 130, 128, 122, 117, 113, 114, 114, 115, 116, 115, 113, 112, 114, 115, 108, 102, 101, 99, 93, 105, 122, 124, 125, 125, 131, 130, 134, 145, 146, 146, 148, 150, 144, 141, 146, 144, 139, 140, 144, 139, 133, 135, 134, 133, 134, 134, 131, 130, 134, 135, 132, 130, 133, 133, 131, 132, 130, 126, 124, 127, 127, 128, 127, 124, 123, 123, 126, 131, 130, 130, 130, 125, 125, 126, 125, 120, 113, 112, 112, 114, 118, 116, 115, 115, 114, 110, 108, 106, 101, 97, 101, 116, 120, 122, 126, 131, 134, 138, 147, 146, 146, 151, 151, 147, 146, 148, 145, 140, 138, 135, 131, 133, 135, 127, 124, 129, 135, 139, 138, 139, 143, 150, 154, 148, 142, 141, 142, 139, 133, 128, 121, 118, 119, 121, 123, 120, 125, 121, 117, 117, 114, 110, 108, 103, 96, 92, 93, 94, 89, 88, 87, 81, 76, 72, 64, 56, 62, 100, 126, 146, 167, 178, 189, 192, 206, 201, 186, 178, 174, 168, 151, 142, 132, 123, 122, 120, 118, 113, 120, 131, 140, 149, 154, 159, 159, 173, 185, 177, 162, 152, 150, 137, 126, 116, 108, 106, 111, 118, 114, 114, 116, 119, 122, 121, 118, 109, 109, 105, 92, 77, 71, 69, 65, 61, 57, 48, 41, 40, 45, 41, 45, 94, 140, 170, 181, 195, 215, 223, 225, 203, 176, 165, 168, 158, 131, 120, 116, 118, 124, 128, 129, 134, 152, 159, 159, 159, 164, 167, 160, 155, 154, 162, 156, 140, 132, 130, 133, 124, 122, 123, 127, 137, 140, 141, 138, 140, 136, 127, 118, 108, 93, 75, 63, 52, 46, 43, 39, 32, 29, 36, 38, 33, 28, 36, 93, 138, 154, 162, 190, 229, 228, 214, 199, 202, 202, 180, 157, 145, 152, 147, 136, 133, 144, 159, 154, 146, 147, 159, 162, 152, 144, 143, 146, 134, 126, 132, 132, 129, 130, 131, 131, 131, 133, 130, 134, 145, 147, 145, 144, 142, 137, 127, 113, 99, 86, 74, 65, 53, 45, 43, 38, 30, 29, 35, 34, 33, 32, 59, 110, 120, 122, 158, 201, 202, 193, 208, 216, 210, 194, 183, 183, 183, 169, 151, 154, 164, 157, 146, 148, 158, 159, 154, 149, 153, 158, 149, 134, 135, 141, 127, 119, 126, 128, 123, 123, 127, 132, 135, 136, 140, 144, 141, 139, 137, 131, 123, 113, 101, 89, 77, 61, 53, 48, 42, 36, 32, 31, 38, 35, 28, 32, 67, 107, 114, 131, 170, 199, 196, 200, 217, 223, 212, 199, 199, 200, 183, 165, 165, 164, 154, 145, 142, 140, 139, 137, 137, 144, 148, 140, 139, 140, 133, 127, 127, 125, 128, 128, 125, 125, 130, 129, 127, 131, 135, 137, 137, 137, 137, 135, 130, 123, 115, 105, 91, 89, 81, 71, 64, 62, 57, 54, 53, 40, 41, 44, 40, 42, 70, 86, 97, 123, 145, 159, 173, 186, 196, 205, 206, 207, 213, 212, 202, 198, 195, 184, 174, 166, 155, 146, 140, 137, 135, 132, 128, 126, 125, 123, 121, 121, 122, 120, 122, 124, 126, 128, 131, 132, 132, 135, 136, 138, 140, 140, 140, 140, 138, 131, 126, 118, 109, 101, 93, 84, 77, 69, 60, 55, 50, 41, 36, 34, 32, 33, 45, 62, 78, 97, 115, 135, 153, 169, 181, 194, 205, 213, 221, 226, 226, 225, 222, 215, 205, 192, 177, 166, 156, 145, 136, 130, 124, 118, 112, 106, 104, 102, 104, 106, 108, 110, 113, 116, 119, 121, 124, 127, 131, 136,
+};
+
+const unsigned char eight[] PROGMEM = {
+104, 93, 82, 71, 61, 52, 41, 26, 14, 4, 0, 0, 0, 0, 0, 13, 41, 64, 89, 118, 147, 173, 192, 209, 232, 251, 255, 255, 255, 255, 255, 255, 250, 234, 214, 196, 181, 169, 155, 144, 135, 125, 115, 103, 95, 89, 86, 85, 87, 90, 96, 101, 108, 114, 122, 130, 140, 149, 158, 166, 171, 174, 171, 166, 157, 149, 136, 123, 110, 97, 80, 69, 59, 46, 35, 23, 13, 7, 0, 0, 5, 32, 39, 49, 83, 111, 126, 145, 170, 193, 212, 225, 233, 242, 244, 243, 243, 230, 213, 205, 195, 181, 166, 153, 144, 138, 122, 110, 108, 104, 97, 89, 90, 95, 93, 99, 116, 124, 134, 146, 162, 170, 173, 188, 191, 181, 176, 173, 156, 139, 127, 111, 92, 72, 55, 51, 38, 27, 25, 23, 15, 10, 11, 3, 0, 1, 106, 103, 90, 207, 219, 178, 241, 255, 224, 228, 219, 226, 217, 166, 173, 195, 145, 141, 161, 132, 120, 126, 124, 120, 115, 119, 122, 112, 109, 122, 126, 125, 138, 154, 156, 161, 165, 172, 176, 161, 162, 162, 138, 123, 114, 94, 78, 72, 61, 47, 42, 41, 36, 20, 34, 19, 1, 16, 0, 0, 49, 126, 96, 133, 238, 218, 205, 255, 249, 223, 214, 214, 208, 176, 149, 162, 156, 124, 141, 145, 125, 121, 131, 121, 118, 123, 119, 120, 117, 129, 139, 128, 148, 166, 151, 158, 173, 166, 163, 171, 158, 144, 131, 121, 114, 93, 82, 85, 65, 49, 54, 43, 27, 24, 18, 10, 1, 0, 0, 0, 101, 131, 97, 210, 253, 193, 235, 255, 222, 209, 214, 200, 183, 159, 151, 168, 138, 136, 157, 138, 126, 142, 132, 117, 135, 132, 127, 137, 142, 139, 150, 155, 143, 151, 163, 153, 151, 163, 153, 132, 137, 118, 98, 92, 72, 66, 54, 49, 45, 32, 32, 23, 6, 8, 0, 0, 0, 85, 116, 73, 209, 245, 172, 248, 255, 214, 208, 233, 202, 171, 174, 155, 158, 139, 135, 153, 136, 130, 138, 138, 123, 130, 133, 126, 135, 131, 138, 148, 138, 152, 157, 149, 151, 162, 151, 148, 149, 131, 124, 113, 92, 81, 74, 55, 59, 46, 33, 32, 14, 11, 0, 0, 0, 33, 105, 46, 123, 218, 162, 194, 255, 236, 201, 255, 236, 184, 197, 186, 161, 145, 148, 146, 127, 131, 131, 129, 121, 123, 132, 125, 130, 135, 135, 137, 139, 148, 152, 148, 158, 159, 154, 153, 151, 142, 126, 117, 106, 81, 71, 58, 42, 25, 22, 6, 0, 0, 0, 0, 0, 79, 69, 77, 183, 171, 161, 237, 242, 203, 236, 255, 208, 199, 213, 178, 159, 160, 151, 121, 125, 125, 106, 112, 113, 110, 116, 122, 122, 129, 144, 148, 153, 171, 175, 174, 182, 177, 169, 165, 153, 141, 125, 108, 88, 80, 64, 49, 51, 41, 30, 33, 34, 15, 9, 38, 77, 61, 82, 145, 135, 136, 194, 203, 183, 216, 229, 205, 210, 216, 184, 178, 174, 142, 133, 132, 112, 105, 113, 103, 98, 110, 110, 111, 128, 127, 127, 144, 147, 143, 155, 165, 153, 160, 165, 145, 141, 145, 113, 99, 99, 62, 53, 48, 17, 3, 7, 0, 29, 43, 44, 92, 108, 114, 154, 179, 170, 204, 219, 205, 215, 221, 199, 190, 190, 165, 154, 147, 132, 120, 119, 111, 104, 108, 110, 111, 120, 120, 125, 135, 136, 139, 147, 151, 151, 156, 157, 152, 144, 139, 124, 110, 97, 81, 59, 47, 25, 5, 9, 24, 26, 31, 68, 81, 89, 124, 156, 153, 182, 208, 195, 215, 223, 203, 202, 205, 175, 166, 162, 141, 132, 132, 117, 113, 114, 110, 114, 116, 116, 117, 126, 129, 128, 136, 144, 144, 144, 151, 148, 141, 141, 131, 113, 102, 90, 68, 51, 35, 5, 34, 35, 4, 66, 77, 56, 116, 142, 121, 170, 200, 175, 203, 224, 190, 198, 207, 175, 167, 172, 149, 135, 140, 125, 113, 120, 114, 108, 119, 117, 115, 124, 127, 127, 134, 141, 141, 143, 150, 147, 144, 143, 135, 118, 108, 94, 72, 59, 46, 17, 27, 56, 15, 53, 94, 67, 103, 144, 135, 153, 190, 180, 189, 207, 195, 187, 191, 177, 164, 160, 151, 139, 134, 127, 120, 119, 117, 118, 119, 121, 123, 125, 128, 130, 134, 137, 139, 140, 141, 138, 133, 128, 118, 106, 95, 82, 63, 50, 38, 40, 46, 38, 62, 85, 77, 105, 136, 131, 153, 181, 174, 184, 201, 190, 185, 189, 180, 166, 163, 157, 142, 138, 134, 123, 124, 123, 116, 119, 124, 120, 122, 125, 126, 128, 129, 135, 133, 134, 139, 135, 128, 134, 125, 115, 113, 98, 89, 83, 71, 72, 79, 75, 84, 97, 98, 108, 122, 125, 133, 143, 145, 147, 150, 150, 148, 147, 144, 142, 141, 138, 136, 137, 134, 133, 134, 132, 131, 132, 131, 130, 129, 129, 128, 128, 127, 127, 127, 126, 126, 126, 125, 125, 124, 124, 124, 123, 123, 122, 122, 121, 122, 122, 123, 124, 125, 127, 127, 128, 128, 129, 129, 130, 130, 130, 130, 130, 129, 129, 128, 128, 128, 127, 127, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127,
+};
+
+const unsigned char nine[] PROGMEM = {
+129, 128, 129, 129, 129, 128, 128, 128, 128, 127, 128, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 128, 127, 128, 127, 128, 128, 129, 128, 128, 129, 128, 128, 128, 127, 128, 125, 125, 125, 123, 121, 119, 122, 116, 116, 118, 118, 116, 118, 117, 117, 117, 118, 118, 117, 120, 119, 123, 121, 124, 124, 122, 127, 124, 127, 127, 129, 131, 134, 136, 137, 140, 141, 142, 142, 146, 143, 146, 146, 145, 143, 142, 141, 137, 136, 133, 130, 127, 126, 122, 121, 119, 120, 117, 118, 117, 118, 118, 119, 120, 121, 123, 125, 125, 126, 128, 127, 128, 125, 127, 122, 124, 119, 119, 117, 114, 114, 111, 113, 110, 106, 107, 104, 106, 106, 104, 109, 107, 114, 114, 118, 122, 127, 134, 143, 148, 156, 163, 171, 177, 179, 184, 183, 184, 181, 180, 174, 168, 162, 156, 147, 140, 130, 123, 117, 110, 106, 102, 100, 98, 99, 99, 100, 103, 105, 109, 112, 116, 119, 120, 123, 124, 126, 126, 127, 126, 126, 124, 122, 121, 118, 116, 112, 109, 105, 101, 97, 97, 92, 91, 89, 85, 85, 82, 83, 83, 89, 98, 107, 117, 130, 143, 157, 170, 183, 193, 198, 203, 205, 205, 203, 201, 195, 188, 181, 171, 159, 148, 139, 128, 119, 113, 107, 102, 101, 99, 98, 101, 104, 108, 115, 121, 126, 133, 140, 143, 146, 151, 152, 151, 150, 147, 141, 136, 131, 122, 115, 108, 100, 93, 85, 78, 72, 67, 62, 58, 58, 60, 60, 64, 68, 69, 73, 76, 78, 83, 92, 100, 110, 129, 147, 156, 172, 189, 196, 203, 214, 217, 217, 220, 219, 210, 203, 198, 185, 170, 161, 147, 133, 123, 115, 105, 100, 97, 92, 88, 89, 90, 92, 97, 103, 108, 117, 127, 134, 142, 149, 156, 161, 166, 167, 166, 164, 163, 156, 149, 142, 133, 124, 117, 108, 97, 90, 83, 75, 67, 63, 59, 54, 54, 54, 51, 53, 57, 58, 62, 67, 78, 85, 95, 110, 122, 139, 158, 171, 180, 195, 207, 212, 215, 221, 222, 219, 221, 214, 200, 190, 183, 175, 153, 138, 125, 107, 102, 95, 89, 89, 92, 95, 99, 109, 117, 124, 133, 140, 148, 153, 152, 151, 150, 151, 147, 142, 137, 132, 129, 126, 120, 112, 109, 110, 106, 101, 95, 91, 89, 82, 75, 71, 67, 66, 70, 76, 75, 72, 81, 85, 103, 122, 136, 145, 170, 230, 240, 198, 157, 141, 138, 142, 143, 134, 142, 165, 175, 165, 149, 130, 126, 131, 130, 120, 118, 123, 130, 136, 135, 127, 125, 126, 126, 130, 137, 139, 139, 147, 155, 156, 148, 139, 132, 133, 134, 131, 127, 123, 123, 126, 124, 116, 110, 102, 93, 89, 88, 83, 80, 78, 78, 78, 82, 88, 92, 82, 65, 67, 94, 126, 143, 154, 157, 204, 239, 204, 143, 106, 104, 124, 160, 168, 161, 164, 179, 173, 156, 132, 111, 114, 130, 139, 139, 138, 132, 133, 136, 134, 125, 122, 121, 118, 122, 133, 138, 139, 145, 149, 147, 145, 140, 132, 132, 134, 132, 132, 131, 129, 128, 125, 120, 115, 106, 97, 94, 93, 93, 92, 94, 90, 89, 88, 85, 83, 80, 73, 69, 76, 97, 122, 146, 209, 244, 218, 165, 108, 72, 80, 129, 168, 188, 183, 166, 141, 136, 141, 136, 130, 123, 115, 120, 132, 139, 145, 143, 140, 131, 128, 119, 110, 112, 118, 129, 143, 164, 171, 165, 153, 133, 118, 115, 118, 130, 143, 144, 135, 125, 124, 117, 114, 111, 102, 92, 84, 81, 85, 87, 84, 88, 80, 60, 60, 78, 100, 130, 195, 247, 231, 182, 119, 71, 73, 113, 156, 179, 173, 154, 142, 140, 146, 150, 144, 135, 126, 125, 129, 127, 131, 132, 130, 134, 134, 126, 117, 112, 113, 118, 133, 145, 163, 173, 167, 158, 138, 117, 111, 121, 131, 135, 135, 131, 125, 129, 124, 116, 110, 103, 97, 87, 80, 72, 65, 64, 68, 66, 64, 82, 95, 117, 205, 255, 232, 178, 112, 61, 70, 125, 165, 189, 176, 143, 127, 129, 134, 147, 150, 138, 130, 124, 125, 131, 137, 140, 142, 136, 128, 124, 117, 112, 106, 111, 126, 142, 164, 178, 180, 167, 144, 121, 110, 118, 130, 136, 130, 118, 109, 117, 129, 132, 119, 99, 92, 82, 70, 49, 38, 46, 57, 85, 104, 114, 169, 229, 227, 187, 126, 73, 69, 110, 165, 201, 195, 152, 120, 114, 128, 151, 157, 143, 132, 135, 140, 138, 136, 134, 138, 138, 128, 117, 107, 102, 111, 124, 144, 170, 183, 177, 164, 141, 121, 117, 119, 124, 132, 125, 120, 120, 123, 126, 123, 114, 105, 97, 88, 72, 53, 54, 61, 64, 69, 77, 77, 157, 248, 250, 202, 121, 52, 51, 113, 171, 210, 199, 159, 130, 120, 118, 126, 139, 143, 154, 155, 142, 130, 126, 127, 137, 143, 139, 131, 120, 113, 111, 115, 138, 169, 178, 170, 151, 132, 129, 137, 135, 128, 120, 113, 113, 117, 123, 123, 108, 96, 92, 88, 73, 55, 41, 34, 51, 84, 111, 124, 183, 234, 214, 164, 99, 52, 70, 128, 170, 193, 181, 148, 143, 156, 160, 157, 143, 124, 124, 132, 134, 136, 137, 134, 139, 142, 130, 120, 119, 122, 147, 165, 153, 137, 136, 139, 151, 157, 138, 120, 114, 113, 115, 121, 118, 117, 117, 105, 91, 78, 59, 41, 35, 45, 70, 98, 109, 148, 211, 221, 180, 125, 84, 77, 118, 157, 165, 164, 160, 155, 160, 160, 146, 135, 131, 126, 130, 140, 141, 138, 148, 150, 143, 146, 130, 114, 110, 136, 158, 159, 149, 137, 138, 145, 143, 129, 128, 124, 122, 119, 115, 112, 110, 112, 106, 89, 75, 73, 70, 58, 43, 39, 66, 102, 127, 195, 246, 201, 129, 92, 82, 97, 135, 156, 154, 161, 167, 161, 159, 146, 129, 129, 137, 137, 136, 134, 128, 135, 143, 139, 134, 131, 125, 127, 144, 145, 133, 128, 129, 133, 138, 138, 132, 127, 128, 130, 125, 117, 111, 113, 111, 105, 95, 89, 83, 77, 73, 57, 53, 80, 93, 99, 188, 240, 190, 145, 125, 106, 111, 131, 122, 125, 152, 169, 165, 156, 144, 141, 148, 143, 134, 129, 127, 127, 132, 135, 132, 128, 130, 134, 148, 149, 136, 131, 130, 129, 131, 133, 130, 127, 131, 134, 128, 119, 105, 96, 100, 102, 92, 84, 81, 72, 65, 61, 58, 79, 95, 117, 174, 202, 177, 150, 148, 138, 127, 126, 133, 146, 154, 159, 154, 149, 148, 148, 144, 137, 135, 135, 131, 129, 132, 132, 138, 144, 139, 143, 141, 133, 131, 128, 127, 129, 130, 130, 129, 127, 119, 109, 105, 101, 92, 88, 90, 81, 70, 71, 68, 61, 54, 56, 72, 110, 169, 187, 174, 168, 169, 160, 141, 129, 132, 145, 153, 153, 158, 161, 156, 157, 154, 144, 141, 138, 127, 127, 131, 129, 136, 153, 151, 141, 141, 137, 132, 130, 130, 130, 128, 127, 124, 123, 122, 112, 106, 103, 96, 86, 81, 79, 72, 67, 66, 63, 63, 58, 61, 86, 134, 160, 164, 176, 182, 174, 153, 143, 139, 140, 144, 147, 154, 158, 161, 160, 157, 152, 145, 138, 136, 133, 129, 131, 145, 154, 143, 143, 147, 137, 132, 134, 132, 130, 125, 124, 123, 119, 114, 105, 99, 101, 91, 83, 86, 79, 73, 68, 62, 57, 57, 41, 43, 72, 113, 146, 152, 178, 187, 178, 170, 163, 157, 147, 145, 151, 157, 153, 156, 163, 157, 152, 152, 146, 139, 135, 131, 136, 155, 148, 136, 148, 141, 132, 134, 135, 130, 129, 128, 125, 124, 119, 114, 108, 100, 101, 95, 82, 86, 83, 70, 71, 70, 65, 55, 45, 48, 57, 102, 131, 143, 179, 179, 177, 182, 166, 159, 161, 154, 153, 166, 159, 152, 161, 155, 151, 150, 143, 137, 136, 133, 141, 155, 143, 144, 149, 138, 135, 137, 134, 131, 128, 127, 125, 120, 116, 108, 101, 97, 95, 86, 80, 79, 74, 68, 67, 63, 57, 55, 48, 58, 86, 115, 134, 159, 182, 183, 181, 175, 169, 161, 160, 161, 157, 157, 159, 158, 156, 155, 152, 146, 139, 136, 140, 147, 147, 147, 150, 146, 139, 137, 135, 133, 130, 128, 130, 126, 121, 120, 113, 104, 101, 95, 89, 83, 77, 76, 68, 61, 65, 60, 54, 49, 42, 40, 64, 106, 112, 142, 178, 175, 183, 185, 177, 179, 171, 167, 178, 168, 156, 162, 160, 153, 153, 149, 145, 143, 140, 138, 141, 148, 145, 142, 143, 139, 134, 134, 134, 132, 131, 130, 129, 127, 124, 120, 116, 111, 103, 97, 93, 85, 81, 76, 69, 67, 61, 51, 44, 38, 31, 38, 58, 69, 84, 111, 127, 138, 152, 158, 164, 175, 183, 185, 189, 193, 189, 186, 179, 172, 166, 156, 148, 143, 140, 137, 137, 137, 140, 137, 135, 137, 135, 133, 135, 133, 133, 134, 132, 130, 131, 131, 128, 127, 126, 122, 118, 113, 108, 101, 93, 86, 78, 67, 58, 52, 40, 30, 27, 25, 35, 54, 66, 80, 107, 125, 135, 150, 158, 163, 173, 183, 185, 189, 193, 190, 187, 183, 176, 170, 162, 154, 148, 143, 139, 136, 134, 135, 133, 131, 133, 133, 132, 133, 134, 133, 134, 132, 129, 128, 125, 120, 115, 110, 105, 99, 94, 90, 86, 82, 79, 77, 75, 74, 75, 75, 77, 80, 82, 85, 88, 90, 95, 106, 116, 123, 134, 147, 157, 167, 175, 182, 189, 193, 194, 195, 194, 190, 184, 177, 171, 164, 154, 144, 138, 132, 127, 125, 125, 125, 126, 128, 129, 130, 131, 131, 131, 130, 128, 126, 123, 120, 116, 112, 106, 101, 97, 94, 91, 89, 88, 88, 88, 86, 87, 89, 90, 92, 95, 99, 102, 103, 105, 106, 107, 111, 117, 122, 127, 135, 144, 152, 160, 166, 172, 177, 180, 182, 182, 180, 177, 173, 169, 163, 157, 150, 144, 138, 132, 128, 126, 124, 124, 124, 125, 126, 126, 126, 125, 125, 123, 122, 120, 117, 114, 112, 111, 109, 107, 105, 104, 104, 103, 102, 101, 102, 102, 102, 103, 104, 106, 109, 111, 114, 115, 117, 119, 121, 124, 126, 130, 133, 135, 138, 141, 144, 146, 148, 150, 151, 152, 153, 153, 153, 152, 151, 150, 149, 146, 144, 141, 139, 137, 135, 133, 132, 130, 129, 128, 127, 125, 124, 123, 122, 121, 120, 119, 119, 119, 119, 119, 119, 120, 120, 121, 122,
+};
+
+const unsigned char dbm[] PROGMEM = {
+126, 127, 126, 128, 126, 128, 124, 126, 124, 129, 126, 133, 137, 141, 152, 128, 122, 119, 117, 114, 125, 123, 128, 122, 132, 140, 127, 127, 127, 125, 117, 123, 124, 127, 118, 127, 127, 125, 121, 129, 126, 126, 135, 134, 137, 130, 130, 127, 119, 118, 142, 128, 137, 138, 128, 129, 120, 121, 121, 123, 113, 129, 123, 116, 126, 129, 123, 129, 133, 127, 134, 128, 133, 130, 131, 127, 135, 131, 125, 138, 128, 133, 126, 137, 126, 126, 131, 125, 128, 122, 132, 124, 128, 120, 126, 125, 120, 124, 124, 124, 121, 125, 120, 126, 120, 124, 127, 122, 122, 127, 128, 119, 132, 127, 124, 132, 128, 127, 132, 132, 128, 135, 132, 132, 139, 135, 136, 141, 141, 138, 141, 141, 143, 142, 140, 141, 143, 138, 137, 137, 137, 133, 128, 134, 128, 123, 122, 124, 115, 114, 117, 108, 109, 109, 106, 102, 106, 103, 102, 106, 99, 107, 106, 101, 107, 111, 100, 104, 110, 98, 106, 99, 97, 109, 113, 107, 126, 140, 131, 151, 157, 163, 171, 174, 180, 182, 174, 178, 177, 163, 161, 153, 145, 135, 129, 123, 117, 112, 110, 112, 107, 112, 116, 116, 119, 125, 127, 131, 135, 137, 139, 140, 141, 139, 136, 134, 131, 126, 123, 119, 116, 111, 109, 105, 103, 101, 97, 95, 92, 91, 87, 88, 90, 85, 91, 91, 89, 90, 97, 120, 100, 119, 152, 131, 145, 172, 167, 168, 184, 185, 186, 180, 181, 184, 164, 162, 162, 145, 136, 138, 126, 120, 119, 117, 116, 114, 119, 121, 121, 125, 131, 129, 131, 138, 134, 135, 137, 136, 133, 130, 128, 123, 120, 115, 110, 106, 100, 97, 93, 91, 89, 88, 85, 86, 90, 87, 87, 92, 90, 87, 106, 111, 101, 125, 143, 132, 145, 168, 163, 166, 178, 183, 180, 177, 183, 177, 166, 164, 161, 148, 141, 140, 130, 125, 124, 123, 121, 120, 125, 126, 125, 129, 130, 130, 131, 132, 130, 128, 126, 123, 119, 113, 110, 105, 100, 97, 92, 92, 89, 87, 88, 86, 88, 87, 84, 91, 88, 84, 102, 110, 99, 121, 141, 129, 145, 163, 161, 167, 176, 183, 181, 180, 184, 178, 169, 167, 162, 149, 144, 141, 132, 127, 126, 125, 123, 123, 125, 127, 127, 128, 131, 131, 129, 131, 128, 124, 122, 118, 112, 107, 102, 99, 94, 88, 90, 86, 81, 85, 82, 81, 84, 81, 83, 85, 96, 107, 103, 121, 138, 135, 145, 164, 166, 167, 180, 182, 181, 180, 180, 175, 166, 163, 157, 149, 140, 139, 132, 127, 127, 125, 127, 123, 128, 128, 127, 131, 131, 130, 129, 129, 126, 123, 119, 115, 110, 104, 102, 95, 91, 90, 85, 82, 83, 80, 80, 80, 80, 80, 85, 98, 101, 109, 122, 132, 139, 148, 163, 165, 171, 182, 182, 181, 182, 180, 172, 168, 162, 154, 147, 141, 136, 129, 129, 126, 127, 127, 125, 131, 129, 131, 132, 131, 132, 130, 129, 126, 121, 117, 115, 105, 103, 98, 90, 90, 86, 83, 80, 83, 79, 79, 82, 82, 85, 91, 97, 107, 114, 124, 137, 143, 154, 165, 170, 177, 183, 183, 185, 181, 177, 173, 163, 154, 148, 139, 132, 126, 122, 121, 119, 122, 125, 127, 131, 137, 138, 140, 143, 144, 141, 138, 136, 130, 124, 118, 113, 105, 100, 96, 91, 87, 83, 82, 80, 77, 79, 78, 77, 79, 88, 96, 88, 115, 121, 115, 143, 146, 154, 165, 174, 182, 184, 186, 192, 184, 178, 178, 164, 154, 148, 137, 129, 124, 117, 115, 115, 116, 118, 124, 129, 135, 137, 143, 145, 144, 144, 142, 140, 133, 132, 125, 118, 114, 106, 99, 93, 88, 84, 81, 80, 77, 76, 77, 76, 74, 73, 79, 93, 88, 102, 121, 116, 133, 148, 153, 162, 177, 179, 185, 190, 187, 188, 180, 176, 170, 161, 151, 146, 135, 127, 124, 118, 115, 116, 118, 118, 123, 130, 134, 136, 143, 145, 142, 144, 143, 137, 135, 130, 124, 119, 112, 106, 102, 98, 93, 92, 90, 90, 88, 90, 92, 92, 95, 100, 105, 109, 116, 123, 127, 132, 140, 145, 146, 151, 155, 155, 156, 157, 156, 153, 152, 151, 149, 147, 144, 142, 140, 137, 135, 134, 132, 130, 129, 127, 126, 125, 124, 123, 122, 122, 122, 121, 121, 121, 121, 120, 120, 120, 120, 120, 120, 119, 119, 118, 118, 117, 116, 115, 114, 113, 112, 112, 112, 113, 114, 115, 117, 119, 122, 126, 129, 132, 135, 138, 140, 142, 144, 145, 145, 145, 145, 144, 143, 142, 141, 140, 138, 136, 135, 133, 131, 130, 128, 127, 125, 124, 123, 122, 122, 121, 121, 122, 122, 122, 123, 124, 124, 125, 126, 126, 127, 127, 127, 127, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 118, 117, 117, 117, 118, 118, 120, 121, 123, 124, 127, 129, 131, 133, 135, 137, 139, 141, 142, 142, 142, 142, 144, 144, 141, 140, 137, 136, 137, 134, 128, 126, 127, 127, 125, 123, 123, 123, 123, 123, 123, 124, 124, 123, 124, 123, 123, 122, 121, 121, 120, 119, 120, 120, 118, 117, 116, 113, 109, 105, 99, 97, 96, 100, 103, 101, 108, 117, 122, 124, 132, 144, 146, 150, 156, 158, 161, 160, 158, 153, 151, 149, 143, 140, 138, 137, 134, 131, 132, 131, 129, 130, 130, 131, 133, 132, 132, 135, 135, 134, 135, 135, 134, 133, 134, 132, 132, 131, 130, 126, 124, 121, 114, 107, 101, 95, 86, 77, 74, 68, 65, 63, 60, 66, 71, 75, 93, 116, 116, 128, 155, 160, 162, 178, 189, 189, 187, 191, 187, 179, 169, 160, 159, 143, 135, 130, 124, 116, 112, 115, 112, 113, 115, 119, 123, 127, 131, 135, 137, 138, 139, 141, 140, 139, 139, 139, 139, 137, 137, 137, 135, 131, 130, 125, 120, 114, 107, 100, 92, 84, 77, 71, 66, 60, 59, 55, 56, 63, 67, 85, 91, 108, 124, 128, 148, 159, 163, 178, 185, 188, 191, 191, 186, 182, 175, 162, 159, 146, 136, 132, 122, 117, 113, 112, 108, 112, 113, 114, 121, 123, 128, 134, 134, 138, 140, 140, 143, 143, 144, 144, 143, 142, 141, 137, 133, 129, 123, 117, 109, 103, 95, 88, 80, 76, 70, 64, 61, 57, 54, 60, 67, 70, 85, 103, 113, 125, 151, 161, 168, 190, 197, 198, 205, 206, 197, 190, 184, 172, 162, 150, 139, 132, 123, 118, 117, 117, 114, 119, 122, 121, 124, 128, 127, 128, 130, 129, 130, 132, 130, 132, 136, 134, 134, 139, 139, 136, 140, 139, 132, 130, 127, 121, 114, 109, 101, 93, 86, 78, 70, 63, 55, 50, 44, 43, 61, 64, 67, 99, 113, 116, 145, 170, 168, 186, 207, 205, 207, 213, 206, 194, 190, 178, 166, 154, 142, 134, 123, 118, 117, 116, 113, 117, 121, 120, 123, 126, 124, 125, 127, 127, 126, 128, 130, 131, 132, 136, 138, 137, 141, 143, 142, 142, 142, 137, 132, 129, 120, 113, 105, 97, 86, 79, 72, 63, 59, 52, 48, 48, 61, 66, 67, 96, 111, 113, 137, 160, 163, 176, 195, 197, 199, 203, 200, 193, 186, 177, 166, 155, 143, 134, 125, 118, 115, 113, 113, 114, 117, 119, 122, 123, 124, 126, 126, 126, 126, 125, 126, 129, 127, 129, 137, 138, 138, 144, 149, 146, 147, 148, 143, 136, 132, 125, 111, 104, 96, 86, 74, 69, 64, 56, 50, 56, 81, 74, 78, 124, 130, 123, 156, 178, 164, 173, 193, 183, 175, 174, 171, 158, 145, 142, 139, 125, 118, 124, 119, 113, 118, 123, 120, 120, 127, 128, 126, 127, 131, 130, 127, 129, 131, 129, 128, 134, 136, 134, 139, 143, 143, 141, 144, 144, 139, 134, 133, 127, 115, 110, 103, 92, 83, 80, 73, 68, 68, 72, 88, 93, 100, 125, 143, 144, 159, 182, 179, 178, 185, 185, 171, 160, 156, 144, 127, 113, 112, 105, 94, 96, 105, 107, 109, 125, 135, 139, 147, 157, 160, 157, 156, 153, 145, 134, 125, 118, 108, 100, 96, 96, 95, 97, 104, 110, 116, 124, 133, 140, 144, 149, 151, 151, 149, 146, 141, 135, 130, 123, 118, 115, 113, 111, 112, 115, 118, 122, 126, 131, 135, 137, 141, 142, 141, 139, 137, 132, 128, 124, 120, 117, 114, 114, 114, 115, 117, 121, 125, 129, 132, 135, 137, 138, 138, 138, 136, 133, 132, 129, 126, 123, 122, 121, 120, 120, 121, 123, 124, 126, 128, 129, 130, 130, 131, 131, 131, 130, 129, 128, 127, 127, 126, 126, 126, 126, 127, 127, 128, 128, 129, 129, 129, 129, 129, 129, 127, 127, 127, 126, 125, 126, 125, 126, 127, 127, 128, 129, 130, 130, 130, 131, 131, 130, 129, 129, 127, 126, 126, 126, 125, 124, 125, 126, 126, 126, 127, 128, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 127, 127, 127, 127, 127, 127, 128, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 128, 128, 128, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 127, 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 128, 127, 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 128, 128, 127, 127, 127, 127, 127, 128, 128, 128, 128, 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 127, 127, 127, 126, 126, 127, 127, 127, 128, 128, 128, 128, 127, 126, 126, 126, 126, 126, 127, 128, 129, 129, 128, 127, 126, 125, 125, 125, 126, 127, 129, 129, 130, 131, 131, 129, 134, 158, 141, 124, 136, 142, 123, 116, 130, 131, 132, 135, 136, 135, 140, 131, 116, 121, 126, 115, 108, 112, 110, 107, 110, 117, 123, 114, 98, 87, 87, 81, 76, 83, 103, 158, 179, 163, 169, 189, 176, 139, 124, 121, 115, 104, 100, 105, 128, 146, 144, 150, 170, 172, 148, 130, 125, 123, 112, 105, 110, 123, 139, 141, 139, 148, 152, 138, 120, 112, 108, 103, 102, 108, 119, 134, 145, 150, 153, 153, 146, 130, 120, 112, 110, 116, 125, 135, 147, 161, 161, 156, 151, 138, 117, 102, 96, 95, 98, 108, 126, 141, 150, 149, 147, 143, 132, 118, 111, 105, 102, 106, 107, 110, 120, 126, 119, 118, 113, 109, 93, 75, 65, 65, 73, 78, 97, 151, 203, 196, 184, 189, 184, 148, 115, 99, 102, 116, 117, 121, 143, 169, 174, 166, 161, 152, 135, 116, 99, 92, 101, 113, 122, 141, 161, 170, 168, 162, 148, 130, 114, 108, 107, 105, 112, 124, 131, 133, 137, 132, 121, 110, 99, 94, 90, 81, 80, 89, 91, 84, 83, 87, 84, 80, 95, 108, 147, 190, 193, 187, 193, 189, 157, 134, 123, 119, 115, 119, 130, 143, 157, 163, 163, 161, 157, 144, 133, 120, 114, 113, 116, 120, 130, 140, 147, 148, 150, 153, 146, 141, 137, 130, 124, 127, 124, 122, 125, 124, 120, 115, 104, 94, 91, 90, 89, 78, 67, 69, 70, 75, 57, 48, 70, 93, 103, 127, 190, 220, 214, 178, 156, 153, 139, 111, 99, 117, 138, 150, 149, 156, 168, 169, 156, 142, 137, 136, 127, 120, 120, 126, 132, 133, 138, 142, 139, 137, 139, 142, 137, 138, 143, 141, 131, 125, 120, 117, 111, 102, 98, 99, 97, 91, 89, 89, 84, 73, 71, 69, 72, 73, 67, 63, 132, 205, 207, 182, 171, 174, 165, 142, 102, 115, 146, 146, 140, 152, 161, 166, 161, 148, 145, 147, 137, 126, 126, 127, 133, 137, 135, 134, 141, 140, 136, 138, 139, 138, 138, 135, 130, 123, 116, 112, 110, 103, 98, 97, 92, 86, 82, 85, 81, 73, 69, 70, 64, 73, 78, 74, 89, 156, 225, 221, 187, 169, 165, 147, 135, 119, 112, 135, 161, 162, 159, 156, 151, 159, 158, 142, 130, 137, 143, 141, 131, 123, 124, 132, 132, 126, 124, 129, 133, 128, 118, 111, 112, 113, 110, 104, 105, 108, 106, 95, 88, 81, 81, 86, 83, 77, 81, 77, 75, 93, 101, 101, 115, 201, 241, 205, 173, 163, 155, 136, 125, 113, 134, 159, 164, 154, 153, 155, 158, 154, 140, 134, 137, 140, 132, 126, 124, 128, 131, 131, 130, 133, 131, 126, 121, 115, 114, 113, 111, 110, 109, 105, 99, 95, 94, 96, 95, 91, 90, 86, 91, 93, 93, 88, 87, 92, 100, 89, 98, 201, 255, 227, 185, 171, 169, 160, 138, 112, 121, 146, 164, 162, 156, 148, 152, 156, 144, 131, 132, 135, 132, 129, 123, 124, 129, 131, 129, 129, 129, 127, 123, 121, 120, 121, 119, 115, 114, 114, 109, 102, 100, 102, 103, 99, 97, 99, 95, 92, 89, 95, 94, 93, 96, 101, 111, 102, 88, 147, 223, 224, 191, 166, 157, 157, 156, 131, 124, 142, 159, 164, 158, 143, 136, 147, 150, 139, 132, 134, 137, 140, 135, 127, 127, 133, 133, 129, 122, 119, 120, 120, 118, 118, 120, 123, 124, 121, 115, 109, 104, 101, 102, 104, 104, 103, 103, 99, 95, 95, 97, 103, 112, 106, 104, 109, 111, 114, 112, 114, 153, 191, 191, 175, 166, 155, 151, 160, 155, 146, 146, 148, 149, 150, 138, 133, 141, 147, 146, 140, 131, 124, 128, 131, 126, 122, 124, 129, 134, 133, 126, 122, 123, 122, 121, 119, 116, 112, 114, 114, 113, 114, 114, 114, 113, 111, 105, 105, 103, 103, 102, 101, 99, 98, 100, 101, 103, 110, 116, 120, 118, 111, 101, 123, 179, 206, 203, 182, 163, 159, 169, 157, 143, 137, 138, 152, 159, 154, 138, 141, 143, 145, 143, 136, 125, 125, 132, 129, 131, 129, 127, 130, 138, 133, 124, 124, 122, 124, 126, 125, 121, 121, 118, 116, 120, 120, 119, 116, 111, 109, 109, 109, 105, 105, 103, 103, 101, 98, 95, 90, 86, 92, 98, 101, 104, 103, 114, 119, 119, 114, 113, 127, 171, 199, 191, 186, 183, 177, 168, 165, 155, 141, 139, 140, 144, 153, 151, 143, 140, 146, 144, 140, 133, 124, 124, 128, 130, 129, 128, 126, 129, 134, 135, 130, 124, 123, 125, 126, 128, 127, 125, 124, 126, 124, 119, 118, 118, 113, 109, 110, 109, 109, 108, 109, 109, 108, 104, 103, 104, 105, 107, 104, 104, 106, 110, 111, 108, 108, 111, 111, 105, 107, 113, 115, 110, 112, 137, 162, 172, 174, 181, 189, 191, 195, 192, 188, 185, 179, 171, 165, 161, 155, 147, 138, 132, 129, 124, 116, 111, 106, 102, 100, 100, 98, 98, 101, 103, 104, 109, 116, 120, 127, 133, 137, 143, 150, 152, 155, 160, 160, 158, 156, 152, 146, 142, 138, 131, 124, 115, 106, 97, 92, 87, 85, 83, 81, 79, 80, 81, 82, 86, 89, 91, 94, 98, 101, 104, 109, 114, 115, 114, 114, 115, 115, 114, 113, 116, 123, 128, 131, 138, 152, 166, 169, 173, 184, 194, 196, 195, 197, 198, 194, 190, 184, 176, 168, 160, 150, 140, 131, 124, 118, 111, 104, 100, 98, 95, 93, 93, 95, 96, 98, 101, 104, 108, 114, 118, 124, 128, 134, 138, 143, 147, 150, 152, 153, 154, 152, 152, 150, 147, 144, 141, 136, 130, 126, 120, 114, 109, 106, 102, 99, 96, 93, 92, 92, 91, 91, 92, 94, 95, 96, 98, 101, 103, 104, 106, 106, 107, 111, 113, 113, 114, 117, 117, 118, 118, 116, 115, 122, 128, 128, 127, 135, 144, 151, 161, 164, 168, 178, 187, 186, 189, 194, 195, 194, 189, 183, 178, 175, 167, 159, 151, 143, 134, 128, 121, 114, 108, 102, 98, 94, 90, 87, 88, 92, 94, 93, 96, 102, 107, 111, 117, 124, 130, 137, 142, 146, 151, 156, 159, 160, 161, 159, 157, 154, 152, 147, 142, 137, 131, 124, 119, 114, 109, 105, 101, 97, 94, 92, 90, 89, 89, 89, 89, 90, 91, 92, 94, 97, 100, 100, 103, 104, 105, 109, 115, 115, 114, 116, 119, 120, 121, 119, 116, 118, 126, 128, 127, 130, 140, 146, 156, 163, 164, 172, 184, 188, 186, 192, 195, 195, 192, 186, 180, 177, 171, 161, 154, 146, 137, 129, 123, 117, 110, 103, 98, 94, 91, 88, 86, 88, 93, 95, 95, 100, 107, 113, 117, 124, 131, 139, 143, 147, 153, 158, 161, 162, 162, 161, 159, 155, 151, 147, 142, 136, 129, 122, 116, 110, 104, 100, 96, 92, 90, 88, 86, 87, 89, 90, 91, 92, 97, 99, 101, 104, 110, 113, 110, 115, 122, 121, 119, 121, 126, 127, 125, 123, 126, 128, 124, 122, 123, 123, 120, 123, 127, 127, 129, 136, 145, 149, 153, 160, 169, 173, 175, 179, 183, 186, 184, 181, 177, 174, 170, 163, 156, 150, 144, 137, 130, 124, 120, 116, 111, 107, 105, 104, 102, 101, 103, 105, 106, 107, 110, 113, 116, 119, 123, 125, 128, 131, 132, 134, 135, 136, 136, 136, 135, 134, 133, 132, 131, 129, 127, 125, 123, 122, 120, 118, 116, 114, 113, 112, 110, 109, 109, 109, 108, 108, 109, 110, 111, 113, 115, 117, 118, 119, 121, 125, 127, 127, 129, 131, 132, 131, 130, 129, 131, 130, 127, 125, 123, 123, 122, 119, 115, 123, 131, 126, 123, 135, 145, 147, 153, 160, 166, 170, 174, 176, 181, 184, 184, 184, 180, 174, 171, 169, 162, 156, 150, 144, 137, 130, 124, 121, 118, 113, 108, 106, 104, 102, 103, 104, 104, 106, 108, 109, 112, 115, 118, 122, 126, 127, 129, 132, 134, 135, 136, 136, 136, 136, 134, 132, 131, 131, 129, 127, 124, 123, 121, 119, 117, 116, 114, 113, 112, 111, 110, 109, 110, 110, 110, 111, 111, 112, 113, 115, 117, 118, 120, 122, 123, 124, 127, 128, 127, 129, 131, 130, 128, 129, 129,
+};
+
+
+/* get our radio ready */
+
+void setup() {
+ Wire.begin();
+ Serial.begin(9600);
+ Serial.print("Radio status: ");
+ int result = radio.testConnection();
+ Serial.println(result);
+ radio.initialize();
+ radio.setFrequency(446000);
+ radio.setVolume1(0xF);
+ radio.setVolume2(0xF);
+ radio.setModeReceive();
+ radio.setTxSourceMic();
+ radio.setSQLoThresh(80);
+ radio.setSQOn();
+}
+
+/* main program loop */
+
+
+void loop() {
+ rssi = radio.readRSSI();
+ if(rssi > -120) {
+ for(;;) {
+ rssi = radio.readRSSI();
+ if(rssi < -120) { break; }
+ if(rssi > peak) { peak = rssi; Serial.print("New peak: "); Serial.println(rssi); }
+ }
+ }
+
+ if(rssi < -120) {
+ Serial.println("Transmit On");
+ radio.setTX(1);
+ delay(250);
+ tone(11,1000,500);
+ delay(1000);
+ itoa(peak,sig,10);
+ Serial.print(sig);
+ Serial.print(" dBm...");
+ for(int x = 0; x < strlen(sig); x++) {
+ if(sig[x] = '0') { startPlayback(zero, sizeof(zero)); }
+ if(sig[x] = '1') { startPlayback(one, sizeof(one)); }
+ if(sig[x] = '2') { startPlayback(two, sizeof(two)); }
+ if(sig[x] = '3') { startPlayback(three, sizeof(three)); }
+ if(sig[x] = '4') { startPlayback(four, sizeof(four)); }
+ if(sig[x] = '5') { startPlayback(five, sizeof(five)); }
+ if(sig[x] = '6') { startPlayback(six, sizeof(six)); }
+ if(sig[x] = '7') { startPlayback(seven, sizeof(seven)); }
+ if(sig[x] = '8') { startPlayback(eight, sizeof(eight)); }
+ if(sig[x] = '9') { startPlayback(nine, sizeof(nine)); }
+ if(sig[x] = '-') { startPlayback(minus, sizeof(minus)); }
+ delay(1000);
+ }
+ startPlayback(dbm,sizeof(dbm));
+ delay(2000);
+ tone(11,1000,500);
+ delay(1000);
+ Serial.println("done!");
+ radio.morseOut(CALLSIGN);
+ radio.setTX(0);
+ Serial.println("Transmit off");
+ radio.setModeReceive();
+ delay(1000);
+ }
+}
+
diff --git a/examples/SignalTest/Sounds/0.wav b/examples/SignalTest/Sounds/0.wav
new file mode 100755
index 0000000..a580efc
Binary files /dev/null and b/examples/SignalTest/Sounds/0.wav differ
diff --git a/examples/SignalTest/Sounds/1.wav b/examples/SignalTest/Sounds/1.wav
new file mode 100755
index 0000000..327b3bf
Binary files /dev/null and b/examples/SignalTest/Sounds/1.wav differ
diff --git a/examples/SignalTest/Sounds/2.wav b/examples/SignalTest/Sounds/2.wav
new file mode 100755
index 0000000..f2fe384
Binary files /dev/null and b/examples/SignalTest/Sounds/2.wav differ
diff --git a/examples/SignalTest/Sounds/3.wav b/examples/SignalTest/Sounds/3.wav
new file mode 100755
index 0000000..e8ded20
Binary files /dev/null and b/examples/SignalTest/Sounds/3.wav differ
diff --git a/examples/SignalTest/Sounds/4.wav b/examples/SignalTest/Sounds/4.wav
new file mode 100755
index 0000000..b5c3807
Binary files /dev/null and b/examples/SignalTest/Sounds/4.wav differ
diff --git a/examples/SignalTest/Sounds/5.wav b/examples/SignalTest/Sounds/5.wav
new file mode 100755
index 0000000..be9a31b
Binary files /dev/null and b/examples/SignalTest/Sounds/5.wav differ
diff --git a/examples/SignalTest/Sounds/6.wav b/examples/SignalTest/Sounds/6.wav
new file mode 100755
index 0000000..6eb054c
Binary files /dev/null and b/examples/SignalTest/Sounds/6.wav differ
diff --git a/examples/SignalTest/Sounds/7.wav b/examples/SignalTest/Sounds/7.wav
new file mode 100755
index 0000000..bf01012
Binary files /dev/null and b/examples/SignalTest/Sounds/7.wav differ
diff --git a/examples/SignalTest/Sounds/8.wav b/examples/SignalTest/Sounds/8.wav
new file mode 100755
index 0000000..05c474c
Binary files /dev/null and b/examples/SignalTest/Sounds/8.wav differ
diff --git a/examples/SignalTest/Sounds/9.wav b/examples/SignalTest/Sounds/9.wav
new file mode 100755
index 0000000..3bcd22d
Binary files /dev/null and b/examples/SignalTest/Sounds/9.wav differ
diff --git a/examples/SignalTest/Sounds/dbm.wav b/examples/SignalTest/Sounds/dbm.wav
new file mode 100755
index 0000000..e51c41b
Binary files /dev/null and b/examples/SignalTest/Sounds/dbm.wav differ
diff --git a/examples/SignalTest/Sounds/minus.wav b/examples/SignalTest/Sounds/minus.wav
new file mode 100755
index 0000000..8b85cd0
Binary files /dev/null and b/examples/SignalTest/Sounds/minus.wav differ
diff --git a/keywords.txt b/keywords.txt
new file mode 100644
index 0000000..10692e5
--- /dev/null
+++ b/keywords.txt
@@ -0,0 +1,30 @@
+#######################################
+# Syntax Coloring Map HAMShield
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+#SD KEYWORD1
+#File KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+#begin KEYWORD2
+#exists KEYWORD2
+#mkdir KEYWORD2
+#remove KEYWORD2
+#rmdir KEYWORD2
+#open KEYWORD2
+#close KEYWORD2
+#seek KEYWORD2
+#position KEYWORD2
+#size KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+#FILE_READ LITERAL1
+#FILE_WRITE LITERAL1
diff --git a/src/HamShield.cpp b/src/HamShield.cpp
new file mode 100644
index 0000000..7e7dab0
--- /dev/null
+++ b/src/HamShield.cpp
@@ -0,0 +1,1362 @@
+// HAMShield library collection
+// Based on Programming Manual rev. 2.0, 5/19/2011 (RM-MPU-6000A-00)
+// 11/22/2013 by Morgan Redfield
+// 04/26/2015 various changes Casey Halverson
+
+
+#include "HAMShield.h"
+#include
+// #include
+
+/* don't change this regulatory value, use dangerMode() and safeMode() instead */
+
+bool restrictions = true;
+
+/* channel lookup tables */
+
+uint32_t FRS[] = {0,462562,462587,462612,462637,462662,462687,462712,467562,467587,467612,467637,467662,467687,467712};
+
+uint32_t GMRS[] = {0,462550,462575,462600,462625,462650,462675,462700,462725};
+
+uint32_t MURS[] = {0,151820,151880,151940,154570,154600};
+
+uint32_t WX[] = {0,162550,162400,162475,162425,162450,162500,162525};
+
+/* morse code lookup table */
+
+const char *ascii = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,?'!/()&:;=+-_\"$@",
+ *itu[] = { ".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----.",".-.-.-","--..--","..--..",".----.","-.-.--","-..-.","-.--.","-.--.-",".-...","---...","-.-.-.","-...-",".-.-.","-....-","..--.-",".-..-.","...-..-",".--.-."
+ };
+
+/* 2200 Hz */
+
+const unsigned char AFSK_mark[] PROGMEM = { 154, 249, 91, 11, 205, 216, 25, 68, 251, 146, 0, 147, 250, 68, 24, 218, 203, 13, 88, 254, 128, 1, 167, 242, 52, 37, 231, 186, 5, 108, 255, 108, 5, 186, 231, 37, 52, 242, 167, 1, 128, 254, 88, 13, 203, 218, 24, 69, 250, 147, 0, 147, 250, 69, 24, 218, 203, 13, 88, 255, 127, 2, 165, 245, 48 };
+
+/* 1200 Hz */
+
+const unsigned char AFSK_space[] PROGMEM = { 140, 228, 250, 166, 53, 0, 53, 166, 249, 230, 128, 24, 7, 88, 203, 255, 203, 88, 7, 24, 128, 230, 249, 167, 53, 0, 53, 167, 249, 230, 128, 24, 6, 88, 202, 255, 202, 88, 6, 24, 127, 231, 249, 167, 52, 0, 52, 167, 248, 231, 127, 25, 6, 89, 202, 255, 202, 89, 6, 25, 127, 231, 248, 167, 53, 0, 54, 165, 251, 227, 133, 14};
+
+
+/* Aux button variables */
+
+volatile int ptt = false;
+volatile long bouncer = 0;
+
+/** Default constructor, uses default I2C address.
+ * @see A1846S_DEFAULT_ADDRESS
+ */
+HAMShield::HAMShield() {
+ devAddr = A1846S_DEV_ADDR_SENLOW;
+}
+
+/** Specific address constructor.
+ * @param address I2C address
+ * @see A1846S_DEFAULT_ADDRESS
+ * @see A1846S_ADDRESS_AD0_LOW
+ * @see A1846S_ADDRESS_AD0_HIGH
+ */
+HAMShield::HAMShield(uint8_t address) {
+ devAddr = address;
+}
+
+/** Power on and prepare for general usage.
+ *
+ */
+void HAMShield::initialize() {
+ // set up PWM output for RF power control - commenting out to get rid of terrible buzzing noise
+ // pwr_control_pin = 9;
+
+
+ // Note: these initial settings are for UHF 12.5kHz channel
+ // see the A1846S register table and initial settings for more info
+
+ // TODO: update code to make it easier to change from VHF to UHF and 12.5kHz channel to 25kHz channel
+ uint16_t tx_data;
+
+ // reset all registers in A1846S
+ softReset();
+ // set pdn_reg bit in control register (0 or 1?) (now done in softReset)
+ //I2Cdev::writeBitW(devAddr, A1846S_CTL_REG, A1846S_PWR_DWN_BIT, 1);
+ tx_data = 0x0698;
+ I2Cdev::writeWord(devAddr, 0x02, tx_data); // why is this here? See A1846S register init table
+
+ //set up clock to ues 12-14MHz
+ setClkMode(1);
+
+ // set up clock to use 12.8MHz crystal
+ setXtalFreq(12800);
+ // set up ADClk frequency to 6.4MHz
+ setAdcClkFreq(6400);
+
+ tx_data = 0xE000;
+ I2Cdev::writeWord(devAddr, 0x24, tx_data); // why is this here? See A1846S register init word doc
+
+ //could change GPIO voltage levels with writes to 0x08 and 0x09
+ // see A1846S register init table
+ tx_data = 0x03AC;
+ I2Cdev::writeWord(devAddr, 0x09, tx_data); // why is this here? See A1846S register init word doc
+
+ // set PA_bias voltage to 1.68V (and do something else too? what's the 3 for?)
+ tx_data = 0x0320;
+ I2Cdev::writeWord(devAddr, 0x0A, tx_data);
+
+ tx_data = 0x1A10;
+ I2Cdev::writeWord(devAddr, 0x0B, tx_data); // why is this here? See A1846S register init table
+
+ tx_data = 0x3E37;
+ I2Cdev::writeWord(devAddr, 0x11, tx_data); // why is this here? See A1846S register init table
+
+ // Automatic Gain Control stuff
+ // AGC when band is UHF,0x32 = 0x627C;when band is VHF,0x32 = 0x62BC//
+ tx_data = 0x627c; // this is uhf, for vhf set to 0x62bc
+ I2Cdev::writeWord(devAddr, 0x32, tx_data); // why is this here? See A1846S register init table
+ tx_data = 0x0AF2;
+ I2Cdev::writeWord(devAddr, 0x33, tx_data); // why is this here? See A1846S register init table
+
+ // why is this here? See A1846S register init word doc
+ tx_data = 0x0F28; // this is uhf, for vhf set to 0x62bc
+ I2Cdev::writeWord(devAddr, 0x3C, tx_data); // why is this here? See A1846S register init table
+ tx_data = 0x200B;
+ I2Cdev::writeWord(devAddr, 0x3D, tx_data); // why is this here? See A1846S register init table
+
+ // Noise threshold settings
+ tx_data = 0x1C2F; // see email from Iris
+ I2Cdev::writeWord(devAddr, 0x47, tx_data); // why is this here? See A1846S register init table
+
+ // SNR LPF settings, sq settings
+ tx_data = 0x293A;
+ I2Cdev::writeWord(devAddr, 0x4e, tx_data); // why is this here? See A1846S register init table
+
+ // subaudio decode setting,sq_out_sel,noise threshold value db
+ tx_data = 0x114A; // A1846S_SQ_OUT_SEL_REG is 0x54
+ I2Cdev::writeWord(devAddr, A1846S_SQ_OUT_SEL_REG, tx_data); // why is this here? See A1846S register init table
+
+ // bandwide setting of filter when RSSI is high or low
+ tx_data = 0x0652;
+ I2Cdev::writeWord(devAddr, 0x56, tx_data); // why is this here? See A1846S register init table
+
+ tx_data = 0x062d;
+ I2Cdev::writeWord(devAddr, 0x6e, tx_data); // why is this here? See A1846S register init table
+
+ // note, this is for 12.5kHz channel
+ tx_data = 0x6C1E;
+ I2Cdev::writeWord(devAddr, 0x71, tx_data); // why is this here? See A1846S register init table
+
+ // see A1846S register init doc for this
+ tx_data = 0x00FF;
+ I2Cdev::writeWord(devAddr, 0x44, tx_data); // why is this here? See A1846S register init table
+ tx_data = 0x0500;
+ I2Cdev::writeWord(devAddr, 0x1F, tx_data); // set up GPIO for RX/TX mirroring
+
+
+ // set RFoutput power (note that the address is 0x85, so do some rigmaroll)
+ tx_data = 0x1;
+ I2Cdev::writeWord(devAddr, 0x7F, tx_data); // prep to write to a reg > 0x7F
+ // If 0x85 is 0x001F, Rfoutput power is 8dBm , ACP is -63dB in 12.5KHz and -65dB in 25KHz
+ // If 0x85 is 0x0018, Rfoutput power is 6dBm , ACP is -64dB in 12.5KHz and -66dB in 25KHz
+ // If 0x85 is 0x0017, Rfoutput power is -3dBm , ACP is -68dBc in 12.5KHz and -68dBc in 25KHz
+ tx_data = 0x001F;
+ I2Cdev::writeWord(devAddr, 0x5, tx_data); // set output power, reg 0x85 - 0x80
+ tx_data = 0x0;
+ I2Cdev::writeWord(devAddr, 0x7F, tx_data); // finish writing to a reg > 0x7F
+
+ // set control reg for pdn_reg, rx, and mute when rxno
+ tx_data = 0xA4;
+ I2Cdev::writeWord(devAddr, A1846S_CTL_REG, tx_data); // finish writing to a reg > 0x7F
+
+ delay(100);
+
+ // set control reg for chip_cal_en, pdn_reg, rx, and mute when rxno
+ tx_data = 0xA6;
+ I2Cdev::writeWord(devAddr, A1846S_CTL_REG, tx_data); // finish writing to a reg > 0x7F
+
+ delay(100);
+
+ // set control reg for chip_cal_en, pdn_reg
+ tx_data = 0x6;
+ I2Cdev::writeWord(devAddr, A1846S_CTL_REG, tx_data); // finish writing to a reg > 0x7F
+
+ delay(100);
+
+ // and then I have no idea about this nonsense
+ // some of these settings seem to be for 12.5kHz channels
+ // TODO: get A1846S to give us a full register table
+ tx_data = 0x1d40;
+ I2Cdev::writeWord(devAddr, 0x54, tx_data);
+ tx_data = 0x062d;
+ I2Cdev::writeWord(devAddr, 0x6e, tx_data);
+ tx_data = 0x102a;
+ I2Cdev::writeWord(devAddr, 0x70, tx_data);
+ tx_data = 0x6c1e;
+ I2Cdev::writeWord(devAddr, 0x71, tx_data);
+ tx_data = 0x0006;
+ I2Cdev::writeWord(devAddr, 0x30, tx_data);
+
+ delay(100);
+
+ // setup default values
+
+ setFrequency(446000);
+ setVolume1(0xF);
+ setVolume2(0xF);
+ setModeReceive();
+ setTxSourceMic();
+ setSQLoThresh(80);
+ setSQOn();
+
+}
+
+/** Verify the I2C connection.
+ * Make sure the device is connected and responds as expected.
+ * @return True if connection is valid, false otherwise
+ */
+bool HAMShield::testConnection() {
+ I2Cdev::readWord(devAddr, 0x09, radio_i2c_buf);
+// 03ac or 032c
+ return radio_i2c_buf[0] == 0x03AC; // TODO: find a device ID reg I can use
+}
+
+
+/** A1846S each register write is 24-bit long, including a
+ * r/nw bit, 7-bit register address , and 16-bit data (MSB
+ * is the first bit).
+ * R/W, A[6:0], D[15:0]
+ *
+ * Note (this shouldn't be necessary, since all ctl registers are below 0x7F)
+ * If register address is more than 7FH, first write 0x0001
+ * to 7FH, and then write value to the address subtracted by
+ * 80H. Finally write 0x0000 to 7FH
+ * Example: writing 85H register address is 0x001F .
+ * Move 7FH 0x0001{
+
+}
+ * Move 05H 0x001F{
+
+} 05H=85H-80H
+ * Move 7FH 0x0000{
+
+}
+ */
+
+uint16_t HAMShield::readCtlReg() {
+ I2Cdev::readWord(devAddr, A1846S_CTL_REG, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+void HAMShield::softReset() {
+ uint16_t tx_data = 0x1;
+ I2Cdev::writeWord(devAddr, A1846S_CTL_REG, tx_data);
+ delay(100); // Note: see A1846S setup info for timing guidelines
+ tx_data = 0x4;
+ I2Cdev::writeWord(devAddr, A1846S_CTL_REG, tx_data);
+}
+
+
+void HAMShield::setFrequency(uint32_t freq_khz) {
+ radio_frequency = freq_khz;
+ uint32_t freq_raw = freq_khz << 3; // shift by 3 to multiply by 8
+
+ // send top 16 bits to A1846S_FREQ_HI_REG
+ uint16_t freq_half = (uint16_t) (0x3FFF & (freq_raw >> 16));
+ I2Cdev::writeWord(devAddr, A1846S_FREQ_HI_REG, freq_half);
+ // send bottom 16 bits to A1846S_FREQ_LO_REG
+ freq_half = (uint16_t) (freq_raw & 0xFFFF);
+ I2Cdev::writeWord(devAddr, A1846S_FREQ_LO_REG, freq_half);
+}
+
+uint32_t HAMShield::getFrequency() {
+ return radio_frequency;
+}
+
+void HAMShield::setUHF() {
+ setGpioHi(2); // turn off VHF
+ setGpioLow(3); // turn on UHF
+}
+
+void HAMShield::setVHF() {
+ setGpioHi(3); // turn off UHF
+ setGpioLow(2); // turn on VHF
+}
+
+void HAMShield::setNoFilters() {
+ setGpioHi(3); // turn off UHF
+ setGpioHi(2); // turn off VHF
+}
+
+// band
+// 00 - 400-520MHz
+// 10 - 200-260MHz
+// 11 - 134-174MHz
+// TODO: add write to 0x32 based on band selection
+void HAMShield::setBand(uint16_t band){
+ if (band == 0) {
+ setUHF();
+ } else if (band == 2) {
+ // not quite in the band for our filters, but use VHF
+ setVHF();
+ } else if (band == 3) {
+ setVHF();
+ } else {
+ // illegal write code, turn UHF and VHF channels both off
+ setNoFilters();
+ // turn off transmit as well to make sure we don't break anything
+ setTX(0);
+ }
+ I2Cdev::writeBitsW(devAddr, A1846S_BAND_SEL_REG, A1846S_BAND_SEL_BIT, A1846S_BAND_SEL_LENGTH, band);
+}
+uint16_t HAMShield::getBand(){
+ I2Cdev::readBitsW(devAddr, A1846S_BAND_SEL_REG, A1846S_BAND_SEL_BIT, A1846S_BAND_SEL_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// xtal frequency (kHz)
+// 12-14MHz crystal: this reg is set to crystal freq_khz
+// 24-28MHz crystal: this reg is set to crystal freq_khz / 2
+void HAMShield::setXtalFreq(uint16_t freq_kHz){
+ I2Cdev::writeWord(devAddr, A1846S_XTAL_FREQ_REG, freq_kHz);
+}
+uint16_t HAMShield::getXtalFreq(){
+ I2Cdev::readWord(devAddr, A1846S_FREQ_HI_REG, radio_i2c_buf);
+
+ return radio_i2c_buf[0];
+}
+
+// adclk frequency (kHz)
+// 12-14MHz crystal: this reg is set to crystal freq_khz / 2
+// 24-28MHz crystal: this reg is set to crystal freq_khz / 4
+void HAMShield::setAdcClkFreq(uint16_t freq_kHz){
+ I2Cdev::writeWord(devAddr, A1846S_ADCLK_FREQ_REG, freq_kHz);
+}
+
+uint16_t HAMShield::getAdcClkFreq(){
+ I2Cdev::readWord(devAddr, A1846S_ADCLK_FREQ_REG, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// clk mode
+// 12-14MHz: set to 1
+// 24-28MHz: set to 0
+void HAMShield::setClkMode(bool LFClk){
+ // include upper bits as default values
+ uint16_t tx_data = 0x0F11; // NOTE: should this be 0fd1 or 0f11? Programming guide and setup guide disagree
+ if (!LFClk) {
+ tx_data = 0x0F10;
+ }
+
+ I2Cdev::writeWord(devAddr, A1846S_CLK_MODE_REG, tx_data);
+}
+bool HAMShield::getClkMode(){
+ I2Cdev::readBitW(devAddr, A1846S_CLK_MODE_REG, A1846S_CLK_MODE_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// clk example
+// 12.8MHz clock
+// A1846S_XTAL_FREQ_REG[15:0]= xtal_freq<15:0>=12.8*1000=12800
+// A1846S_ADCLK_FREQ_REG[12:0] =adclk_freq<15:0>=(12.8/2)*1000=6400
+// A1846S_CLK_MODE_REG[0]= clk_mode =1
+
+// TX/RX control
+
+// channel mode
+// 11 - 25kHz channel
+// 00 - 12.5kHz channel
+// 10,01 - reserved
+void HAMShield::setChanMode(uint16_t mode){
+ I2Cdev::writeBitsW(devAddr, A1846S_CTL_REG, A1846S_CHAN_MODE_BIT, A1846S_CHAN_MODE_LENGTH, mode);
+}
+uint16_t HAMShield::getChanMode(){
+ I2Cdev::readBitsW(devAddr, A1846S_CTL_REG, A1846S_CHAN_MODE_BIT, A1846S_CHAN_MODE_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// choose tx or rx
+void HAMShield::setTX(bool on_noff){
+ // make sure RX is off
+ if (on_noff) {
+ setRX(false);
+
+ // For RF6886:
+ // first turn on power
+ // set RX output on
+ setGpioHi(4); // remember that RX and TX are active low
+ // set TX output off
+ setGpioLow(5); // remember that RX and TX are active low
+ // then turn on VREG (PWM output)
+ // then apply RF signal
+ setRfPower(100); // figure out a good default number (or don't set a default)
+ }
+
+ // todo: make sure gpio are set correctly after this
+ I2Cdev::writeBitW(devAddr, A1846S_CTL_REG, A1846S_TX_MODE_BIT, on_noff);
+
+
+}
+bool HAMShield::getTX(){
+ I2Cdev::readBitW(devAddr, A1846S_CTL_REG, A1846S_TX_MODE_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+void HAMShield::setRX(bool on_noff){
+ // make sure TX is off
+ if (on_noff) {
+ setTX(false);
+
+ // set TX output off
+ setGpioHi(5); // remember that RX and TX are active low
+ // set RX output on
+ setGpioLow(4); // remember that RX and TX are active low
+ }
+
+ I2Cdev::writeBitW(devAddr, A1846S_CTL_REG, A1846S_RX_MODE_BIT, on_noff);
+}
+bool HAMShield::getRX(){
+ I2Cdev::readBitW(devAddr, A1846S_CTL_REG, A1846S_RX_MODE_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+void HAMShield::setModeTransmit(){
+ // check to see if we should allow them to do this
+ if(restrictions == true) {
+ if((radio_frequency > 139999) & (radio_frequency < 148001)) { setRX(false); setTX(true); }
+ if((radio_frequency > 218999) & (radio_frequency < 225001)) { setRX(false); setTX(true); }
+ if((radio_frequency > 419999) & (radio_frequency < 450001)) { setRX(false); setTX(true); }
+ } else {
+ // turn off rx, turn on tx
+ setRX(false); // break before make
+ setTX(true); }
+}
+void HAMShield::setModeReceive(){
+ // turn on rx, turn off tx
+ setTX(false); // break before make
+ setRX(true);
+}
+void HAMShield::setModeOff(){
+ // turn off rx, turn off tx, set pwr_dwn bit
+ setTX(false);
+ setRX(false);
+}
+
+// set tx source
+// 00 - Mic source
+// 01 - sine source from tone2
+// 10 - tx code from GPIO1 code_in (gpio1<1:0> must be set to 01)
+// 11 - no tx source
+void HAMShield::setTxSource(uint16_t tx_source){
+ I2Cdev::writeBitsW(devAddr, A1846S_TX_VOICE_REG, A1846S_VOICE_SEL_BIT, A1846S_VOICE_SEL_LENGTH, tx_source);
+}
+void HAMShield::setTxSourceMic(){
+ setTxSource(0);
+}
+void HAMShield::setTxSourceSine(){
+ setTxSource(1);
+}
+void HAMShield::setTxSourceCode(){
+ // note, also set GPIO1 to 01
+ setGpioMode(1, 1);
+
+ setTxSource(2);
+}
+void HAMShield::setTxSourceNone(){
+ setTxSource(3);
+}
+uint16_t HAMShield::getTxSource(){
+ I2Cdev::readBitsW(devAddr, A1846S_TX_VOICE_REG, A1846S_VOICE_SEL_BIT, A1846S_VOICE_SEL_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// set PA_bias voltage
+// 000000: 1.01V
+// 000001:1.05V
+// 000010:1.09V
+// 000100: 1.18V
+// 001000: 1.34V
+// 010000: 1.68V
+// 100000: 2.45V
+// 1111111:3.13V
+void HAMShield::setPABiasVoltage(uint16_t voltage){
+ I2Cdev::writeBitsW(devAddr, A1846S_PABIAS_REG, A1846S_PABIAS_BIT, A1846S_PABIAS_LENGTH, voltage);
+}
+uint16_t HAMShield::getPABiasVoltage(){
+ I2Cdev::readBitsW(devAddr, A1846S_PABIAS_REG, A1846S_PABIAS_BIT, A1846S_PABIAS_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// Subaudio settings
+// TX and RX code
+/*
+ Set code mode:
+ Step1: set 58H[1:0]=11 set voice hpf bypass
+ Step2: set 58H[5:3]=111 set voice lpf bypass and pre/de-emph bypass
+ Step3 set 3CH[15:14]=10 set code mode
+ Step4: set 1FH[3:2]=01 set GPIO code in or code out
+
+ TX code mode:
+ Step1: 45H[2:0]=010
+
+ RX code mode:
+ Step1: set 45H[2:0]=001
+ Step2: set 4dH[15:10]=000001
+*/
+
+// Ctcss/cdcss mode sel
+// x00=disable,
+// 001=inner ctcss en,
+// 010= inner cdcss en
+// 101= outer ctcss en,
+// 110=outer cdcss en
+// others =disable
+void HAMShield::setCtcssCdcssMode(uint16_t mode){
+ I2Cdev::writeBitsW(devAddr, A1846S_SUBAUDIO_REG, A1846S_C_MODE_BIT, A1846S_C_MODE_LENGTH, mode);
+}
+uint16_t HAMShield::getCtcssCdcssMode(){
+ I2Cdev::readBitsW(devAddr, A1846S_SUBAUDIO_REG, A1846S_C_MODE_BIT, A1846S_C_MODE_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setInnerCtcssMode(){
+ setCtcssCdcssMode(1);
+}
+void HAMShield::setInnerCdcssMode(){
+ setCtcssCdcssMode(2);
+}
+void HAMShield::setOuterCtcssMode(){
+ setCtcssCdcssMode(5);
+}
+void HAMShield::setOuterCdcssMode(){
+ setCtcssCdcssMode(6);
+}
+void HAMShield::disableCtcssCdcss(){
+ setCtcssCdcssMode(0);
+}
+
+// Ctcss_sel
+// 1 = ctcss_cmp/cdcss_cmp out via gpio
+// 0 = ctcss/cdcss sdo out vio gpio
+void HAMShield::setCtcssSel(bool cmp_nsdo){
+ I2Cdev::writeBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_CTCSS_SEL_BIT, cmp_nsdo);
+}
+bool HAMShield::getCtcssSel(){
+ I2Cdev::readBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_CTCSS_SEL_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// Cdcss_sel
+// 1 = long (24 bit) code
+// 0 = short(23 bit) code
+void HAMShield::setCdcssSel(bool long_nshort){
+ I2Cdev::writeBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_CDCSS_SEL_BIT, long_nshort);
+}
+bool HAMShield::getCdcssSel(){
+ I2Cdev::readBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_CDCSS_SEL_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// Cdcss neg_det_en
+void HAMShield::enableCdcssNegDet(){
+ I2Cdev::writeBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_NEG_DET_EN_BIT, 1);
+}
+void HAMShield::disableCdcssNegDet(){
+ I2Cdev::writeBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_NEG_DET_EN_BIT, 0);
+}
+bool HAMShield::getCdcssNegDetEnabled(){
+ I2Cdev::readBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_NEG_DET_EN_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// Cdcss pos_det_en
+void HAMShield::enableCdcssPosDet(){
+ I2Cdev::writeBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_POS_DET_EN_BIT, 1);
+}
+void HAMShield::disableCdcssPosDet(){
+ I2Cdev::writeBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_POS_DET_EN_BIT, 0);
+}
+bool HAMShield::getCdcssPosDetEnabled(){
+ I2Cdev::readBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_POS_DET_EN_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// css_det_en
+void HAMShield::enableCssDet(){
+ I2Cdev::writeBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_CSS_DET_EN_BIT, 1);
+}
+void HAMShield::disableCssDet(){
+ I2Cdev::writeBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_CSS_DET_EN_BIT, 0);
+}
+bool HAMShield::getCssDetEnabled(){
+ I2Cdev::readBitW(devAddr, A1846S_SUBAUDIO_REG, A1846S_CSS_DET_EN_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// ctcss freq
+void HAMShield::setCtcss(float freq) {
+ int dfreq = freq / 10000;
+ dfreq = dfreq * 65536;
+ setCtcssFreq(dfreq);
+}
+
+void HAMShield::setCtcssFreq(uint16_t freq){
+ I2Cdev::writeWord(devAddr, A1846S_CTCSS_FREQ_REG, freq);
+}
+uint16_t HAMShield::getCtcssFreq(){
+ I2Cdev::readWord(devAddr, A1846S_CTCSS_FREQ_REG, radio_i2c_buf);
+
+ return radio_i2c_buf[0];
+}
+void HAMShield::setCtcssFreqToStandard(){
+ // freq must be 134.4Hz for standard cdcss mode
+ setCtcssFreq(0x2268);
+}
+
+// cdcss codes
+void HAMShield::setCdcssCode(uint16_t code) {
+ // note: assuming a well formed code (xyz, where x, y, and z are all 0-7)
+
+ // Set both code registers at once (23 or 24 bit code)
+ // sends 100, c1, c2, c3, 11 bits of crc
+
+ // TODO: figure out what to do about 24 or 23 bit codes
+
+ uint32_t cdcss_code = 0x800000; // top three bits are 100
+ uint32_t oct_code = code%10;
+ code = code / 10;
+ cdcss_code += oct_code << 20;
+ oct_code = code % 10;
+ code = code / 10;
+ cdcss_code += oct_code << 17;
+ cdcss_code += (code % 10) << 14;
+
+ // TODO: CRC
+
+ // set registers
+ uint16_t temp_code = (uint16_t) cdcss_code;
+ I2Cdev::writeWord(devAddr, A1846S_CDCSS_CODE_HI_REG, temp_code);
+ temp_code = (uint16_t) (cdcss_code >> 16);
+ I2Cdev::writeWord(devAddr, A1846S_CDCSS_CODE_LO_REG, temp_code);
+}
+uint16_t HAMShield::getCdcssCode() {
+ uint32_t oct_code;
+ I2Cdev::readWord(devAddr, A1846S_CDCSS_CODE_HI_REG, radio_i2c_buf);
+ oct_code = (radio_i2c_buf[0] << 16);
+ I2Cdev::readWord(devAddr, A1846S_CDCSS_CODE_LO_REG, radio_i2c_buf);
+ oct_code += radio_i2c_buf[0];
+
+ oct_code = oct_code >> 12;
+ uint16_t code = (oct_code & 0x3);
+ oct_code = oct_code >> 3;
+ code += (oct_code & 0x3)*10;
+ oct_code = oct_code >> 3;
+ code += (oct_code & 0x3)*100;
+
+ return code;
+}
+
+// SQ
+void HAMShield::setSQOn(){
+ I2Cdev::writeBitW(devAddr, A1846S_CTL_REG, A1846S_SQ_ON_BIT, 1);
+}
+void HAMShield::setSQOff(){
+ I2Cdev::writeBitW(devAddr, A1846S_CTL_REG, A1846S_SQ_ON_BIT, 0);
+}
+bool HAMShield::getSQState(){
+ I2Cdev::readBitW(devAddr, A1846S_CTL_REG, A1846S_SQ_ON_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// SQ threshold
+void HAMShield::setSQHiThresh(uint16_t sq_hi_threshold){
+ // Sq detect high th, rssi_cmp will be 1 when rssi>th_h_sq, unit 1/8dB
+ I2Cdev::writeWord(devAddr, A1846S_SQ_OPEN_THRESH_REG, sq_hi_threshold);
+}
+uint16_t HAMShield::getSQHiThresh(){
+ I2Cdev::readWord(devAddr, A1846S_SQ_OPEN_THRESH_REG, radio_i2c_buf);
+
+ return radio_i2c_buf[0];
+}
+void HAMShield::setSQLoThresh(uint16_t sq_lo_threshold){
+ // Sq detect low th, rssi_cmp will be 0 when rssi th_h_vox, then vox will be 1(unit mV )
+ I2Cdev::writeWord(devAddr, A1846S_TH_H_VOX_REG, vox_open_thresh);
+}
+uint16_t HAMShield::getVoxOpenThresh(){
+ I2Cdev::readWord(devAddr, A1846S_TH_H_VOX_REG, radio_i2c_buf);
+
+ return radio_i2c_buf[0];
+}
+void HAMShield::setVoxShutThresh(uint16_t vox_shut_thresh){
+ // When vssi < th_l_vox && time delay meet, then vox will be 0 (unit mV )
+ I2Cdev::writeWord(devAddr, A1846S_TH_L_VOX_REG, vox_shut_thresh);
+}
+uint16_t HAMShield::getVoxShutThresh(){
+ I2Cdev::readWord(devAddr, A1846S_TH_L_VOX_REG, radio_i2c_buf);
+
+ return radio_i2c_buf[0];
+}
+
+// Tail Noise
+void HAMShield::enableTailNoiseElim(){
+ I2Cdev::writeBitW(devAddr, A1846S_CTL_REG, A1846S_TAIL_ELIM_EN_BIT, 1);
+}
+void HAMShield::disableTailNoiseElim(){
+ I2Cdev::writeBitW(devAddr, A1846S_CTL_REG, A1846S_TAIL_ELIM_EN_BIT, 1);
+}
+bool HAMShield::getTailNoiseElimEnabled(){
+ I2Cdev::readBitW(devAddr, A1846S_CTL_REG, A1846S_TAIL_ELIM_EN_BIT, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// tail noise shift select
+// Select ctcss phase shift when use tail eliminating function when TX
+// 00 = 120 degree shift
+// 01 = 180 degree shift
+// 10 = 240 degree shift
+// 11 = reserved
+void HAMShield::setShiftSelect(uint16_t shift_sel){
+ I2Cdev::writeBitsW(devAddr, A1846S_SUBAUDIO_REG, A1846S_SHIFT_SEL_BIT, A1846S_SHIFT_SEL_LENGTH, shift_sel);
+}
+uint16_t HAMShield::getShiftSelect(){
+ I2Cdev::readBitsW(devAddr, A1846S_SUBAUDIO_REG, A1846S_SHIFT_SEL_BIT, A1846S_SHIFT_SEL_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// DTMF
+void HAMShield::setDTMFC0(uint16_t freq) {
+ I2Cdev::writeBitsW(devAddr, A1846S_DTMF_C01_REG, A1846S_DTMF_C0_BIT, A1846S_DTMF_C0_LENGTH, freq);
+}
+uint16_t HAMShield::getDTMFC0() {
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_C01_REG, A1846S_DTMF_C0_BIT, A1846S_DTMF_C0_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setDTMFC1(uint16_t freq) {
+ I2Cdev::writeBitsW(devAddr, A1846S_DTMF_C01_REG, A1846S_DTMF_C1_BIT, A1846S_DTMF_C1_LENGTH, freq);
+}
+uint16_t HAMShield::getDTMFC1() {
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_C01_REG, A1846S_DTMF_C1_BIT, A1846S_DTMF_C1_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setDTMFC2(uint16_t freq) {
+ I2Cdev::writeBitsW(devAddr, A1846S_DTMF_C23_REG, A1846S_DTMF_C2_BIT, A1846S_DTMF_C2_LENGTH, freq);
+}
+uint16_t HAMShield::getDTMFC2() {
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_C23_REG, A1846S_DTMF_C2_BIT, A1846S_DTMF_C2_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setDTMFC3(uint16_t freq) {
+ I2Cdev::writeBitsW(devAddr, A1846S_DTMF_C23_REG, A1846S_DTMF_C3_BIT, A1846S_DTMF_C3_LENGTH, freq);
+}
+uint16_t HAMShield::getDTMFC3() {
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_C23_REG, A1846S_DTMF_C3_BIT, A1846S_DTMF_C3_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setDTMFC4(uint16_t freq) {
+ I2Cdev::writeBitsW(devAddr, A1846S_DTMF_C45_REG, A1846S_DTMF_C4_BIT, A1846S_DTMF_C4_LENGTH, freq);
+}
+uint16_t HAMShield::getDTMFC4() {
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_C45_REG, A1846S_DTMF_C4_BIT, A1846S_DTMF_C4_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setDTMFC5(uint16_t freq) {
+ I2Cdev::writeBitsW(devAddr, A1846S_DTMF_C45_REG, A1846S_DTMF_C5_BIT, A1846S_DTMF_C5_LENGTH, freq);
+}
+uint16_t HAMShield::getDTMFC5() {
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_C45_REG, A1846S_DTMF_C5_BIT, A1846S_DTMF_C5_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setDTMFC6(uint16_t freq) {
+ I2Cdev::writeBitsW(devAddr, A1846S_DTMF_C67_REG, A1846S_DTMF_C6_BIT, A1846S_DTMF_C6_LENGTH, freq);
+}
+uint16_t HAMShield::getDTMFC6() {
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_C67_REG, A1846S_DTMF_C6_BIT, A1846S_DTMF_C6_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setDTMFC7(uint16_t freq) {
+ I2Cdev::writeBitsW(devAddr, A1846S_DTMF_C67_REG, A1846S_DTMF_C7_BIT, A1846S_DTMF_C7_LENGTH, freq);
+}
+uint16_t HAMShield::getDTMFC7() {
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_C67_REG, A1846S_DTMF_C7_BIT, A1846S_DTMF_C7_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// TX FM deviation
+void HAMShield::setFMVoiceCssDeviation(uint16_t deviation){
+ I2Cdev::writeBitsW(devAddr, A1846S_FM_DEV_REG, A1846S_FM_DEV_VOICE_BIT, A1846S_FM_DEV_VOICE_LENGTH, deviation);
+}
+uint16_t HAMShield::getFMVoiceCssDeviation(){
+ I2Cdev::readBitsW(devAddr, A1846S_FM_DEV_REG, A1846S_FM_DEV_VOICE_BIT, A1846S_FM_DEV_VOICE_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setFMCssDeviation(uint16_t deviation){
+ I2Cdev::writeBitsW(devAddr, A1846S_FM_DEV_REG, A1846S_FM_DEV_CSS_BIT, A1846S_FM_DEV_CSS_LENGTH, deviation);
+}
+uint16_t HAMShield::getFMCssDeviation(){
+ I2Cdev::readBitsW(devAddr, A1846S_FM_DEV_REG, A1846S_FM_DEV_CSS_BIT, A1846S_FM_DEV_CSS_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// RX voice range
+void HAMShield::setVolume1(uint16_t volume){
+ I2Cdev::writeBitsW(devAddr, A1846S_RX_VOLUME_REG, A1846S_RX_VOL_1_BIT, A1846S_RX_VOL_1_LENGTH, volume);
+}
+uint16_t HAMShield::getVolume1(){
+ I2Cdev::readBitsW(devAddr, A1846S_RX_VOLUME_REG, A1846S_RX_VOL_1_BIT, A1846S_RX_VOL_1_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setVolume2(uint16_t volume){
+ I2Cdev::writeBitsW(devAddr, A1846S_RX_VOLUME_REG, A1846S_RX_VOL_2_BIT, A1846S_RX_VOL_2_LENGTH, volume);
+}
+uint16_t HAMShield::getVolume2(){
+ I2Cdev::readBitsW(devAddr, A1846S_RX_VOLUME_REG, A1846S_RX_VOL_2_BIT, A1846S_RX_VOL_2_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// GPIO
+void HAMShield::setGpioMode(uint16_t gpio, uint16_t mode){
+ uint16_t mode_len = 2;
+ uint16_t bit = gpio*2 + 1;
+
+ I2Cdev::writeBitsW(devAddr, A1846S_GPIO_MODE_REG, bit, mode_len, mode);
+}
+void HAMShield::setGpioHiZ(uint16_t gpio){
+ setGpioMode(gpio, 0);
+}
+void HAMShield::setGpioFcn(uint16_t gpio){
+ setGpioMode(gpio, 1);
+}
+void HAMShield::setGpioLow(uint16_t gpio){
+ setGpioMode(gpio, 2);
+}
+void HAMShield::setGpioHi(uint16_t gpio){
+ setGpioMode(gpio, 3);
+}
+uint16_t HAMShield::getGpioMode(uint16_t gpio){
+ uint16_t mode_len = 2;
+ uint16_t bit = gpio*2 + 1;
+
+ I2Cdev::readBitsW(devAddr, A1846S_GPIO_MODE_REG, bit, mode_len, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+// Int
+void HAMShield::enableInterrupt(uint16_t interrupt){
+ I2Cdev::writeBitW(devAddr, A1846S_INT_MODE_REG, interrupt, 1);
+}
+void HAMShield::disableInterrupt(uint16_t interrupt){
+ I2Cdev::writeBitW(devAddr, A1846S_INT_MODE_REG, interrupt, 0);
+}
+bool HAMShield::getInterruptEnabled(uint16_t interrupt){
+ I2Cdev::readBitW(devAddr, A1846S_INT_MODE_REG, interrupt, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// ST mode
+void HAMShield::setStMode(uint16_t mode){
+ I2Cdev::writeBitsW(devAddr, A1846S_CTL_REG, A1846S_ST_MODE_BIT, A1846S_ST_MODE_LENGTH, mode);
+}
+uint16_t HAMShield::getStMode(){
+ I2Cdev::readBitsW(devAddr, A1846S_CTL_REG, A1846S_ST_MODE_BIT, A1846S_ST_MODE_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+void HAMShield::setStFullAuto(){
+setStMode(2);
+}
+void HAMShield::setStRxAutoTxManu(){
+setStMode(1);
+}
+void HAMShield::setStFullManu(){
+setStMode(0);
+}
+
+// Pre-emphasis, De-emphasis filter
+void HAMShield::bypassPreDeEmph(){
+ I2Cdev::writeBitW(devAddr, A1846S_EMPH_FILTER_REG, A1846S_EMPH_FILTER_EN, 1);
+}
+void HAMShield::usePreDeEmph(){
+ I2Cdev::writeBitW(devAddr, A1846S_EMPH_FILTER_REG, A1846S_EMPH_FILTER_EN, 0);
+}
+bool HAMShield::getPreDeEmphEnabled(){
+ I2Cdev::readBitW(devAddr, A1846S_EMPH_FILTER_REG, A1846S_EMPH_FILTER_EN, radio_i2c_buf);
+ return (radio_i2c_buf[0] != 0);
+}
+
+// Read Only Status Registers
+int16_t HAMShield::readRSSI(){
+ I2Cdev::readWord(devAddr, A1846S_RSSI_REG, radio_i2c_buf);
+
+ int16_t rssi = (radio_i2c_buf[0] & 0x3FF) / 8 - 135;
+ return rssi; // only need lowest 10 bits
+}
+uint16_t HAMShield::readVSSI(){
+ I2Cdev::readWord(devAddr, A1846S_VSSI_REG, radio_i2c_buf);
+
+ return radio_i2c_buf[0] & 0x7FF; // only need lowest 10 bits
+}
+uint16_t HAMShield::readDTMFIndex(){
+// TODO: may want to split this into two (index1 and index2)
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_RX_REG, A1846S_DTMF_INDEX_BIT, A1846S_DTMF_INDEX_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+uint16_t HAMShield::readDTMFCode(){
+// 1:f0+f4, 2:f0+f5, 3:f0+f6, A:f0+f7,
+// 4:f1+f4, 5:f1+f5, 6:f1+f6, B:f1+f7,
+// 7:f2+f4, 8:f2+f5, 9:f2+f6, C:f2+f7,
+// E(*):f3+f4, 0:f3+f5, F(#):f3+f6, D:f3+f7
+ I2Cdev::readBitsW(devAddr, A1846S_DTMF_RX_REG, A1846S_DTMF_CODE_BIT, A1846S_DTMF_CODE_LENGTH, radio_i2c_buf);
+ return radio_i2c_buf[0];
+}
+
+void HAMShield::setRfPower(uint8_t pwr) {
+
+ // using loop reference voltage input to op-amp
+ // (see RF6886 datasheet)
+ // 30 is 0.5V, which is ~min loop reference voltage
+ // 127 is 2.5V, which is ~max loop ref voltage
+ int max_pwr = 255; //167; // 167 is 3.3*255/5 - 1;
+ if (pwr > max_pwr) {
+ pwr = max_pwr;
+ }
+
+
+ // using open loop reference voltage into Vreg1/2
+ /*int max_pwr = 78; // 78 = 1.58*255/5 - 1
+ if (pwr > max_pwr) {
+ pwr = max_pwr;
+ }*/
+ // using loop ref voltage as specified in RF6886 datasheet
+ // analogWrite(pwr_control_pin, pwr);
+}
+
+
+bool HAMShield::frequency(uint32_t freq_khz) {
+ if((freq_khz >= 137000) && (freq_khz <= 174000)) {
+ setVHF();
+ setBand(3); // 0b11 is 134-174MHz
+ setFrequency(freq_khz);
+ return true;
+ }
+
+ if((freq_khz >= 200000) && (freq_khz <= 260000)) {
+ setVHF();
+ setBand(2); // 10 is 200-260MHz
+ setFrequency(freq_khz);
+ return true;
+ }
+
+ if((freq_khz >= 400000) && (freq_khz <= 520000)) {
+ setUHF();
+ setBand(00); // 00 is 400-520MHz
+ setFrequency(freq_khz);
+ return true;
+ }
+ return false;
+}
+
+/* FRS Lookup Table */
+
+bool HAMShield::setFRSChannel(uint8_t channel) {
+ if(channel < 15) {
+ setFrequency(FRS[channel]);
+ return true;
+ }
+ return false;
+}
+
+/* GMRS Lookup Table (borrows from FRS table since channels overlap) */
+
+bool HAMShield::setGMRSChannel(uint8_t channel) {
+ if((channel > 8) & (channel < 16)) {
+ channel = channel - 7; // we start with 0, to try to avoid channel 8 being nothing
+ setFrequency(FRS[channel]);
+ return true;
+ }
+ if(channel < 9) {
+ setFrequency(GMRS[channel]);
+ return true;
+ }
+ return false;
+}
+
+/* MURS band is 11.25KHz (2.5KHz dev) in channel 1-3, 20KHz (5KHz dev) in channel 4-5. Should we set this? */
+
+bool HAMShield::setMURSChannel(uint8_t channel) {
+ if(channel < 6) {
+ setFrequency(MURS[channel]);
+ return true;
+ }
+}
+
+/* Weather radio channels */
+
+bool HAMShield::setWXChannel(uint8_t channel) {
+ if(channel < 8) {
+ setFrequency(WX[channel]);
+ setModeReceive();
+ // turn off squelch?
+ // channel bandwidth?
+ return true;
+ }
+ return false;
+}
+
+/* Scan channels for strongest signal. returns channel number. You could do radio.setWXChannel(radio.scanWXChannel()) */
+
+uint8_t HAMShield::scanWXChannel() {
+ uint8_t channel = 0;
+ int16_t toprssi = 0;
+ for(int x = 0; x < 8; x++) {
+ setWXChannel(x);
+ delay(100);
+ int16_t rssi = readRSSI();
+ if(rssi > toprssi) { toprssi = rssi; channel = x; }
+ }
+ return channel;
+}
+
+
+/* removes the out of band transmit restrictions for those who hold special licenses */
+
+void HAMShield::dangerMode() {
+ restrictions = false;
+ return;
+}
+
+/* enable restrictions on out of band transmissions */
+
+void HAMShield::safeMode() {
+ restrictions = true;
+ return;
+}
+
+/* scanner mode. Scans a range and returns the active frequency when it detects a signal. If none is detected, returns 0. */
+
+uint32_t HAMShield::scanMode(uint32_t start,uint32_t stop, uint8_t speed, uint16_t step, uint16_t threshold) {
+ setModeReceive();
+ int16_t rssi = -150;
+ for(uint32_t freq = start; freq < stop; freq = freq + step) {
+ setFrequency(freq);
+ for(int x = 0; x < speed; x++) {
+ rssi = readRSSI();
+ if(rssi > threshold) { return freq; }
+ }
+ }
+ return 0; // found nothing
+}
+
+/* white space finder. (inverted scanner) Scans a range for a white space, and if no signal exists, stop there. */
+
+uint32_t HAMShield::findWhitespace(uint32_t start,uint32_t stop, uint8_t dwell, uint16_t step, uint16_t threshold) {
+ setModeReceive();
+ int16_t rssi = -150;
+ for(uint32_t freq = start; freq < stop; freq = freq + step) {
+ setFrequency(freq);
+ for(int x = 0; x < dwell; x++) {
+ rssi = readRSSI();
+ if(rssi > threshold) { break; }
+ }
+ if(rssi < threshold) { return freq; } /* found a blank channel */
+ }
+ return 0; // everything is busy
+}
+
+/*
+channel scanner. Scans an array of channels for activity. returns channel number if found. Otherwise, returns 0. ignores whatever is in array position
+0
+*/
+
+uint32_t HAMShield::scanChannels(uint32_t buffer[],uint8_t buffsize, uint8_t speed, uint16_t threshold) {
+ setModeReceive();
+ int16_t rssi = 0;
+ for(int x = 1; x < buffsize; x++) {
+ setFrequency(buffer[x]);
+ for(int y = 0; y < speed; y++) {
+ rssi = readRSSI();
+ if(rssi > threshold) { return x; }
+ }
+ }
+ return 0;
+
+}
+
+/*
+white space channel finder. Scans an array of channels for white space. returns channel number if empty found. Otherwise, returns 0. ignores whatever is in array position
+0
+*/
+
+uint32_t HAMShield::findWhitespaceChannels(uint32_t buffer[],uint8_t buffsize, uint8_t dwell, uint16_t threshold) {
+ setModeReceive();
+ int16_t rssi = 0;
+ for(int x = 1; x < buffsize; x++) {
+ setFrequency(buffer[x]);
+ for(int y = 0; y < dwell; y++) {
+ rssi = readRSSI();
+ if(rssi > threshold) { break; }
+ }
+ if(rssi < threshold) { return x; } /* found a blank channel */
+ }
+ return 0; // everything is busy
+}
+
+
+/*
+BUG: I cannot figure out how to attach these interrupt handlers without the error:
+
+/Users/casey/Documents/Arduino/libraries/HAMShield/HAMShield.cpp: In member function 'void HAMShield::buttonMode(uint8_t)':
+/Users/casey/Documents/Arduino/libraries/HAMShield/HAMShield.cpp:1125: error: argument of type 'void (HAMShield::)()' does not match 'void (*)()'
+/Users/casey/Documents/Arduino/libraries/HAMShield/HAMShield.cpp:1126: error: argument of type 'void (HAMShield::)()' does not match 'void (*)()'
+*/
+
+
+/*
+void HAMShield::buttonMode(uint8_t mode) {
+ pinMode(HAMSHIELD_AUX_BUTTON,INPUT); // set the pin mode to input
+ digitalWrite(HAMSHIELD_AUX_BUTTON,HIGH); // turn on internal pull up
+ if(mode == PTT_MODE) { attachInterrupt(HAMSHIELD_AUX_BUTTON, isr_ptt, CHANGE); }
+ if(mode == RESET_MODE) { attachInterrupt(HAMSHIELD_AUX_BUTTON, isr_reset, CHANGE); }
+}
+*/
+
+/* Interrupt routines */
+
+/* handle aux button to reset condition */
+
+void HAMShield::isr_reset() {
+ wdt_enable(WDTO_15MS);
+ while(1) { }
+}
+
+/* Transmit on press, receive on release. We need debouncing !! */
+
+void HAMShield::isr_ptt() {
+ if((bouncer + 200) > millis()) {
+ if(ptt == false) {
+ ptt = true;
+ HAMShield::setModeTransmit();
+ bouncer = millis();
+ }
+ if(ptt == true) {
+ ptt = false;
+ HAMShield::setModeReceive();
+ bouncer = millis();
+ } }
+}
+
+/*
+
+ Radio etiquette function: Wait for empty channel.
+
+ Optional timeout (0 waits forever)
+ Optional break window (how much dead air to wait for after a transmission completes)
+
+Does not take in account the millis() overflow
+
+*/
+
+bool HAMShield::waitForChannel(long timeout = 0, long breakwindow = 0) {
+ int16_t rssi = 0; // Set RSSI to max received signal
+ for(int x = 0; x < 20; x++) { rssi = readRSSI(); } // "warm up" to get past RSSI hysteresis
+ long timer = millis() + timeout; // Setup the timeout value
+ if(timeout == 0) { timer = 4294967295; } // If we want to wait forever, set it to the max millis()
+ while(timer > millis()) { // while our timer is not timed out.
+ rssi = readRSSI(); // Read signal strength
+ if(rssi < HAMSHIELD_EMPTY_CHANNEL_RSSI) { // If the channel is empty, lets see if anyone breaks in.
+ timer = millis() + breakwindow;
+ while(timer > millis()) {
+ rssi = readRSSI();
+ if(rssi > HAMSHIELD_EMPTY_CHANNEL_RSSI) { return false; } // Someone broke into the channel, abort.
+ } return true; // It passed the test...channel is open.
+ }
+ }
+ return false;
+}
+
+
+/* Morse code out, blocking */
+
+void HAMShield::morseOut(char buffer[HAMSHIELD_MORSE_BUFFER_SIZE]) {
+
+ for(int x = 0; x < strlen(buffer); x++) {
+ char output = morseLookup(buffer[x]);
+ if(buffer[x] != ' ') {
+ for(int m = 0; m < strlen(itu[output]); m++) {
+ if(itu[output][m] == '-') { tone(HAMSHIELD_PWM_PIN,1000,HAMSHIELD_MORSE_DOT*3); delay(HAMSHIELD_MORSE_DOT*3); }
+ else { tone(HAMSHIELD_PWM_PIN,1000,HAMSHIELD_MORSE_DOT); delay(HAMSHIELD_MORSE_DOT); }
+ delay(HAMSHIELD_MORSE_DOT);
+ }
+ delay(HAMSHIELD_MORSE_DOT*3);
+ } else { delay(HAMSHIELD_MORSE_DOT*7); }
+ }
+ return;
+}
+
+/* Morse code lookup table */
+
+char HAMShield::morseLookup(char letter) {
+ for(int x = 0; x < 54; x++) {
+ if(letter == ascii[x]) {
+ return x;
+ // return itu[x];
+ }
+ }
+}
+
+/*
+
+SSTV VIS Digital Header
+
+Reference: http://www.barberdsp.com/files/Dayton%20Paper.pdf
+
+Millis Freq Description
+-----------------------------------------------
+300 1900 Leader tone
+10 1200 break
+300 1900 Leader tone
+30 1200 VIS start bit
+30 bit 0 1100hz = “1”, 1300hz = “0”
+30 bit 1 “”
+30 bit 2 “”
+30 bit 3 “”
+30 bit 4 “”
+30 bit 5 “”
+30 bit 6 “”
+30 PARITY Even=1300hz,Odd=1100hz
+30 1200 VIS stop bit
+
+*/
+
+void HAMShield::SSTVVISCode(int code) {
+ toneWait(1900,300);
+ toneWait(1200,10);
+ toneWait(1900,300);
+ toneWait(1200,30);
+ for(int x = 0; x < 7; x++) {
+ if(bitRead(code,x)) { toneWait(1100,30); } else { toneWait(1300,30); }
+ }
+ if(parityCalc(code)) { toneWait(1300,30); } else { toneWait(1100,30); }
+ toneWait(1200,30);
+ return;
+}
+
+/*
+
+SSTV Test Pattern
+Print 6 color bars
+MARTIN1 is only supported for this
+Reference: http://www.barberdsp.com/files/Dayton%20Paper.pdf
+
+*/
+
+void HAMShield::SSTVTestPattern(int code) {
+ SSTVVISCode(code);
+ if(code == MARTIN1) {
+ for(int x = 0; x < 257; x++){
+
+ toneWaitU(1200,4862); // sync pulse (4862 uS)
+ toneWaitU(1500,572); // sync porch (572 uS)
+
+ /* Green Channel - 146.432ms a line (we are doing 144ms) */
+
+ toneWait(2400,24);
+ toneWait(2400,24);
+ toneWait(2400,24);
+ toneWait(2400,24);
+ toneWait(1500,24);
+ toneWait(1500,24);
+
+ toneWaitU(1500,572); // color separator pulse (572 uS)
+
+ /* Blue Channel - 146.432ms a line (we are doing 144ms) */
+
+ toneWait(2400,24);
+ toneWait(1500,24);
+ toneWait(2400,24);
+ toneWait(1500,24);
+ toneWait(1500,24);
+ toneWait(2400,24);
+
+ toneWaitU(1500,572); // color separator pulse (572 uS)
+
+ /* Red Channel - 146.432ms a line (we are doing 144ms) */
+
+ toneWait(2400,24);
+ toneWait(2400,24);
+ toneWait(1500,24);
+ toneWait(1500,24);
+ toneWait(2400,24);
+ toneWait(1500,24);
+
+ toneWaitU(1500,572); // color separator pulse (572 uS)
+ }
+ }
+}
+
+/* wait for tone to complete */
+
+void HAMShield::toneWait(uint16_t freq, long timer) {
+ tone(HAMSHIELD_PWM_PIN,freq,timer);
+ delay(timer);
+}
+
+/* wait microseconds for tone to complete */
+
+void HAMShield::toneWaitU(uint16_t freq, long timer) {
+ if(freq < 16383) {
+ tone(HAMSHIELD_PWM_PIN,freq);
+ delayMicroseconds(timer); noTone(HAMSHIELD_PWM_PIN); return;
+ }
+ tone(HAMSHIELD_PWM_PIN,freq);
+ delay(timer / 1000); noTone(HAMSHIELD_PWM_PIN); return;
+}
+
+
+bool HAMShield::parityCalc(int code) {
+ unsigned int v; // word value to compute the parity of
+ bool parity = false; // parity will be the parity of v
+
+ while (code)
+ {
+ parity = !parity;
+ code = code & (code - 1);
+ }
+
+ return parity;
+}
+/*
+void HAMShield::AFSKOut(char buffer[80]) {
+ for(int x = 0; x < 65536; x++) {
+ startPlayback(AFSK_mark, sizeof(AFSK_mark)); delay(8);
+ startPlayback(AFSK_space, sizeof(AFSK_space)); delay(8); }
+
+}
+*/
\ No newline at end of file
diff --git a/src/HamShield.h b/src/HamShield.h
new file mode 100644
index 0000000..84775c6
--- /dev/null
+++ b/src/HamShield.h
@@ -0,0 +1,554 @@
+// HAMShield library collection
+// Based on Programming Manual rev. 2.0, 5/19/2011 (RM-MPU-6000A-00)
+// 11/22/2013 by Morgan Redfield
+// 04/26/2015 various changes Casey Halverson
+
+
+
+#ifndef _HAMSHIELD_H_
+#define _HAMSHIELD_H_
+
+#include "I2Cdev_rda.h"
+#include
+
+// HAMShield constants
+
+#define HAMSHIELD_MORSE_DOT 100 // Morse code dot length (smaller is faster WPM)
+#define HAMSHIELD_MORSE_BUFFER_SIZE 80 // Char buffer size for morse code text
+#define HAMSHIELD_AUX_BUTTON 5 // Pin assignment for AUX button
+#define HAMSHIELD_PWM_PIN 9 // Pin assignment for PWM output
+#define HAMSHIELD_EMPTY_CHANNEL_RSSI -110 // Threshold where channel is considered "clear"
+
+// button modes
+#define PTT_MODE 1
+#define RESET_MODE 2
+
+// Device Constants
+#define A1846S_DEV_ADDR_SENHIGH 0b0101110
+#define A1846S_DEV_ADDR_SENLOW 0b1110001
+
+
+// Device Registers
+#define A1846S_CTL_REG 0x30 // control register
+#define A1846S_CLK_MODE_REG 0x04 // clk_mode
+#define A1846S_PABIAS_REG 0x0A // control register for bias voltage
+#define A1846S_BAND_SEL_REG 0x0F // band_sel register <1:0>
+#define A1846S_GPIO_MODE_REG 0x1F // GPIO mode select register
+#define A1846S_FREQ_HI_REG 0x29 // freq<29:16>
+#define A1846S_FREQ_LO_REG 0x2A // freq<15:0>
+#define A1846S_XTAL_FREQ_REG 0x2B // xtal_freq<15:0>
+#define A1846S_ADCLK_FREQ_REG 0x2C // adclk_freq<15:0>
+#define A1846S_INT_MODE_REG 0x2D // interrupt enables
+#define A1846S_TX_VOICE_REG 0x3C // tx voice control reg
+#define A1846S_TH_H_VOX_REG 0x41 // register holds vox high (open) threshold bits
+#define A1846S_TH_L_VOX_REG 0x42 // register holds vox low (shut) threshold bits
+#define A1846S_FM_DEV_REG 0x43 // register holds fm deviation settings
+#define A1846S_RX_VOLUME_REG 0x44 // register holds RX volume settings
+#define A1846S_SUBAUDIO_REG 0x45 // sub audio register
+#define A1846S_SQ_OPEN_THRESH_REG 0x48 // see sq
+#define A1846S_SQ_SHUT_THRESH_REG 0x49 // see sq
+#define A1846S_CTCSS_FREQ_REG 0x4A // ctcss_freq<15:0>
+#define A1846S_CDCSS_CODE_HI_REG 0x4B // cdcss_code<23:16>
+#define A1846S_CDCSS_CODE_LO_REG 0x4C // cdccs_code<15:0>
+#define A1846S_SQ_OUT_SEL_REG 0x54 // see sq
+#define A1846S_EMPH_FILTER_REG 0x58
+#define A1846S_FLAG_REG 0x5C // holds flags for different statuses
+#define A1846S_RSSI_REG 0x5F // holds RSSI (unit 1/8dB)
+#define A1846S_VSSI_REG 0x60 // holds VSSI (unit mV)
+#define A1846S_DTMF_CTL_REG 0x63 // see dtmf
+#define A1846S_DTMF_C01_REG 0x66 // holds frequency value for c0 and c1
+#define A1846S_DTMF_C23_REG 0x67 // holds frequency value for c2 and c3
+#define A1846S_DTMF_C45_REG 0x68 // holds frequency value for c4 and c5
+#define A1846S_DTMF_C67_REG 0x69 // holds frequency value for c6 and c7
+#define A1846S_DTMF_RX_REG 0x6C // received dtmf signal
+
+// NOTE: could add registers and bitfields for dtmf tones, is this necessary?
+
+
+// Device Bit Fields
+
+// Bitfields for A1846S_CTL_REG
+#define A1846S_CHAN_MODE_BIT 13 //channel_mode<1:0>
+#define A1846S_CHAN_MODE_LENGTH 2
+#define A1846S_TAIL_ELIM_EN_BIT 11 // enables tail elim when set to 1
+#define A1846S_ST_MODE_BIT 9 // set mode for txon and rxon
+#define A1846S_ST_MODE_LENGTH 2
+#define A1846S_MUTE_BIT 7 // 0 no mute, 1 mute when rxno
+#define A1846S_TX_MODE_BIT 6 //tx-on
+#define A1846S_RX_MODE_BIT 5 //rx-on
+#define A1846S_VOX_ON_BIT 4 // 0 off, 1 on and chip auto-vox
+#define A1846S_SQ_ON_BIT 3 // auto sq enable bit
+#define A1846S_PWR_DWN_BIT 2 // power control bit
+#define A1846S_CHIP_CAL_EN_BIT 1 // 0 cal disable, 1 cal enable
+#define A1846S_SOFT_RESET_BIT 0 // 0 normal value, 1 reset all registers to normal value
+
+// Bitfields for A1846S_CLK_MODE_REG
+#define A1846S_CLK_MODE_BIT 0 // 0 24-28MHz, 1 12-14MHz
+
+// Bitfields for A1846S_PABIAS_REG
+#define A1846S_PABIAS_BIT 5 // pabias_voltage<5:0>
+#define A1846S_PABIAS_LENGTH 6
+
+// Bitfields for A1846S_BAND_SEL_REG
+#define A1846S_BAND_SEL_BIT 7 // band_sel<1:0>
+#define A1846S_BAND_SEL_LENGTH 2
+
+// Bitfields for RDA1864_GPIO_MODE_REG
+#define RDA1864_GPIO7_MODE_BIT 15 // <1:0> 00=hi-z,01=vox,10=low,11=hi
+#define RDA1864_GPIO7_MODE_LENGTH 2
+#define RDA1864_GPIO6_MODE_BIT 13 // <1:0> 00=hi-z,01=sq or =sq&ctcss/cdcss when sq_out_sel=1,10=low,11=hi
+#define RDA1864_GPIO6_MODE_LENGTH 2
+#define RDA1864_GPIO5_MODE_BIT 11 // <1:0> 00=hi-z,01=txon_rf,10=low,11=hi
+#define RDA1864_GPIO5_MODE_LENGTH 2
+#define RDA1864_GPIO4_MODE_BIT 9 // <1:0> 00=hi-z,01=rxon_rf,10=low,11=hi
+#define RDA1864_GPIO4_MODE_LENGTH 2
+#define RDA1864_GPIO3_MODE_BIT 7 // <1:0> 00=hi-z,01=sdo,10=low,11=hi
+#define RDA1864_GPIO3_MODE_LENGTH 2
+#define RDA1864_GPIO2_MODE_BIT 5 // <1:0> 00=hi-z,01=int,10=low,11=hi
+#define RDA1864_GPIO2_MODE_LENGTH 2
+#define RDA1864_GPIO1_MODE_BIT 3 // <1:0> 00=hi-z,01=code_out/code_in,10=low,11=hi
+#define RDA1864_GPIO1_MODE_LENGTH 2
+#define RDA1864_GPIO0_MODE_BIT 1 // <1:0> 00=hi-z,01=css_out/css_in/css_cmp,10=low,11=hi
+#define RDA1864_GPIO0_MODE_LENGTH 2
+
+// Bitfields for A1846S_INT_MODE_REG
+#define A1846S_CSS_CMP_INT_BIT 9 // css_cmp_uint16_t enable
+#define A1846S_RXON_RF_INT_BIT 8 // rxon_rf_uint16_t enable
+#define A1846S_TXON_RF_INT_BIT 7 // txon_rf_uint16_t enable
+#define A1846S_DTMF_IDLE_INT_BIT 6 // dtmf_idle_uint16_t enable
+#define A1846S_CTCSS_PHASE_INT_BIT 5 // ctcss phase shift detect uint16_t enable
+#define A1846S_IDLE_TIMEOUT_INT_BIT 4 // idle state time out uint16_t enable
+#define A1846S_RXON_RF_TIMeOUT_INT_BIT 3 // rxon_rf timerout uint16_t enable
+#define A1846S_SQ_INT_BIT 2 // sq uint16_t enable
+#define A1846S_TXON_RF_TIMEOUT_INT_BIT 1 // txon_rf time out uint16_t enable
+#define A1846S_VOX_INT_BIT 0 // vox uint16_t enable
+
+// Bitfields for A1846S_TX_VOICE_REG
+#define A1846S_VOICE_SEL_BIT 15 //voice_sel<1:0>
+#define A1846S_VOICE_SEL_LENGTH 2
+
+// Bitfields for A1846S_TH_H_VOX_REG
+#define A1846S_TH_H_VOX_BIT 14 // th_h_vox<14:0>
+#define A1846S_TH_H_VOX_LENGTH 15
+
+// Bitfields for A1846S_FM_DEV_REG
+#define A1846S_FM_DEV_VOICE_BIT 12 // CTCSS/CDCSS and voice deviation <6:0>
+#define A1846S_FM_DEV_VOICE_LENGTH 7
+#define A1846S_FM_DEV_CSS_BIT 5 // CTCSS/CDCSS deviation only <5:0>
+#define A1846S_FM_DEV_CSS_LENGTH 6
+
+// Bitfields for A1846S_RX_VOLUME_REG
+#define A1846S_RX_VOL_1_BIT 7 // volume 1 <3:0>, (0000)-15dB~(1111)0dB, step 1dB
+#define A1846S_RX_VOL_1_LENGTH 4
+#define A1846S_RX_VOL_2_BIT 3 // volume 2 <3:0>, (0000)-15dB~(1111)0dB, step 1dB
+#define A1846S_RX_VOL_2_LENGTH 4
+
+// Bitfields for A1846S_SUBAUDIO_REG Sub Audio Register
+#define A1846S_SHIFT_SEL_BIT 15 // shift_sel<1:0> see eliminating tail noise
+#define A1846S_SHIFT_SEL_LENGTH 2
+#define A1846S_POS_DET_EN_BIT 11 // if 1, cdcss code will be detected
+#define A1846S_CSS_DET_EN_BIT 10 // 1 - sq detect will add ctcss/cdcss detect result and control voice output on or off
+#define A1846S_NEG_DET_EN_BIT 7 // if 1, cdcss inverse code will be detected at same time
+#define A1846S_CDCSS_SEL_BIT 4 // cdcss_sel
+#define A1846S_CTCSS_SEL_BIT 3 // ctcss_sel
+#define A1846S_C_MODE_BIT 2 // c_mode<2:0>
+#define A1846S_C_MODE_LENGTH 3
+
+// Bitfields for A1846S_SQ_THRESH_REG
+#define A1846S_SQ_OPEN_THRESH_BIT 9 // sq open threshold <9:0>
+#define A1846S_SQ_OPEN_THRESH_LENGTH 10
+
+// Bitfields for A1846S_SQ_SHUT_THRESH_REG
+#define A1846S_SQ_SHUT_THRESH_BIT 9 // sq shut threshold <9:0>
+#define A1846S_SQ_SHUT_THRESH_LENGTH 10
+
+// Bitfields for A1846S_SQ_OUT_SEL_REG
+#define A1846S_SQ_OUT_SEL_BIT 7 // sq_out_sel
+
+// Bitfields for A1846S_EMPH_FILTER_REG
+#define A1846S_EMPH_FILTER_EN 3
+
+// Bitfields for A1846S_FLAG_REG
+#define A1846S_DTMF_IDLE_FLAG_BIT 12 // dtmf idle flag
+#define A1846S_RXON_RF_FLAG_BIT 10 // 1 when rxon is enabled
+#define A1846S_TXON_RF_FLAG_BIT 9 // 1 when txon is enabled
+#define A1846S_INVERT_DET_FLAG_BIT 7 // ctcss phase shift detect
+#define A1846S_CSS_CMP_FLAG_BIT 2 // ctcss/cdcss compared
+#define A1846S_SQ_FLAG_BIT 1 // sq final signal out from dsp
+#define A1846S_VOX_FLAG_BIT 0 // vox out from dsp
+
+// Bitfields for A1846S_RSSI_REG
+#define A1846S_RSSI_BIT 9 // RSSI readings <9:0>
+#define A1846S_RSSI_LENGTH 10
+
+// Bitfields for A1846S_VSSI_REG
+#define A1846S_VSSI_BIT 14 // voice signal strength indicator <14:0> (unit mV)
+#define A1846S_VSSI_LENGTH 15
+
+// Bitfields for A1846S_DTMF_CTL_REG
+#define A1846S_DTMF_MODE_BIT 9 //
+#define A1846S_DTMF_MODE_LENGTH 2
+#define A1846S_DTMF_EN_BIT 8 // enable dtmf
+#define A1846S_DTMF_TIME1_BIT 7 // dtmf time 1 <3:0>
+#define A1846S_DTMF_TIME1_LENGTH 4
+#define A1846S_DTMF_TIME2_BIT 3 // dtmf time 2 <3:0>
+#define A1846S_DTMF_TIME2_LENGTH 4
+
+// Bitfields for A1846S_DTMF_RX_REG
+#define A1846S_DTMF_INDEX_BIT 10 // dtmf index <5:3> - tone 1 detect index, <2:0> - tone 2 detect index
+#define A1846S_DTMF_INDEX_LENGTH 6
+#define A1846S_DTMF_TONE1_IND_BIT 10
+#define A1846S_DTMF_TONE1_IND_LENGTH 3
+#define A1846S_DTMF_TONE2_IND_BIT 7
+#define A1846S_DTMF_TONE2_IND_LENGTH 3
+#define A1846S_DTMF_FLAG_BIT 4
+#define A1846S_DTMF_CODE_BIT 3 // dtmf code out <3:0>
+#define A1846S_DTMF_CODE_LENGTH 4
+// dtmf code out
+// 1:f0+f4, 2:f0+f5, 3:f0+f6, A:f0+f7,
+// 4:f1+f4, 5:f1+f5, 6:f1+f6, B:f1+f7,
+// 7:f2+f4, 8:f2+f5, 9:f2+f6, C:f2+f7,
+// E(*):f3+f4, 0:f3+f5, F(#):f3+f6, D:f3+f7
+
+// Bitfields for DTMF registers
+#define A1846S_DTMF_C0_BIT 15
+#define A1846S_DTMF_C0_LENGTH 8
+#define A1846S_DTMF_C1_BIT 7
+#define A1846S_DTMF_C1_LENGTH 8
+#define A1846S_DTMF_C2_BIT 15
+#define A1846S_DTMF_C2_LENGTH 8
+#define A1846S_DTMF_C3_BIT 7
+#define A1846S_DTMF_C3_LENGTH 8
+#define A1846S_DTMF_C4_BIT 15
+#define A1846S_DTMF_C4_LENGTH 8
+#define A1846S_DTMF_C5_BIT 7
+#define A1846S_DTMF_C5_LENGTH 8
+#define A1846S_DTMF_C6_BIT 15
+#define A1846S_DTMF_C6_LENGTH 8
+#define A1846S_DTMF_C7_BIT 7
+#define A1846S_DTMF_C7_LENGTH 8
+
+// SSTV VIS Codes
+
+
+#define ROBOT8BW 2
+#define SC2-180 55
+#define MARTIN1 44
+
+// RTTY Frequencies
+
+#define HAMSHIELD_RTTY_FREQ 2200
+#define HAMSHIELD_RTTY_SHIFT 850
+#define HAMSHIELD_RTTY_BAUD 75
+
+// PSK31 Frequencies
+
+#define HAMSHIELD_PSK31_FREQ 1000
+
+
+
+class HAMShield {
+ public:
+ HAMShield();
+ HAMShield(uint8_t address);
+
+ void initialize();
+ bool testConnection();
+
+ // read control reg
+ uint16_t readCtlReg();
+ void softReset();
+
+ // center frequency
+ void setFrequency(uint32_t freq_khz);
+ uint32_t getFrequency();
+
+ // band
+ // 00 - 400-520MHz
+ // 10 - 200-260MHz
+ // 11 - 134-174MHz
+ void setBand(uint16_t band);
+ uint16_t getBand();
+
+ void setUHF();
+ void setVHF();
+ void setNoFilters();
+ bool frequency(uint32_t freq_khz);
+
+ // xtal frequency (kHz)
+ // 12-14MHz crystal: this reg is set to crystal freq_khz
+ // 24-28MHz crystal: this reg is set to crystal freq_khz / 2
+ void setXtalFreq(uint16_t freq_kHz);
+ uint16_t getXtalFreq();
+
+ // adclk frequency (kHz)
+ // 12-14MHz crystal: this reg is set to crystal freq_khz / 2
+ // 24-28MHz crystal: this reg is set to crystal freq_khz / 4
+ void setAdcClkFreq(uint16_t freq_kHz);
+ uint16_t getAdcClkFreq();
+
+ // clk mode
+ // 12-14MHz: set to 1
+ // 24-28MHz: set to 0
+ void setClkMode(bool LFClk);
+ bool getClkMode();
+
+ // clk example
+ // 12.8MHz clock
+ // A1846S_XTAL_FREQ_REG[15:0]= xtal_freq<15:0>=12.8*1000=12800
+ // A1846S_ADCLK_FREQ_REG[12:0] =adclk_freq<15:0>=(12.8/2)*1000=6400
+ // A1846S_CLK_MODE_REG[0]= clk_mode =1
+
+ // TX/RX control
+
+ // channel mode
+ // 11 - 25kHz channel
+ // 00 - 12.5kHz channel
+ // 10,01 - reserved
+ void setChanMode(uint16_t mode);
+ uint16_t getChanMode();
+
+ // choose tx or rx
+ void setTX(bool on_noff);
+ bool getTX();
+
+ void setRX(bool on_noff);
+ bool getRX();
+
+ void setModeTransmit(); // turn off rx, turn on tx
+ void setModeReceive(); // turn on rx, turn off tx
+ void setModeOff(); // turn off rx, turn off tx, set pwr_dwn bit
+
+ // set tx source
+ // 00 - Mic source
+ // 01 - sine source from tone2
+ // 10 - tx code from GPIO1 code_in (gpio1<1:0> must be set to 01)
+ // 11 - no tx source
+ void setTxSource(uint16_t tx_source);
+ void setTxSourceMic();
+ void setTxSourceSine();
+ void setTxSourceCode();
+ void setTxSourceNone();
+ uint16_t getTxSource();
+
+ // set PA_bias voltage
+ // 000000: 1.01V
+ // 000001:1.05V
+ // 000010:1.09V
+ // 000100: 1.18V
+ // 001000: 1.34V
+ // 010000: 1.68V
+ // 100000: 2.45V
+ // 1111111:3.13V
+ void setPABiasVoltage(uint16_t voltage);
+ uint16_t getPABiasVoltage();
+
+ // Subaudio settings
+
+ // Ctcss/cdcss mode sel
+ // x00=disable,
+ // 001=inner ctcss en,
+ // 010= inner cdcss en
+ // 101= outer ctcss en,
+ // 110=outer cdcss en
+ // others =disable
+ void setCtcssCdcssMode(uint16_t mode);
+ uint16_t getCtcssCdcssMode();
+ void setInnerCtcssMode();
+ void setInnerCdcssMode();
+ void setOuterCtcssMode();
+ void setOuterCdcssMode();
+ void disableCtcssCdcss();
+
+ // Ctcss_sel
+ // 1 = ctcss_cmp/cdcss_cmp out via gpio
+ // 0 = ctcss/cdcss sdo out vio gpio
+ void setCtcssSel(bool cmp_nsdo);
+ bool getCtcssSel();
+
+ // Cdcss_sel
+ // 1 = long (24 bit) code
+ // 0 = short(23 bit) code
+ void setCdcssSel(bool long_nshort);
+ bool getCdcssSel();
+ // Cdcss neg_det_en
+ void enableCdcssNegDet();
+ void disableCdcssNegDet();
+ bool getCdcssNegDetEnabled();
+
+ // Cdcss pos_det_en
+ void enableCdcssPosDet();
+ void disableCdcssPosDet();
+ bool getCdcssPosDetEnabled();
+
+ // css_det_en
+ void enableCssDet();
+ void disableCssDet();
+ bool getCssDetEnabled();
+
+ // ctcss freq
+ void setCtcss(float freq);
+ void setCtcssFreq(uint16_t freq);
+ uint16_t getCtcssFreq();
+ void setCtcssFreqToStandard(); // freq must be 134.4Hz for standard cdcss mode
+
+ // cdcss codes
+ void setCdcssCode(uint16_t code);
+ uint16_t getCdcssCode();
+
+ // SQ
+ void setSQOn();
+ void setSQOff();
+ bool getSQState();
+
+ // SQ threshold
+ void setSQHiThresh(uint16_t sq_hi_threshold); // Sq detect high th, rssi_cmp will be 1 when rssi>th_h_sq, unit 1/8dB
+ uint16_t getSQHiThresh();
+ void setSQLoThresh(uint16_t sq_lo_threshold); // Sq detect low th, rssi_cmp will be 0 when rssi th_h_vox, then vox will be 1(unit mV )
+ uint16_t getVoxOpenThresh();
+ void setVoxShutThresh(uint16_t vox_shut_thresh); // When vssi < th_l_vox && time delay meet, then vox will be 0 (unit mV )
+ uint16_t getVoxShutThresh();
+
+ // Tail Noise
+ void enableTailNoiseElim();
+ void disableTailNoiseElim();
+ bool getTailNoiseElimEnabled();
+
+ // tail noise shift select
+ // Select ctcss phase shift when use tail eliminating function when TX
+ // 00 = 120 degree shift
+ // 01 = 180 degree shift
+ // 10 = 240 degree shift
+ // 11 = reserved
+ void setShiftSelect(uint16_t shift_sel);
+ uint16_t getShiftSelect();
+
+ // DTMF
+ void setDTMFC0(uint16_t freq);
+ uint16_t getDTMFC0();
+ void setDTMFC1(uint16_t freq);
+ uint16_t getDTMFC1();
+ void setDTMFC2(uint16_t freq);
+ uint16_t getDTMFC2();
+ void setDTMFC3(uint16_t freq);
+ uint16_t getDTMFC3();
+ void setDTMFC4(uint16_t freq);
+ uint16_t getDTMFC4();
+ void setDTMFC5(uint16_t freq);
+ uint16_t getDTMFC5();
+ void setDTMFC6(uint16_t freq);
+ uint16_t getDTMFC6();
+ void setDTMFC7(uint16_t freq);
+ uint16_t getDTMFC7();
+
+ // TX FM deviation
+ void setFMVoiceCssDeviation(uint16_t deviation);
+ uint16_t getFMVoiceCssDeviation();
+ void setFMCssDeviation(uint16_t deviation);
+ uint16_t getFMCssDeviation();
+
+ // RX voice range
+ void setVolume1(uint16_t volume);
+ uint16_t getVolume1();
+ void setVolume2(uint16_t volume);
+ uint16_t getVolume2();
+
+ // GPIO
+ void setGpioMode(uint16_t gpio, uint16_t mode);
+ void setGpioHiZ(uint16_t gpio);
+ void setGpioFcn(uint16_t gpio);
+ void setGpioLow(uint16_t gpio);
+ void setGpioHi(uint16_t gpio);
+ uint16_t getGpioMode(uint16_t gpio);
+
+ // Int
+ void enableInterrupt(uint16_t interrupt);
+ void disableInterrupt(uint16_t interrupt);
+ bool getInterruptEnabled(uint16_t interrupt);
+
+ // ST mode
+ void setStMode(uint16_t mode);
+ uint16_t getStMode();
+ void setStFullAuto();
+ void setStRxAutoTxManu();
+ void setStFullManu();
+
+ // Pre-emphasis, De-emphasis filter
+ void bypassPreDeEmph();
+ void usePreDeEmph();
+ bool getPreDeEmphEnabled();
+
+ // Read Only Status Registers
+ int16_t readRSSI();
+ uint16_t readVSSI();
+ uint16_t readDTMFIndex(); // may want to split this into two (index1 and index2)
+ uint16_t readDTMFCode();
+
+ // set output power of radio
+ void setRfPower(uint8_t pwr);
+
+ // channel helper functions
+ bool setGMRSChannel(uint8_t channel);
+ bool setFRSChannel(uint8_t channel);
+ bool setMURSChannel(uint8_t channel);
+ bool setWXChannel(uint8_t channel);
+ uint8_t scanWXChannel();
+
+
+ // restrictions control
+ void dangerMode();
+ void safeMode();
+
+ // utilities
+ uint32_t scanMode(uint32_t start,uint32_t stop, uint8_t speed, uint16_t step, uint16_t threshold);
+ uint32_t findWhitespace(uint32_t start,uint32_t stop, uint8_t dwell, uint16_t step, uint16_t threshold);
+ uint32_t scanChannels(uint32_t buffer[],uint8_t buffsize, uint8_t speed, uint16_t threshold);
+ uint32_t findWhitespaceChannels(uint32_t buffer[],uint8_t buffsize, uint8_t dwell, uint16_t threshold);
+ void buttonMode(uint8_t mode);
+ void isr_ptt();
+ void isr_reset();
+ void morseOut(char buffer[HAMSHIELD_MORSE_BUFFER_SIZE]);
+ char morseLookup(char letter);
+ bool waitForChannel(long timeout, long breakwindow);
+ void SSTVVISCode(int code);
+ void SSTVTestPattern(int code);
+ void toneWait(uint16_t freq, long timer);
+ void toneWaitU(uint16_t freq, long timer);
+ bool parityCalc(int code);
+ // void AFSKOut(char buffer[80]);
+
+
+ private:
+ uint8_t devAddr;
+ uint16_t radio_i2c_buf[4];
+ int pwr_control_pin;
+ uint32_t radio_frequency;
+ uint32_t FRS[];
+ uint32_t GMRS[];
+ uint32_t MURS[];
+ uint32_t WX[];
+
+
+// int8_t A1846S::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout);
+// int8_t A1846S::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout);
+// int8_t A1846S::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout);
+// int8_t A1846S::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout);
+// bool A1846S::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data);
+// bool A1846S::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data);
+};
+
+#endif /* _HAMSHIELD_H_ */
diff --git a/src/I2Cdev_rda.cpp b/src/I2Cdev_rda.cpp
new file mode 100644
index 0000000..2cc4e2b
--- /dev/null
+++ b/src/I2Cdev_rda.cpp
@@ -0,0 +1,1458 @@
+// I2Cdev library collection - Main I2C device class
+// Abstracts bit and byte I2C R/W functions into a convenient class
+// 6/9/2012 by Jeff Rowberg
+//
+// Changelog:
+// 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications
+// 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan)
+// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire
+// - add compiler warnings when using outdated or IDE or limited I2Cdev implementation
+// 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums)
+// 2011-10-03 - added automatic Arduino version detection for ease of use
+// 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications
+// 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x)
+// 2011-08-03 - added optional timeout parameter to read* methods to easily change from default
+// 2011-08-02 - added support for 16-bit registers
+// - fixed incorrect Doxygen comments on some methods
+// - added timeout value for read operations (thanks mem @ Arduino forums)
+// 2011-07-30 - changed read/write function structures to return success or byte counts
+// - made all methods static for multi-device memory savings
+// 2011-07-28 - initial release
+
+/* ============================================
+I2Cdev device library code is placed under the MIT license
+Copyright (c) 2013 Jeff Rowberg
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+===============================================
+*/
+
+#include "I2Cdev_rda.h"
+
+#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
+
+ #ifdef I2CDEV_IMPLEMENTATION_WARNINGS
+ #if ARDUINO < 100
+ #warning Using outdated Arduino IDE with Wire library is functionally limiting.
+ #warning Arduino IDE v1.0.1+ with I2Cdev Fastwire implementation is recommended.
+ #warning This I2Cdev implementation does not support:
+ #warning - Repeated starts conditions
+ #warning - Timeout detection (some Wire requests block forever)
+ #elif ARDUINO == 100
+ #warning Using outdated Arduino IDE with Wire library is functionally limiting.
+ #warning Arduino IDE v1.0.1+ with I2Cdev Fastwire implementation is recommended.
+ #warning This I2Cdev implementation does not support:
+ #warning - Repeated starts conditions
+ #warning - Timeout detection (some Wire requests block forever)
+ #elif ARDUINO > 100
+ #warning Using current Arduino IDE with Wire library is functionally limiting.
+ #warning Arduino IDE v1.0.1+ with I2CDEV_BUILTIN_FASTWIRE implementation is recommended.
+ #warning This I2Cdev implementation does not support:
+ #warning - Timeout detection (some Wire requests block forever)
+ #endif
+ #endif
+
+#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
+
+ //#error The I2CDEV_BUILTIN_FASTWIRE implementation is known to be broken right now. Patience, Iago!
+
+#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE
+
+ #ifdef I2CDEV_IMPLEMENTATION_WARNINGS
+ #warning Using I2CDEV_BUILTIN_NBWIRE implementation may adversely affect interrupt detection.
+ #warning This I2Cdev implementation does not support:
+ #warning - Repeated starts conditions
+ #endif
+
+ // NBWire implementation based heavily on code by Gene Knight
+ // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html
+ // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html
+ TwoWire Wire;
+
+#endif
+
+/** Default constructor.
+ */
+I2Cdev::I2Cdev() {
+}
+
+/** Read a single bit from an 8-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to read from
+ * @param bitNum Bit position to read (0-7)
+ * @param data Container for single bit value
+ * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
+ * @return Status of read operation (true = success)
+ */
+int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) {
+ uint8_t b;
+ uint8_t count = readByte(devAddr, regAddr, &b, timeout);
+ *data = b & (1 << bitNum);
+ return count;
+}
+
+/** Read a single bit from a 16-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to read from
+ * @param bitNum Bit position to read (0-15)
+ * @param data Container for single bit value
+ * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
+ * @return Status of read operation (true = success)
+ */
+int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) {
+ uint16_t b;
+ uint8_t count = readWord(devAddr, regAddr, &b, timeout);
+ *data = b & (1 << bitNum);
+ return count;
+}
+
+/** Read multiple bits from an 8-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to read from
+ * @param bitStart First bit position to read (0-7)
+ * @param length Number of bits to read (not more than 8)
+ * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05)
+ * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
+ * @return Status of read operation (true = success)
+ */
+int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) {
+ // 01101001 read byte
+ // 76543210 bit numbers
+ // xxx args: bitStart=4, length=3
+ // 010 masked
+ // -> 010 shifted
+ uint8_t count, b;
+ if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) {
+ uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
+ b &= mask;
+ b >>= (bitStart - length + 1);
+ *data = b;
+ }
+ return count;
+}
+
+/** Read multiple bits from a 16-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to read from
+ * @param bitStart First bit position to read (0-15)
+ * @param length Number of bits to read (not more than 16)
+ * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05)
+ * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
+ * @return Status of read operation (1 = success, 0 = failure, -1 = timeout)
+ */
+int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) {
+ // 1101011001101001 read byte
+ // fedcba9876543210 bit numbers
+ // xxx args: bitStart=12, length=3
+ // 010 masked
+ // -> 010 shifted
+ uint8_t count;
+ uint16_t w;
+ if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) {
+ uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1);
+ w &= mask;
+ w >>= (bitStart - length + 1);
+ *data = w;
+ }
+ return count;
+}
+
+/** Read single byte from an 8-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to read from
+ * @param data Container for byte value read from device
+ * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
+ * @return Status of read operation (true = success)
+ */
+int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) {
+ return readBytes(devAddr, regAddr, 1, data, timeout);
+}
+
+/** Read single word from a 16-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to read from
+ * @param data Container for word value read from device
+ * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
+ * @return Status of read operation (true = success)
+ */
+int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) {
+ return readWords(devAddr, regAddr, 1, data, timeout);
+}
+
+/** Read multiple bytes from an 8-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr First register regAddr to read from
+ * @param length Number of bytes to read
+ * @param data Buffer to store read data in
+ * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
+ * @return Number of bytes read (-1 indicates failure)
+ */
+int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) {
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print("I2C (0x");
+ Serial.print(devAddr, HEX);
+ Serial.print(") reading ");
+ Serial.print(length, DEC);
+ Serial.print(" bytes from 0x");
+ Serial.print(regAddr, HEX);
+ Serial.print("...");
+ #endif
+
+ int8_t count = 0;
+ uint32_t t1 = millis();
+
+ #if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE)
+
+ #if (ARDUINO < 100)
+ // Arduino v00xx (before v1.0), Wire library
+
+ // I2C/TWI subsystem uses internal buffer that breaks with large data requests
+ // so if user requests more than BUFFER_LENGTH bytes, we have to do it in
+ // smaller chunks instead of all at once
+ for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) {
+ Wire.beginTransmission(devAddr);
+ Wire.send(regAddr);
+ Wire.endTransmission();
+ Wire.beginTransmission(devAddr);
+ Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH));
+
+ for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {
+ data[count] = Wire.receive();
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(data[count], HEX);
+ if (count + 1 < length) Serial.print(" ");
+ #endif
+ }
+
+ Wire.endTransmission();
+ }
+ #elif (ARDUINO == 100)
+ // Arduino v1.0.0, Wire library
+ // Adds standardized write() and read() stream methods instead of send() and receive()
+
+ // I2C/TWI subsystem uses internal buffer that breaks with large data requests
+ // so if user requests more than BUFFER_LENGTH bytes, we have to do it in
+ // smaller chunks instead of all at once
+ for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) {
+ Wire.beginTransmission(devAddr);
+ Wire.write(regAddr);
+ Wire.endTransmission();
+ Wire.beginTransmission(devAddr);
+ Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH));
+
+ for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {
+ data[count] = Wire.read();
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(data[count], HEX);
+ if (count + 1 < length) Serial.print(" ");
+ #endif
+ }
+
+ Wire.endTransmission();
+ }
+ #elif (ARDUINO > 100)
+ // Arduino v1.0.1+, Wire library
+ // Adds official support for repeated start condition, yay!
+
+ // I2C/TWI subsystem uses internal buffer that breaks with large data requests
+ // so if user requests more than BUFFER_LENGTH bytes, we have to do it in
+ // smaller chunks instead of all at once
+ for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) {
+ Wire.beginTransmission(devAddr);
+ Wire.write(regAddr);
+ Wire.endTransmission();
+ Wire.beginTransmission(devAddr);
+ Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH));
+
+ for (; Wire.available() && (timeout == 0 || millis() - t1 < timeout); count++) {
+ data[count] = Wire.read();
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(data[count], HEX);
+ if (count + 1 < length) Serial.print(" ");
+ #endif
+ }
+ }
+ #endif
+
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
+
+ // Fastwire library
+ // no loop required for fastwire
+ uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, data, length);
+ if (status == 0) {
+ count = length; // success
+ } else {
+ count = -1; // error
+ }
+
+ #endif
+
+ // check for timeout
+ if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout
+
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(". Done (");
+ Serial.print(count, DEC);
+ Serial.println(" read).");
+ #endif
+
+ return count;
+}
+
+/** Read multiple words from a 16-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr First register regAddr to read from
+ * @param length Number of words to read
+ * @param data Buffer to store read data in
+ * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout)
+ * @return Number of words read (-1 indicates failure)
+ */
+int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) {
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print("I2C (0x");
+ Serial.print(devAddr, HEX);
+ Serial.print(") reading ");
+ Serial.print(length, DEC);
+ Serial.print(" words from 0x");
+ Serial.print(regAddr, HEX);
+ Serial.print("...");
+ #endif
+
+ int8_t count = 0;
+ uint32_t t1 = millis();
+
+ #if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE)
+
+ #if (ARDUINO < 100)
+ // Arduino v00xx (before v1.0), Wire library
+
+ // I2C/TWI subsystem uses internal buffer that breaks with large data requests
+ // so if user requests more than BUFFER_LENGTH bytes, we have to do it in
+ // smaller chunks instead of all at once
+ for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) {
+ Wire.beginTransmission(devAddr);
+ Wire.send(regAddr);
+ Wire.endTransmission();
+ Wire.beginTransmission(devAddr);
+ Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
+
+ bool msb = true; // starts with MSB, then LSB
+ for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
+ if (msb) {
+ // first byte is bits 15-8 (MSb=15)
+ data[count] = Wire.receive() << 8;
+ } else {
+ // second byte is bits 7-0 (LSb=0)
+ data[count] |= Wire.receive();
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(data[count], HEX);
+ if (count + 1 < length) Serial.print(" ");
+ #endif
+ count++;
+ }
+ msb = !msb;
+ }
+
+ Wire.endTransmission();
+ }
+ #elif (ARDUINO == 100)
+ // Arduino v1.0.0, Wire library
+ // Adds standardized write() and read() stream methods instead of send() and receive()
+
+ // I2C/TWI subsystem uses internal buffer that breaks with large data requests
+ // so if user requests more than BUFFER_LENGTH bytes, we have to do it in
+ // smaller chunks instead of all at once
+ for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) {
+ Wire.beginTransmission(devAddr);
+ Wire.write(regAddr);
+ Wire.endTransmission();
+ Wire.beginTransmission(devAddr);
+ Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
+
+ bool msb = true; // starts with MSB, then LSB
+ for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
+ if (msb) {
+ // first byte is bits 15-8 (MSb=15)
+ data[count] = Wire.read() << 8;
+ } else {
+ // second byte is bits 7-0 (LSb=0)
+ data[count] |= Wire.read();
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(data[count], HEX);
+ if (count + 1 < length) Serial.print(" ");
+ #endif
+ count++;
+ }
+ msb = !msb;
+ }
+
+ Wire.endTransmission();
+ }
+ #elif (ARDUINO > 100)
+ //Serial.println("wires");
+ // Arduino v1.0.1+, Wire library
+ // Adds official support for repeated start condition, yay!
+
+ // I2C/TWI subsystem uses internal buffer that breaks with large data requests
+ // so if user requests more than BUFFER_LENGTH bytes, we have to do it in
+ // smaller chunks instead of all at once
+ for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) {
+ Wire.beginTransmission(devAddr);
+ Wire.write(regAddr);
+ Wire.endTransmission(false);
+// Wire.beginTransmission(devAddr);
+ Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes
+
+ bool msb = true; // starts with MSB, then LSB
+ for (; Wire.available() && count < length && (timeout == 0 || millis() - t1 < timeout);) {
+ if (msb) {
+ // first byte is bits 15-8 (MSb=15)
+ data[count] = Wire.read() << 8;
+ } else {
+ // second byte is bits 7-0 (LSb=0)
+ data[count] |= Wire.read();
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(data[count], HEX);
+ if (count + 1 < length) Serial.print(" ");
+ #endif
+ count++;
+ }
+ msb = !msb;
+ }
+
+ Wire.endTransmission();
+ }
+ #endif
+
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
+
+ // Fastwire library
+ // no loop required for fastwire
+ uint16_t intermediate[(uint8_t)length];
+ uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, (uint8_t *)intermediate, (uint8_t)(length * 2));
+ if (status == 0) {
+ count = length; // success
+ for (uint8_t i = 0; i < length; i++) {
+ data[i] = (intermediate[2*i] << 8) | intermediate[2*i + 1];
+ }
+ } else {
+ count = -1; // error
+ }
+
+ #endif
+
+ if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout
+
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(". Done (");
+ Serial.print(count, DEC);
+ Serial.println(" read).");
+ #endif
+
+ return count;
+}
+
+/** write a single bit in an 8-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to write to
+ * @param bitNum Bit position to write (0-7)
+ * @param value New bit value to write
+ * @return Status of operation (true = success)
+ */
+bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) {
+ uint8_t b;
+ readByte(devAddr, regAddr, &b);
+ b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
+ return writeByte(devAddr, regAddr, b);
+}
+
+/** write a single bit in a 16-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to write to
+ * @param bitNum Bit position to write (0-15)
+ * @param value New bit value to write
+ * @return Status of operation (true = success)
+ */
+bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) {
+ uint16_t w;
+ readWord(devAddr, regAddr, &w);
+ w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum));
+ return writeWord(devAddr, regAddr, w);
+}
+
+/** Write multiple bits in an 8-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to write to
+ * @param bitStart First bit position to write (0-7)
+ * @param length Number of bits to write (not more than 8)
+ * @param data Right-aligned value to write
+ * @return Status of operation (true = success)
+ */
+bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) {
+ // 010 value to write
+ // 76543210 bit numbers
+ // xxx args: bitStart=4, length=3
+ // 00011100 mask byte
+ // 10101111 original value (sample)
+ // 10100011 original & ~mask
+ // 10101011 masked | value
+ uint8_t b;
+ if (readByte(devAddr, regAddr, &b) != 0) {
+ uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
+ data <<= (bitStart - length + 1); // shift data into correct position
+ data &= mask; // zero all non-important bits in data
+ b &= ~(mask); // zero all important bits in existing byte
+ b |= data; // combine data with existing byte
+ return writeByte(devAddr, regAddr, b);
+ } else {
+ return false;
+ }
+}
+
+/** Write multiple bits in a 16-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register regAddr to write to
+ * @param bitStart First bit position to write (0-15)
+ * @param length Number of bits to write (not more than 16)
+ * @param data Right-aligned value to write
+ * @return Status of operation (true = success)
+ */
+bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) {
+ // 010 value to write
+ // fedcba9876543210 bit numbers
+ // xxx args: bitStart=12, length=3
+ // 0001110000000000 mask word
+ // 1010111110010110 original value (sample)
+ // 1010001110010110 original & ~mask
+ // 1010101110010110 masked | value
+ uint16_t w;
+ if (readWord(devAddr, regAddr, &w) != 0) {
+ uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1);
+ data <<= (bitStart - length + 1); // shift data into correct position
+ data &= mask; // zero all non-important bits in data
+ w &= ~(mask); // zero all important bits in existing word
+ w |= data; // combine data with existing word
+ return writeWord(devAddr, regAddr, w);
+ } else {
+ return false;
+ }
+}
+
+/** Write single byte to an 8-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register address to write to
+ * @param data New byte value to write
+ * @return Status of operation (true = success)
+ */
+bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) {
+ return writeBytes(devAddr, regAddr, 1, &data);
+}
+
+/** Write single word to a 16-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr Register address to write to
+ * @param data New word value to write
+ * @return Status of operation (true = success)
+ */
+bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) {
+ return writeWords(devAddr, regAddr, 1, &data);
+}
+
+/** Write multiple bytes to an 8-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr First register address to write to
+ * @param length Number of bytes to write
+ * @param data Buffer to copy new data from
+ * @return Status of operation (true = success)
+ */
+bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) {
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print("I2C (0x");
+ Serial.print(devAddr, HEX);
+ Serial.print(") writing ");
+ Serial.print(length, DEC);
+ Serial.print(" bytes to 0x");
+ Serial.print(regAddr, HEX);
+ Serial.print("...");
+ #endif
+ uint8_t status = 0;
+ #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
+ Wire.beginTransmission(devAddr);
+ Wire.send((uint8_t) regAddr); // send address
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
+ Wire.beginTransmission(devAddr);
+ Wire.write((uint8_t) regAddr); // send address
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
+ Fastwire::beginTransmission(devAddr);
+ Fastwire::write(regAddr);
+ #endif
+ for (uint8_t i = 0; i < length; i++) {
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(data[i], HEX);
+ if (i + 1 < length) Serial.print(" ");
+ #endif
+ #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
+ Wire.send((uint8_t) data[i]);
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
+ Wire.write((uint8_t) data[i]);
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
+ Fastwire::write((uint8_t) data[i]);
+ #endif
+ }
+ #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
+ Wire.endTransmission();
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
+ status = Wire.endTransmission();
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
+ Fastwire::stop();
+ //status = Fastwire::endTransmission();
+ #endif
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.println(". Done.");
+ #endif
+ return status == 0;
+}
+
+/** Write multiple words to a 16-bit device register.
+ * @param devAddr I2C slave device address
+ * @param regAddr First register address to write to
+ * @param length Number of words to write
+ * @param data Buffer to copy new data from
+ * @return Status of operation (true = success)
+ */
+bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data) {
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print("I2C (0x");
+ Serial.print(devAddr, HEX);
+ Serial.print(") writing ");
+ Serial.print(length, DEC);
+ Serial.print(" words to 0x");
+ Serial.print(regAddr, HEX);
+ Serial.print("...");
+ #endif
+ uint8_t status = 0;
+ #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
+ Wire.beginTransmission(devAddr);
+ Wire.send(regAddr); // send address
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
+ Wire.beginTransmission(devAddr);
+ Wire.write(regAddr); // send address
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
+ Fastwire::beginTransmission(devAddr);
+ Fastwire::write(regAddr);
+ #endif
+ for (uint8_t i = 0; i < length * 2; i++) {
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.print(data[i], HEX);
+ if (i + 1 < length) Serial.print(" ");
+ #endif
+ #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
+ Wire.send((uint8_t)(data[i] >> 8)); // send MSB
+ Wire.send((uint8_t)data[i++]); // send LSB
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
+ Wire.write((uint8_t)(data[i] >> 8)); // send MSB
+ Wire.write((uint8_t)data[i++]); // send LSB
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
+ Fastwire::write((uint8_t)(data[i] >> 8)); // send MSB
+ status = Fastwire::write((uint8_t)data[i++]); // send LSB
+ if (status != 0) break;
+ #endif
+ }
+ #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE)
+ Wire.endTransmission();
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100)
+ status = Wire.endTransmission();
+ #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE)
+ Fastwire::stop();
+ //status = Fastwire::endTransmission();
+ #endif
+ #ifdef I2CDEV_SERIAL_DEBUG
+ Serial.println(". Done.");
+ #endif
+ return status == 0;
+}
+
+/** Default timeout value for read operations.
+ * Set this to 0 to disable timeout detection.
+ */
+uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT;
+
+#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
+ // I2C library
+ //////////////////////
+ // Copyright(C) 2012
+ // Francesco Ferrara
+ // ferrara[at]libero[point]it
+ //////////////////////
+
+ /*
+ FastWire
+ - 0.24 added stop
+ - 0.23 added reset
+
+ This is a library to help faster programs to read I2C devices.
+ Copyright(C) 2012 Francesco Ferrara
+ occhiobello at gmail dot com
+ [used by Jeff Rowberg for I2Cdevlib with permission]
+ */
+
+ boolean Fastwire::waitInt() {
+ int l = 250;
+ while (!(TWCR & (1 << TWINT)) && l-- > 0);
+ return l > 0;
+ }
+
+ void Fastwire::setup(int khz, boolean pullup) {
+ TWCR = 0;
+ #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
+ // activate internal pull-ups for twi (PORTC bits 4 & 5)
+ // as per note from atmega8 manual pg167
+ if (pullup) PORTC |= ((1 << 4) | (1 << 5));
+ else PORTC &= ~((1 << 4) | (1 << 5));
+ #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
+ // activate internal pull-ups for twi (PORTC bits 0 & 1)
+ if (pullup) PORTC |= ((1 << 0) | (1 << 1));
+ else PORTC &= ~((1 << 0) | (1 << 1));
+ #else
+ // activate internal pull-ups for twi (PORTD bits 0 & 1)
+ // as per note from atmega128 manual pg204
+ if (pullup) PORTD |= ((1 << 0) | (1 << 1));
+ else PORTD &= ~((1 << 0) | (1 << 1));
+ #endif
+
+ TWSR = 0; // no prescaler => prescaler = 1
+ TWBR = ((16000L / khz) - 16) / 2; // change the I2C clock rate
+ TWCR = 1 << TWEN; // enable twi module, no interrupt
+ }
+
+ // added by Jeff Rowberg 2013-05-07:
+ // Arduino Wire-style "beginTransmission" function
+ // (takes 7-bit device address like the Wire method, NOT 8-bit: 0x68, not 0xD0/0xD1)
+ byte Fastwire::beginTransmission(byte device) {
+ byte twst, retry;
+ retry = 2;
+ do {
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA);
+ if (!waitInt()) return 1;
+ twst = TWSR & 0xF8;
+ if (twst != TW_START && twst != TW_REP_START) return 2;
+
+ //Serial.print(device, HEX);
+ //Serial.print(" ");
+ TWDR = device << 1; // send device address without read bit (1)
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ if (!waitInt()) return 3;
+ twst = TWSR & 0xF8;
+ } while (twst == TW_MT_SLA_NACK && retry-- > 0);
+ if (twst != TW_MT_SLA_ACK) return 4;
+ return 0;
+ }
+
+ byte Fastwire::writeBuf(byte device, byte address, byte *data, byte num) {
+ byte twst, retry;
+
+ retry = 2;
+ do {
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA);
+ if (!waitInt()) return 1;
+ twst = TWSR & 0xF8;
+ if (twst != TW_START && twst != TW_REP_START) return 2;
+
+ //Serial.print(device, HEX);
+ //Serial.print(" ");
+ TWDR = device & 0xFE; // send device address without read bit (1)
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ if (!waitInt()) return 3;
+ twst = TWSR & 0xF8;
+ } while (twst == TW_MT_SLA_NACK && retry-- > 0);
+ if (twst != TW_MT_SLA_ACK) return 4;
+
+ //Serial.print(address, HEX);
+ //Serial.print(" ");
+ TWDR = address; // send data to the previously addressed device
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ if (!waitInt()) return 5;
+ twst = TWSR & 0xF8;
+ if (twst != TW_MT_DATA_ACK) return 6;
+
+ for (byte i = 0; i < num; i++) {
+ //Serial.print(data[i], HEX);
+ //Serial.print(" ");
+ TWDR = data[i]; // send data to the previously addressed device
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ if (!waitInt()) return 7;
+ twst = TWSR & 0xF8;
+ if (twst != TW_MT_DATA_ACK) return 8;
+ }
+ //Serial.print("\n");
+
+ return 0;
+ }
+
+ byte Fastwire::write(byte value) {
+ byte twst;
+ //Serial.println(value, HEX);
+ TWDR = value; // send data
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ if (!waitInt()) return 1;
+ twst = TWSR & 0xF8;
+ if (twst != TW_MT_DATA_ACK) return 2;
+ return 0;
+ }
+
+ byte Fastwire::readBuf(byte device, byte address, byte *data, byte num) {
+ byte twst, retry;
+
+ retry = 2;
+ do {
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA);
+ if (!waitInt()) return 16;
+ twst = TWSR & 0xF8;
+ if (twst != TW_START && twst != TW_REP_START) return 17;
+
+ //Serial.print(device, HEX);
+ //Serial.print(" ");
+ TWDR = device & 0xfe; // send device address to write
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ if (!waitInt()) return 18;
+ twst = TWSR & 0xF8;
+ } while (twst == TW_MT_SLA_NACK && retry-- > 0);
+ if (twst != TW_MT_SLA_ACK) return 19;
+
+ //Serial.print(address, HEX);
+ //Serial.print(" ");
+ TWDR = address; // send data to the previously addressed device
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ if (!waitInt()) return 20;
+ twst = TWSR & 0xF8;
+ if (twst != TW_MT_DATA_ACK) return 21;
+
+ /***/
+
+ retry = 2;
+ do {
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA);
+ if (!waitInt()) return 22;
+ twst = TWSR & 0xF8;
+ if (twst != TW_START && twst != TW_REP_START) return 23;
+
+ //Serial.print(device, HEX);
+ //Serial.print(" ");
+ TWDR = device | 0x01; // send device address with the read bit (1)
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ if (!waitInt()) return 24;
+ twst = TWSR & 0xF8;
+ } while (twst == TW_MR_SLA_NACK && retry-- > 0);
+ if (twst != TW_MR_SLA_ACK) return 25;
+
+ for (uint8_t i = 0; i < num; i++) {
+ if (i == num - 1)
+ TWCR = (1 << TWINT) | (1 << TWEN);
+ else
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
+ if (!waitInt()) return 26;
+ twst = TWSR & 0xF8;
+ if (twst != TW_MR_DATA_ACK && twst != TW_MR_DATA_NACK) return twst;
+ data[i] = TWDR;
+ //Serial.print(data[i], HEX);
+ //Serial.print(" ");
+ }
+ //Serial.print("\n");
+ stop();
+
+ return 0;
+ }
+
+ void Fastwire::reset() {
+ TWCR = 0;
+ }
+
+ byte Fastwire::stop() {
+ TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
+ if (!waitInt()) return 1;
+ return 0;
+ }
+#endif
+
+#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE
+ // NBWire implementation based heavily on code by Gene Knight
+ // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html
+ // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html
+
+ /*
+ call this version 1.0
+
+ Offhand, the only funky part that I can think of is in nbrequestFrom, where the buffer
+ length and index are set *before* the data is actually read. The problem is that these
+ are variables local to the TwoWire object, and by the time we actually have read the
+ data, and know what the length actually is, we have no simple access to the object's
+ variables. The actual bytes read *is* given to the callback function, though.
+
+ The ISR code for a slave receiver is commented out. I don't have that setup, and can't
+ verify it at this time. Save it for 2.0!
+
+ The handling of the read and write processes here is much like in the demo sketch code:
+ the process is broken down into sequential functions, where each registers the next as a
+ callback, essentially.
+
+ For example, for the Read process, twi_read00 just returns if TWI is not yet in a
+ ready state. When there's another interrupt, and the interface *is* ready, then it
+ sets up the read, starts it, and registers twi_read01 as the function to call after
+ the *next* interrupt. twi_read01, then, just returns if the interface is still in a
+ "reading" state. When the reading is done, it copies the information to the buffer,
+ cleans up, and calls the user-requested callback function with the actual number of
+ bytes read.
+
+ The writing is similar.
+
+ Questions, comments and problems can go to Gene@Telobot.com.
+
+ Thumbs Up!
+ Gene Knight
+
+ */
+
+ uint8_t TwoWire::rxBuffer[NBWIRE_BUFFER_LENGTH];
+ uint8_t TwoWire::rxBufferIndex = 0;
+ uint8_t TwoWire::rxBufferLength = 0;
+
+ uint8_t TwoWire::txAddress = 0;
+ uint8_t TwoWire::txBuffer[NBWIRE_BUFFER_LENGTH];
+ uint8_t TwoWire::txBufferIndex = 0;
+ uint8_t TwoWire::txBufferLength = 0;
+
+ //uint8_t TwoWire::transmitting = 0;
+ void (*TwoWire::user_onRequest)(void);
+ void (*TwoWire::user_onReceive)(int);
+
+ static volatile uint8_t twi_transmitting;
+ static volatile uint8_t twi_state;
+ static uint8_t twi_slarw;
+ static volatile uint8_t twi_error;
+ static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
+ static volatile uint8_t twi_masterBufferIndex;
+ static uint8_t twi_masterBufferLength;
+ static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
+ static volatile uint8_t twi_rxBufferIndex;
+ //static volatile uint8_t twi_Interrupt_Continue_Command;
+ static volatile uint8_t twi_Return_Value;
+ static volatile uint8_t twi_Done;
+ void (*twi_cbendTransmissionDone)(int);
+ void (*twi_cbreadFromDone)(int);
+
+ void twi_init() {
+ // initialize state
+ twi_state = TWI_READY;
+
+ // activate internal pull-ups for twi
+ // as per note from atmega8 manual pg167
+ sbi(PORTC, 4);
+ sbi(PORTC, 5);
+
+ // initialize twi prescaler and bit rate
+ cbi(TWSR, TWPS0); // TWI Status Register - Prescaler bits
+ cbi(TWSR, TWPS1);
+
+ /* twi bit rate formula from atmega128 manual pg 204
+ SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
+ note: TWBR should be 10 or higher for master mode
+ It is 72 for a 16mhz Wiring board with 100kHz TWI */
+
+ TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; // bitrate register
+ // enable twi module, acks, and twi interrupt
+
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
+
+ /* TWEN - TWI Enable Bit
+ TWIE - TWI Interrupt Enable
+ TWEA - TWI Enable Acknowledge Bit
+ TWINT - TWI Interrupt Flag
+ TWSTA - TWI Start Condition
+ */
+ }
+
+ typedef struct {
+ uint8_t address;
+ uint8_t* data;
+ uint8_t length;
+ uint8_t wait;
+ uint8_t i;
+ } twi_Write_Vars;
+
+ twi_Write_Vars *ptwv = 0;
+ static void (*fNextInterruptFunction)(void) = 0;
+
+ void twi_Finish(byte bRetVal) {
+ if (ptwv) {
+ free(ptwv);
+ ptwv = 0;
+ }
+ twi_Done = 0xFF;
+ twi_Return_Value = bRetVal;
+ fNextInterruptFunction = 0;
+ }
+
+ uint8_t twii_WaitForDone(uint16_t timeout) {
+ uint32_t endMillis = millis() + timeout;
+ while (!twi_Done && (timeout == 0 || millis() < endMillis)) continue;
+ return twi_Return_Value;
+ }
+
+ void twii_SetState(uint8_t ucState) {
+ twi_state = ucState;
+ }
+
+ void twii_SetError(uint8_t ucError) {
+ twi_error = ucError ;
+ }
+
+ void twii_InitBuffer(uint8_t ucPos, uint8_t ucLength) {
+ twi_masterBufferIndex = 0;
+ twi_masterBufferLength = ucLength;
+ }
+
+ void twii_CopyToBuf(uint8_t* pData, uint8_t ucLength) {
+ uint8_t i;
+ for (i = 0; i < ucLength; ++i) {
+ twi_masterBuffer[i] = pData[i];
+ }
+ }
+
+ void twii_CopyFromBuf(uint8_t *pData, uint8_t ucLength) {
+ uint8_t i;
+ for (i = 0; i < ucLength; ++i) {
+ pData[i] = twi_masterBuffer[i];
+ }
+ }
+
+ void twii_SetSlaRW(uint8_t ucSlaRW) {
+ twi_slarw = ucSlaRW;
+ }
+
+ void twii_SetStart() {
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
+ }
+
+ void twi_write01() {
+ if (TWI_MTX == twi_state) return; // blocking test
+ twi_transmitting = 0 ;
+ if (twi_error == 0xFF)
+ twi_Finish (0); // success
+ else if (twi_error == TW_MT_SLA_NACK)
+ twi_Finish (2); // error: address send, nack received
+ else if (twi_error == TW_MT_DATA_NACK)
+ twi_Finish (3); // error: data send, nack received
+ else
+ twi_Finish (4); // other twi error
+ if (twi_cbendTransmissionDone) return twi_cbendTransmissionDone(twi_Return_Value);
+ return;
+ }
+
+
+ void twi_write00() {
+ if (TWI_READY != twi_state) return; // blocking test
+ if (TWI_BUFFER_LENGTH < ptwv -> length) {
+ twi_Finish(1); // end write with error 1
+ return;
+ }
+ twi_Done = 0x00; // show as working
+ twii_SetState(TWI_MTX); // to transmitting
+ twii_SetError(0xFF); // to No Error
+ twii_InitBuffer(0, ptwv -> length); // pointer and length
+ twii_CopyToBuf(ptwv -> data, ptwv -> length); // get the data
+ twii_SetSlaRW((ptwv -> address << 1) | TW_WRITE); // write command
+ twii_SetStart(); // start the cycle
+ fNextInterruptFunction = twi_write01; // next routine
+ return twi_write01();
+ }
+
+ void twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) {
+ uint8_t i;
+ ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars));
+ ptwv -> address = address;
+ ptwv -> data = data;
+ ptwv -> length = length;
+ ptwv -> wait = wait;
+ fNextInterruptFunction = twi_write00;
+ return twi_write00();
+ }
+
+ void twi_read01() {
+ if (TWI_MRX == twi_state) return; // blocking test
+ if (twi_masterBufferIndex < ptwv -> length) ptwv -> length = twi_masterBufferIndex;
+ twii_CopyFromBuf(ptwv -> data, ptwv -> length);
+ twi_Finish(ptwv -> length);
+ if (twi_cbreadFromDone) return twi_cbreadFromDone(twi_Return_Value);
+ return;
+ }
+
+ void twi_read00() {
+ if (TWI_READY != twi_state) return; // blocking test
+ if (TWI_BUFFER_LENGTH < ptwv -> length) twi_Finish(0); // error return
+ twi_Done = 0x00; // show as working
+ twii_SetState(TWI_MRX); // reading
+ twii_SetError(0xFF); // reset error
+ twii_InitBuffer(0, ptwv -> length - 1); // init to one less than length
+ twii_SetSlaRW((ptwv -> address << 1) | TW_READ); // read command
+ twii_SetStart(); // start cycle
+ fNextInterruptFunction = twi_read01;
+ return twi_read01();
+ }
+
+ void twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) {
+ uint8_t i;
+
+ ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars));
+ ptwv -> address = address;
+ ptwv -> data = data;
+ ptwv -> length = length;
+ fNextInterruptFunction = twi_read00;
+ return twi_read00();
+ }
+
+ void twi_reply(uint8_t ack) {
+ // transmit master read ready signal, with or without ack
+ if (ack){
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
+ } else {
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
+ }
+ }
+
+ void twi_stop(void) {
+ // send stop condition
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
+
+ // wait for stop condition to be exectued on bus
+ // TWINT is not set after a stop condition!
+ while (TWCR & _BV(TWSTO)) {
+ continue;
+ }
+
+ // update twi state
+ twi_state = TWI_READY;
+ }
+
+ void twi_releaseBus(void) {
+ // release bus
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
+
+ // update twi state
+ twi_state = TWI_READY;
+ }
+
+ SIGNAL(TWI_vect) {
+ switch (TW_STATUS) {
+ // All Master
+ case TW_START: // sent start condition
+ case TW_REP_START: // sent repeated start condition
+ // copy device address and r/w bit to output register and ack
+ TWDR = twi_slarw;
+ twi_reply(1);
+ break;
+
+ // Master Transmitter
+ case TW_MT_SLA_ACK: // slave receiver acked address
+ case TW_MT_DATA_ACK: // slave receiver acked data
+ // if there is data to send, send it, otherwise stop
+ if (twi_masterBufferIndex < twi_masterBufferLength) {
+ // copy data to output register and ack
+ TWDR = twi_masterBuffer[twi_masterBufferIndex++];
+ twi_reply(1);
+ } else {
+ twi_stop();
+ }
+ break;
+
+ case TW_MT_SLA_NACK: // address sent, nack received
+ twi_error = TW_MT_SLA_NACK;
+ twi_stop();
+ break;
+
+ case TW_MT_DATA_NACK: // data sent, nack received
+ twi_error = TW_MT_DATA_NACK;
+ twi_stop();
+ break;
+
+ case TW_MT_ARB_LOST: // lost bus arbitration
+ twi_error = TW_MT_ARB_LOST;
+ twi_releaseBus();
+ break;
+
+ // Master Receiver
+ case TW_MR_DATA_ACK: // data received, ack sent
+ // put byte into buffer
+ twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
+
+ case TW_MR_SLA_ACK: // address sent, ack received
+ // ack if more bytes are expected, otherwise nack
+ if (twi_masterBufferIndex < twi_masterBufferLength) {
+ twi_reply(1);
+ } else {
+ twi_reply(0);
+ }
+ break;
+
+ case TW_MR_DATA_NACK: // data received, nack sent
+ // put final byte into buffer
+ twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
+
+ case TW_MR_SLA_NACK: // address sent, nack received
+ twi_stop();
+ break;
+
+ // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case
+
+ // Slave Receiver (NOT IMPLEMENTED YET)
+ /*
+ case TW_SR_SLA_ACK: // addressed, returned ack
+ case TW_SR_GCALL_ACK: // addressed generally, returned ack
+ case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack
+ case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack
+ // enter slave receiver mode
+ twi_state = TWI_SRX;
+
+ // indicate that rx buffer can be overwritten and ack
+ twi_rxBufferIndex = 0;
+ twi_reply(1);
+ break;
+
+ case TW_SR_DATA_ACK: // data received, returned ack
+ case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
+ // if there is still room in the rx buffer
+ if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) {
+ // put byte in buffer and ack
+ twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
+ twi_reply(1);
+ } else {
+ // otherwise nack
+ twi_reply(0);
+ }
+ break;
+
+ case TW_SR_STOP: // stop or repeated start condition received
+ // put a null char after data if there's room
+ if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) {
+ twi_rxBuffer[twi_rxBufferIndex] = 0;
+ }
+
+ // sends ack and stops interface for clock stretching
+ twi_stop();
+
+ // callback to user defined callback
+ twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
+
+ // since we submit rx buffer to "wire" library, we can reset it
+ twi_rxBufferIndex = 0;
+
+ // ack future responses and leave slave receiver state
+ twi_releaseBus();
+ break;
+
+ case TW_SR_DATA_NACK: // data received, returned nack
+ case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
+ // nack back at master
+ twi_reply(0);
+ break;
+
+ // Slave Transmitter
+ case TW_ST_SLA_ACK: // addressed, returned ack
+ case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
+ // enter slave transmitter mode
+ twi_state = TWI_STX;
+
+ // ready the tx buffer index for iteration
+ twi_txBufferIndex = 0;
+
+ // set tx buffer length to be zero, to verify if user changes it
+ twi_txBufferLength = 0;
+
+ // request for txBuffer to be filled and length to be set
+ // note: user must call twi_transmit(bytes, length) to do this
+ twi_onSlaveTransmit();
+
+ // if they didn't change buffer & length, initialize it
+ if (0 == twi_txBufferLength) {
+ twi_txBufferLength = 1;
+ twi_txBuffer[0] = 0x00;
+ }
+
+ // transmit first byte from buffer, fall through
+
+ case TW_ST_DATA_ACK: // byte sent, ack returned
+ // copy data to output register
+ TWDR = twi_txBuffer[twi_txBufferIndex++];
+
+ // if there is more to send, ack, otherwise nack
+ if (twi_txBufferIndex < twi_txBufferLength) {
+ twi_reply(1);
+ } else {
+ twi_reply(0);
+ }
+ break;
+
+ case TW_ST_DATA_NACK: // received nack, we are done
+ case TW_ST_LAST_DATA: // received ack, but we are done already!
+ // ack future responses
+ twi_reply(1);
+ // leave slave receiver state
+ twi_state = TWI_READY;
+ break;
+ */
+
+ // all
+ case TW_NO_INFO: // no state information
+ break;
+
+ case TW_BUS_ERROR: // bus error, illegal stop/start
+ twi_error = TW_BUS_ERROR;
+ twi_stop();
+ break;
+ }
+
+ if (fNextInterruptFunction) return fNextInterruptFunction();
+ }
+
+ TwoWire::TwoWire() { }
+
+ void TwoWire::begin(void) {
+ rxBufferIndex = 0;
+ rxBufferLength = 0;
+
+ txBufferIndex = 0;
+ txBufferLength = 0;
+
+ twi_init();
+ }
+
+ void TwoWire::beginTransmission(uint8_t address) {
+ //beginTransmission((uint8_t)address);
+
+ // indicate that we are transmitting
+ twi_transmitting = 1;
+
+ // set address of targeted slave
+ txAddress = address;
+
+ // reset tx buffer iterator vars
+ txBufferIndex = 0;
+ txBufferLength = 0;
+ }
+
+ uint8_t TwoWire::endTransmission(uint16_t timeout) {
+ // transmit buffer (blocking)
+ //int8_t ret =
+ twi_cbendTransmissionDone = NULL;
+ twi_writeTo(txAddress, txBuffer, txBufferLength, 1);
+ int8_t ret = twii_WaitForDone(timeout);
+
+ // reset tx buffer iterator vars
+ txBufferIndex = 0;
+ txBufferLength = 0;
+
+ // indicate that we are done transmitting
+ // twi_transmitting = 0;
+ return ret;
+ }
+
+ void TwoWire::nbendTransmission(void (*function)(int)) {
+ twi_cbendTransmissionDone = function;
+ twi_writeTo(txAddress, txBuffer, txBufferLength, 1);
+ return;
+ }
+
+ void TwoWire::send(uint8_t data) {
+ if (twi_transmitting) {
+ // in master transmitter mode
+ // don't bother if buffer is full
+ if (txBufferLength >= NBWIRE_BUFFER_LENGTH) {
+ return;
+ }
+
+ // put byte in tx buffer
+ txBuffer[txBufferIndex] = data;
+ ++txBufferIndex;
+
+ // update amount in buffer
+ txBufferLength = txBufferIndex;
+ } else {
+ // in slave send mode
+ // reply to master
+ //twi_transmit(&data, 1);
+ }
+ }
+
+ uint8_t TwoWire::receive(void) {
+ // default to returning null char
+ // for people using with char strings
+ uint8_t value = 0;
+
+ // get each successive byte on each call
+ if (rxBufferIndex < rxBufferLength) {
+ value = rxBuffer[rxBufferIndex];
+ ++rxBufferIndex;
+ }
+
+ return value;
+ }
+
+ uint8_t TwoWire::requestFrom(uint8_t address, int quantity, uint16_t timeout) {
+ // clamp to buffer length
+ if (quantity > NBWIRE_BUFFER_LENGTH) {
+ quantity = NBWIRE_BUFFER_LENGTH;
+ }
+
+ // perform blocking read into buffer
+ twi_cbreadFromDone = NULL;
+ twi_readFrom(address, rxBuffer, quantity);
+ uint8_t read = twii_WaitForDone(timeout);
+
+ // set rx buffer iterator vars
+ rxBufferIndex = 0;
+ rxBufferLength = read;
+
+ return read;
+ }
+
+ void TwoWire::nbrequestFrom(uint8_t address, int quantity, void (*function)(int)) {
+ // clamp to buffer length
+ if (quantity > NBWIRE_BUFFER_LENGTH) {
+ quantity = NBWIRE_BUFFER_LENGTH;
+ }
+
+ // perform blocking read into buffer
+ twi_cbreadFromDone = function;
+ twi_readFrom(address, rxBuffer, quantity);
+ //uint8_t read = twii_WaitForDone();
+
+ // set rx buffer iterator vars
+ //rxBufferIndex = 0;
+ //rxBufferLength = read;
+
+ rxBufferIndex = 0;
+ rxBufferLength = quantity; // this is a hack
+
+ return; //read;
+ }
+
+ uint8_t TwoWire::available(void) {
+ return rxBufferLength - rxBufferIndex;
+ }
+
+#endif
diff --git a/src/I2Cdev_rda.h b/src/I2Cdev_rda.h
new file mode 100644
index 0000000..56850f2
--- /dev/null
+++ b/src/I2Cdev_rda.h
@@ -0,0 +1,269 @@
+// I2Cdev library collection - Main I2C device class header file
+// Abstracts bit and byte I2C R/W functions into a convenient class
+// 6/9/2012 by Jeff Rowberg
+//
+// Changelog:
+// 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications
+// 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan)
+// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire
+// - add compiler warnings when using outdated or IDE or limited I2Cdev implementation
+// 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums)
+// 2011-10-03 - added automatic Arduino version detection for ease of use
+// 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications
+// 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x)
+// 2011-08-03 - added optional timeout parameter to read* methods to easily change from default
+// 2011-08-02 - added support for 16-bit registers
+// - fixed incorrect Doxygen comments on some methods
+// - added timeout value for read operations (thanks mem @ Arduino forums)
+// 2011-07-30 - changed read/write function structures to return success or byte counts
+// - made all methods static for multi-device memory savings
+// 2011-07-28 - initial release
+
+/* ============================================
+I2Cdev device library code is placed under the MIT license
+Copyright (c) 2013 Jeff Rowberg
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+===============================================
+*/
+
+#ifndef _I2CDEV_RDA_H_
+#define _I2CDEV_RDA_H_
+
+// -----------------------------------------------------------------------------
+// I2C interface implementation setting
+// -----------------------------------------------------------------------------
+#define I2CDEV_IMPLEMENTATION I2CDEV_ARDUINO_WIRE
+//#define I2CDEV_IMPLEMENTATION I2CDEV_BUILTIN_FASTWIRE
+
+// comment this out if you are using a non-optimal IDE/implementation setting
+// but want the compiler to shut up about it
+#define I2CDEV_IMPLEMENTATION_WARNINGS
+
+// -----------------------------------------------------------------------------
+// I2C interface implementation options
+// -----------------------------------------------------------------------------
+#define I2CDEV_ARDUINO_WIRE 1 // Wire object from Arduino
+#define I2CDEV_BUILTIN_NBWIRE 2 // Tweaked Wire object from Gene Knight's NBWire project
+ // ^^^ NBWire implementation is still buggy w/some interrupts!
+#define I2CDEV_BUILTIN_FASTWIRE 3 // FastWire object from Francesco Ferrara's project
+#define I2CDEV_I2CMASTER_LIBRARY 4 // I2C object from DSSCircuits I2C-Master Library at https://github.com/DSSCircuits/I2C-Master-Library
+
+// -----------------------------------------------------------------------------
+// Arduino-style "Serial.print" debug constant (uncomment to enable)
+// -----------------------------------------------------------------------------
+//#define I2CDEV_SERIAL_DEBUG
+
+#ifdef ARDUINO
+ #if ARDUINO < 100
+ #include "WProgram.h"
+ #else
+ #include "Arduino.h"
+ #endif
+ #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
+ #include
+ #endif
+ #if I2CDEV_IMPLEMENTATION == I2CDEV_I2CMASTER_LIBRARY
+ #include
+ #endif
+#endif
+
+// 1000ms default read timeout (modify with "I2Cdev::readTimeout = [ms];")
+#define I2CDEV_DEFAULT_READ_TIMEOUT 1000
+
+class I2Cdev {
+ public:
+ I2Cdev();
+
+ static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
+ static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
+ static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
+ static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
+ static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
+ static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
+ static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout);
+ static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout);
+
+ static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data);
+ static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data);
+ static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data);
+ static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data);
+ static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data);
+ static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data);
+ static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data);
+ static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data);
+
+ static uint16_t readTimeout;
+};
+
+#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
+ //////////////////////
+ // FastWire 0.24
+ // This is a library to help faster programs to read I2C devices.
+ // Copyright(C) 2012
+ // Francesco Ferrara
+ //////////////////////
+
+ /* Master */
+ #define TW_START 0x08
+ #define TW_REP_START 0x10
+
+ /* Master Transmitter */
+ #define TW_MT_SLA_ACK 0x18
+ #define TW_MT_SLA_NACK 0x20
+ #define TW_MT_DATA_ACK 0x28
+ #define TW_MT_DATA_NACK 0x30
+ #define TW_MT_ARB_LOST 0x38
+
+ /* Master Receiver */
+ #define TW_MR_ARB_LOST 0x38
+ #define TW_MR_SLA_ACK 0x40
+ #define TW_MR_SLA_NACK 0x48
+ #define TW_MR_DATA_ACK 0x50
+ #define TW_MR_DATA_NACK 0x58
+
+ #define TW_OK 0
+ #define TW_ERROR 1
+
+ class Fastwire {
+ private:
+ static boolean waitInt();
+
+ public:
+ static void setup(int khz, boolean pullup);
+ static byte beginTransmission(byte device);
+ static byte write(byte value);
+ static byte writeBuf(byte device, byte address, byte *data, byte num);
+ static byte readBuf(byte device, byte address, byte *data, byte num);
+ static void reset();
+ static byte stop();
+ };
+#endif
+
+#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE
+ // NBWire implementation based heavily on code by Gene Knight
+ // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html
+ // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html
+
+ #define NBWIRE_BUFFER_LENGTH 32
+
+ class TwoWire {
+ private:
+ static uint8_t rxBuffer[];
+ static uint8_t rxBufferIndex;
+ static uint8_t rxBufferLength;
+
+ static uint8_t txAddress;
+ static uint8_t txBuffer[];
+ static uint8_t txBufferIndex;
+ static uint8_t txBufferLength;
+
+ // static uint8_t transmitting;
+ static void (*user_onRequest)(void);
+ static void (*user_onReceive)(int);
+ static void onRequestService(void);
+ static void onReceiveService(uint8_t*, int);
+
+ public:
+ TwoWire();
+ void begin();
+ void begin(uint8_t);
+ void begin(int);
+ void beginTransmission(uint8_t);
+ //void beginTransmission(int);
+ uint8_t endTransmission(uint16_t timeout=0);
+ void nbendTransmission(void (*function)(int)) ;
+ uint8_t requestFrom(uint8_t, int, uint16_t timeout=0);
+ //uint8_t requestFrom(int, int);
+ void nbrequestFrom(uint8_t, int, void (*function)(int));
+ void send(uint8_t);
+ void send(uint8_t*, uint8_t);
+ //void send(int);
+ void send(char*);
+ uint8_t available(void);
+ uint8_t receive(void);
+ void onReceive(void (*)(int));
+ void onRequest(void (*)(void));
+ };
+
+ #define TWI_READY 0
+ #define TWI_MRX 1
+ #define TWI_MTX 2
+ #define TWI_SRX 3
+ #define TWI_STX 4
+
+ #define TW_WRITE 0
+ #define TW_READ 1
+
+ #define TW_MT_SLA_NACK 0x20
+ #define TW_MT_DATA_NACK 0x30
+
+ #define CPU_FREQ 16000000L
+ #define TWI_FREQ 100000L
+ #define TWI_BUFFER_LENGTH 32
+
+ /* TWI Status is in TWSR, in the top 5 bits: TWS7 - TWS3 */
+
+ #define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3))
+ #define TW_STATUS (TWSR & TW_STATUS_MASK)
+ #define TW_START 0x08
+ #define TW_REP_START 0x10
+ #define TW_MT_SLA_ACK 0x18
+ #define TW_MT_SLA_NACK 0x20
+ #define TW_MT_DATA_ACK 0x28
+ #define TW_MT_DATA_NACK 0x30
+ #define TW_MT_ARB_LOST 0x38
+ #define TW_MR_ARB_LOST 0x38
+ #define TW_MR_SLA_ACK 0x40
+ #define TW_MR_SLA_NACK 0x48
+ #define TW_MR_DATA_ACK 0x50
+ #define TW_MR_DATA_NACK 0x58
+ #define TW_ST_SLA_ACK 0xA8
+ #define TW_ST_ARB_LOST_SLA_ACK 0xB0
+ #define TW_ST_DATA_ACK 0xB8
+ #define TW_ST_DATA_NACK 0xC0
+ #define TW_ST_LAST_DATA 0xC8
+ #define TW_SR_SLA_ACK 0x60
+ #define TW_SR_ARB_LOST_SLA_ACK 0x68
+ #define TW_SR_GCALL_ACK 0x70
+ #define TW_SR_ARB_LOST_GCALL_ACK 0x78
+ #define TW_SR_DATA_ACK 0x80
+ #define TW_SR_DATA_NACK 0x88
+ #define TW_SR_GCALL_DATA_ACK 0x90
+ #define TW_SR_GCALL_DATA_NACK 0x98
+ #define TW_SR_STOP 0xA0
+ #define TW_NO_INFO 0xF8
+ #define TW_BUS_ERROR 0x00
+
+ //#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
+ //#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))
+
+ #ifndef sbi // set bit
+ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+ #endif // sbi
+
+ #ifndef cbi // clear bit
+ #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+ #endif // cbi
+
+ extern TwoWire Wire;
+
+#endif // I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE
+
+#endif /* _I2CDEV_RDA_H_ */