https://youtu.be/99cUIxc72h0

Dependencies:   BLE_API mbed nRF51822

Revision:
0:24c8585f0f35
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jul 14 10:35:54 2017 +0000
@@ -0,0 +1,165 @@
+#include "mbed.h"
+#include "MicrobitHw.h"
+#include "BLE.h"
+#include "UARTService.h"
+#include "Firmata.h"
+
+#define DLM "\r\n"
+
+static const char DEVICE_NAME[] = "chibi:bit";
+
+static Serial pc(USBTX, USBRX);
+
+static BLEDevice  ble;
+static UARTService* uart;
+
+static bool LedDisplay[3][9];
+
+void BleConnectionCallback(const Gap::ConnectionCallbackParams_t* params)
+{
+    pc.printf("Connected."DLM);
+
+    Gap::ConnectionParams_t gap_conn_params;
+    gap_conn_params.minConnectionInterval        = 6;   // 7.5[msec.] / 1.25
+    gap_conn_params.maxConnectionInterval        = 6;   // 7.5[msec.] / 1.25
+    gap_conn_params.slaveLatency                 = 1;
+    gap_conn_params.connectionSupervisionTimeout = 500; // 5000[msec.] / 10
+
+    if (ble.updateConnectionParams(params->handle, &gap_conn_params) != BLE_ERROR_NONE) {
+        pc.printf("Failed to update connection paramter."DLM);
+    }
+}
+
+void BleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t* params)
+{
+    pc.printf("Disconnected."DLM);
+    ble.startAdvertising();
+}
+
+void BleTimeoutCallback(const Gap::TimeoutSource_t source)
+{
+    pc.printf("Timeout."DLM);
+    ble.startAdvertising();
+}
+
+void BleOnDataWritten(const GattWriteCallbackParams* params)
+{
+    if (uart == NULL || params->handle != uart->getTXCharacteristicHandle()) return;
+
+    uint8_t payload[40];
+    uint16_t len = params->len;
+    ble.readCharacteristicValue(uart->getTXCharacteristicHandle(), payload, &len);
+
+    // Display for rx data.
+    pc.printf("RX(%2d): ", params->len);
+    for (int i = 0; i < len; i++) {
+        pc.printf("%02x ", payload[i]);
+    }
+    pc.printf(DLM);
+
+    if (len == 3 && (payload[0] & 0xf0) == DIGITAL_MESSAGE)
+    {
+        int port = payload[0] & 0x0f;
+        uint8_t value = (payload[1] & 0x7f) | (payload[2] & 0x01) << 7;
+        pc.printf("DIGITAL_MESSAGE port=%d, value=%02x"DLM, port, value);
+        switch (port)
+        {
+        case 0:
+            LedDisplay[0][0] = value & 0x01 ? true : false;
+            LedDisplay[1][3] = value & 0x02 ? true : false;
+            LedDisplay[0][1] = value & 0x04 ? true : false;
+            LedDisplay[1][4] = value & 0x08 ? true : false;
+            LedDisplay[0][2] = value & 0x10 ? true : false;
+            LedDisplay[2][3] = value & 0x20 ? true : false;
+            LedDisplay[2][4] = value & 0x40 ? true : false;
+            LedDisplay[2][5] = value & 0x80 ? true : false;
+            break;
+        case 1:
+            LedDisplay[2][6] = value & 0x01 ? true : false;
+            LedDisplay[2][7] = value & 0x02 ? true : false;
+            LedDisplay[1][1] = value & 0x04 ? true : false;
+            LedDisplay[0][8] = value & 0x08 ? true : false;
+            LedDisplay[1][2] = value & 0x10 ? true : false;
+            LedDisplay[2][8] = value & 0x20 ? true : false;
+            LedDisplay[1][0] = value & 0x40 ? true : false;
+            LedDisplay[0][7] = value & 0x80 ? true : false;
+            break;
+        case 2:
+            LedDisplay[0][6] = value & 0x01 ? true : false;
+            LedDisplay[0][5] = value & 0x02 ? true : false;
+            LedDisplay[0][4] = value & 0x04 ? true : false;
+            LedDisplay[0][3] = value & 0x08 ? true : false;
+            LedDisplay[2][2] = value & 0x10 ? true : false;
+            LedDisplay[1][6] = value & 0x20 ? true : false;
+            LedDisplay[2][0] = value & 0x40 ? true : false;
+            LedDisplay[1][5] = value & 0x80 ? true : false;
+            break;
+        case 3:
+            LedDisplay[2][1] = value & 0x01 ? true : false;
+            break;
+        default:
+            break;
+        }
+    }
+    else if (len == 3 && payload[0] == START_SYSEX && payload[1] == CAPABILITY_QUERY && payload[2] == END_SYSEX) {
+        pc.printf("CAPABILITY_QUERY"DLM);
+        const uint8_t buf[] = { START_SYSEX, CAPABILITY_RESPONSE, 1, 1, 0x7f, 1, 1, 0x7f, END_SYSEX, };
+        ble.updateCharacteristicValue(uart->getRXCharacteristicHandle(), buf, sizeof (buf));
+    }
+}
+
+void BleInitialize()
+{
+    ble.init();
+    ble.initializeSecurity();
+    ble.setDeviceName((const uint8_t*)DEVICE_NAME);
+
+    ble.onConnection(BleConnectionCallback);
+    ble.onDisconnection(BleDisconnectionCallback);
+    ble.onTimeout(BleTimeoutCallback);
+    ble.onDataWritten(BleOnDataWritten);
+
+    uart = new UARTService(ble);
+
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t*)DEVICE_NAME, sizeof (DEVICE_NAME) - 1);
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t*)UARTServiceUUID_reversed, sizeof (UARTServiceUUID_reversed));
+
+    ble.setAdvertisingInterval(160);
+}
+
+void flip()
+{
+    static int row = 0;
+    row++;
+    if (row >= 3) row = 0;
+
+    int value = (LedDisplay[row][0] ? 0x0001 : 0) |
+                (LedDisplay[row][1] ? 0x0002 : 0) |
+                (LedDisplay[row][2] ? 0x0004 : 0) |
+                (LedDisplay[row][3] ? 0x0008 : 0) |
+                (LedDisplay[row][4] ? 0x0010 : 0) |
+                (LedDisplay[row][5] ? 0x0020 : 0) |
+                (LedDisplay[row][6] ? 0x0040 : 0) |
+                (LedDisplay[row][7] ? 0x0080 : 0) |
+                (LedDisplay[row][8] ? 0x0100 : 0);
+                
+    MicrobitHwLedMatrix(row, value);
+}
+
+int main()
+{
+    MicrobitHwInitialize();
+    
+    pc.baud(115200);
+    pc.printf("Start a chibi:bit firmata."DLM);
+    
+    Ticker ticker;
+    ticker.attach_us(flip, 1000);
+
+    BleInitialize();
+    ble.startAdvertising();
+    for(;;) {
+        ble.waitForEvent();
+    }
+}