https://youtu.be/99cUIxc72h0

Dependencies:   BLE_API mbed nRF51822

Committer:
matsujirushi
Date:
Fri Jul 14 10:35:54 2017 +0000
Revision:
0:24c8585f0f35
1st commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
matsujirushi 0:24c8585f0f35 1 #include "mbed.h"
matsujirushi 0:24c8585f0f35 2 #include "MicrobitHw.h"
matsujirushi 0:24c8585f0f35 3 #include "BLE.h"
matsujirushi 0:24c8585f0f35 4 #include "UARTService.h"
matsujirushi 0:24c8585f0f35 5 #include "Firmata.h"
matsujirushi 0:24c8585f0f35 6
matsujirushi 0:24c8585f0f35 7 #define DLM "\r\n"
matsujirushi 0:24c8585f0f35 8
matsujirushi 0:24c8585f0f35 9 static const char DEVICE_NAME[] = "chibi:bit";
matsujirushi 0:24c8585f0f35 10
matsujirushi 0:24c8585f0f35 11 static Serial pc(USBTX, USBRX);
matsujirushi 0:24c8585f0f35 12
matsujirushi 0:24c8585f0f35 13 static BLEDevice ble;
matsujirushi 0:24c8585f0f35 14 static UARTService* uart;
matsujirushi 0:24c8585f0f35 15
matsujirushi 0:24c8585f0f35 16 static bool LedDisplay[3][9];
matsujirushi 0:24c8585f0f35 17
matsujirushi 0:24c8585f0f35 18 void BleConnectionCallback(const Gap::ConnectionCallbackParams_t* params)
matsujirushi 0:24c8585f0f35 19 {
matsujirushi 0:24c8585f0f35 20 pc.printf("Connected."DLM);
matsujirushi 0:24c8585f0f35 21
matsujirushi 0:24c8585f0f35 22 Gap::ConnectionParams_t gap_conn_params;
matsujirushi 0:24c8585f0f35 23 gap_conn_params.minConnectionInterval = 6; // 7.5[msec.] / 1.25
matsujirushi 0:24c8585f0f35 24 gap_conn_params.maxConnectionInterval = 6; // 7.5[msec.] / 1.25
matsujirushi 0:24c8585f0f35 25 gap_conn_params.slaveLatency = 1;
matsujirushi 0:24c8585f0f35 26 gap_conn_params.connectionSupervisionTimeout = 500; // 5000[msec.] / 10
matsujirushi 0:24c8585f0f35 27
matsujirushi 0:24c8585f0f35 28 if (ble.updateConnectionParams(params->handle, &gap_conn_params) != BLE_ERROR_NONE) {
matsujirushi 0:24c8585f0f35 29 pc.printf("Failed to update connection paramter."DLM);
matsujirushi 0:24c8585f0f35 30 }
matsujirushi 0:24c8585f0f35 31 }
matsujirushi 0:24c8585f0f35 32
matsujirushi 0:24c8585f0f35 33 void BleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t* params)
matsujirushi 0:24c8585f0f35 34 {
matsujirushi 0:24c8585f0f35 35 pc.printf("Disconnected."DLM);
matsujirushi 0:24c8585f0f35 36 ble.startAdvertising();
matsujirushi 0:24c8585f0f35 37 }
matsujirushi 0:24c8585f0f35 38
matsujirushi 0:24c8585f0f35 39 void BleTimeoutCallback(const Gap::TimeoutSource_t source)
matsujirushi 0:24c8585f0f35 40 {
matsujirushi 0:24c8585f0f35 41 pc.printf("Timeout."DLM);
matsujirushi 0:24c8585f0f35 42 ble.startAdvertising();
matsujirushi 0:24c8585f0f35 43 }
matsujirushi 0:24c8585f0f35 44
matsujirushi 0:24c8585f0f35 45 void BleOnDataWritten(const GattWriteCallbackParams* params)
matsujirushi 0:24c8585f0f35 46 {
matsujirushi 0:24c8585f0f35 47 if (uart == NULL || params->handle != uart->getTXCharacteristicHandle()) return;
matsujirushi 0:24c8585f0f35 48
matsujirushi 0:24c8585f0f35 49 uint8_t payload[40];
matsujirushi 0:24c8585f0f35 50 uint16_t len = params->len;
matsujirushi 0:24c8585f0f35 51 ble.readCharacteristicValue(uart->getTXCharacteristicHandle(), payload, &len);
matsujirushi 0:24c8585f0f35 52
matsujirushi 0:24c8585f0f35 53 // Display for rx data.
matsujirushi 0:24c8585f0f35 54 pc.printf("RX(%2d): ", params->len);
matsujirushi 0:24c8585f0f35 55 for (int i = 0; i < len; i++) {
matsujirushi 0:24c8585f0f35 56 pc.printf("%02x ", payload[i]);
matsujirushi 0:24c8585f0f35 57 }
matsujirushi 0:24c8585f0f35 58 pc.printf(DLM);
matsujirushi 0:24c8585f0f35 59
matsujirushi 0:24c8585f0f35 60 if (len == 3 && (payload[0] & 0xf0) == DIGITAL_MESSAGE)
matsujirushi 0:24c8585f0f35 61 {
matsujirushi 0:24c8585f0f35 62 int port = payload[0] & 0x0f;
matsujirushi 0:24c8585f0f35 63 uint8_t value = (payload[1] & 0x7f) | (payload[2] & 0x01) << 7;
matsujirushi 0:24c8585f0f35 64 pc.printf("DIGITAL_MESSAGE port=%d, value=%02x"DLM, port, value);
matsujirushi 0:24c8585f0f35 65 switch (port)
matsujirushi 0:24c8585f0f35 66 {
matsujirushi 0:24c8585f0f35 67 case 0:
matsujirushi 0:24c8585f0f35 68 LedDisplay[0][0] = value & 0x01 ? true : false;
matsujirushi 0:24c8585f0f35 69 LedDisplay[1][3] = value & 0x02 ? true : false;
matsujirushi 0:24c8585f0f35 70 LedDisplay[0][1] = value & 0x04 ? true : false;
matsujirushi 0:24c8585f0f35 71 LedDisplay[1][4] = value & 0x08 ? true : false;
matsujirushi 0:24c8585f0f35 72 LedDisplay[0][2] = value & 0x10 ? true : false;
matsujirushi 0:24c8585f0f35 73 LedDisplay[2][3] = value & 0x20 ? true : false;
matsujirushi 0:24c8585f0f35 74 LedDisplay[2][4] = value & 0x40 ? true : false;
matsujirushi 0:24c8585f0f35 75 LedDisplay[2][5] = value & 0x80 ? true : false;
matsujirushi 0:24c8585f0f35 76 break;
matsujirushi 0:24c8585f0f35 77 case 1:
matsujirushi 0:24c8585f0f35 78 LedDisplay[2][6] = value & 0x01 ? true : false;
matsujirushi 0:24c8585f0f35 79 LedDisplay[2][7] = value & 0x02 ? true : false;
matsujirushi 0:24c8585f0f35 80 LedDisplay[1][1] = value & 0x04 ? true : false;
matsujirushi 0:24c8585f0f35 81 LedDisplay[0][8] = value & 0x08 ? true : false;
matsujirushi 0:24c8585f0f35 82 LedDisplay[1][2] = value & 0x10 ? true : false;
matsujirushi 0:24c8585f0f35 83 LedDisplay[2][8] = value & 0x20 ? true : false;
matsujirushi 0:24c8585f0f35 84 LedDisplay[1][0] = value & 0x40 ? true : false;
matsujirushi 0:24c8585f0f35 85 LedDisplay[0][7] = value & 0x80 ? true : false;
matsujirushi 0:24c8585f0f35 86 break;
matsujirushi 0:24c8585f0f35 87 case 2:
matsujirushi 0:24c8585f0f35 88 LedDisplay[0][6] = value & 0x01 ? true : false;
matsujirushi 0:24c8585f0f35 89 LedDisplay[0][5] = value & 0x02 ? true : false;
matsujirushi 0:24c8585f0f35 90 LedDisplay[0][4] = value & 0x04 ? true : false;
matsujirushi 0:24c8585f0f35 91 LedDisplay[0][3] = value & 0x08 ? true : false;
matsujirushi 0:24c8585f0f35 92 LedDisplay[2][2] = value & 0x10 ? true : false;
matsujirushi 0:24c8585f0f35 93 LedDisplay[1][6] = value & 0x20 ? true : false;
matsujirushi 0:24c8585f0f35 94 LedDisplay[2][0] = value & 0x40 ? true : false;
matsujirushi 0:24c8585f0f35 95 LedDisplay[1][5] = value & 0x80 ? true : false;
matsujirushi 0:24c8585f0f35 96 break;
matsujirushi 0:24c8585f0f35 97 case 3:
matsujirushi 0:24c8585f0f35 98 LedDisplay[2][1] = value & 0x01 ? true : false;
matsujirushi 0:24c8585f0f35 99 break;
matsujirushi 0:24c8585f0f35 100 default:
matsujirushi 0:24c8585f0f35 101 break;
matsujirushi 0:24c8585f0f35 102 }
matsujirushi 0:24c8585f0f35 103 }
matsujirushi 0:24c8585f0f35 104 else if (len == 3 && payload[0] == START_SYSEX && payload[1] == CAPABILITY_QUERY && payload[2] == END_SYSEX) {
matsujirushi 0:24c8585f0f35 105 pc.printf("CAPABILITY_QUERY"DLM);
matsujirushi 0:24c8585f0f35 106 const uint8_t buf[] = { START_SYSEX, CAPABILITY_RESPONSE, 1, 1, 0x7f, 1, 1, 0x7f, END_SYSEX, };
matsujirushi 0:24c8585f0f35 107 ble.updateCharacteristicValue(uart->getRXCharacteristicHandle(), buf, sizeof (buf));
matsujirushi 0:24c8585f0f35 108 }
matsujirushi 0:24c8585f0f35 109 }
matsujirushi 0:24c8585f0f35 110
matsujirushi 0:24c8585f0f35 111 void BleInitialize()
matsujirushi 0:24c8585f0f35 112 {
matsujirushi 0:24c8585f0f35 113 ble.init();
matsujirushi 0:24c8585f0f35 114 ble.initializeSecurity();
matsujirushi 0:24c8585f0f35 115 ble.setDeviceName((const uint8_t*)DEVICE_NAME);
matsujirushi 0:24c8585f0f35 116
matsujirushi 0:24c8585f0f35 117 ble.onConnection(BleConnectionCallback);
matsujirushi 0:24c8585f0f35 118 ble.onDisconnection(BleDisconnectionCallback);
matsujirushi 0:24c8585f0f35 119 ble.onTimeout(BleTimeoutCallback);
matsujirushi 0:24c8585f0f35 120 ble.onDataWritten(BleOnDataWritten);
matsujirushi 0:24c8585f0f35 121
matsujirushi 0:24c8585f0f35 122 uart = new UARTService(ble);
matsujirushi 0:24c8585f0f35 123
matsujirushi 0:24c8585f0f35 124 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
matsujirushi 0:24c8585f0f35 125 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t*)DEVICE_NAME, sizeof (DEVICE_NAME) - 1);
matsujirushi 0:24c8585f0f35 126 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t*)UARTServiceUUID_reversed, sizeof (UARTServiceUUID_reversed));
matsujirushi 0:24c8585f0f35 127
matsujirushi 0:24c8585f0f35 128 ble.setAdvertisingInterval(160);
matsujirushi 0:24c8585f0f35 129 }
matsujirushi 0:24c8585f0f35 130
matsujirushi 0:24c8585f0f35 131 void flip()
matsujirushi 0:24c8585f0f35 132 {
matsujirushi 0:24c8585f0f35 133 static int row = 0;
matsujirushi 0:24c8585f0f35 134 row++;
matsujirushi 0:24c8585f0f35 135 if (row >= 3) row = 0;
matsujirushi 0:24c8585f0f35 136
matsujirushi 0:24c8585f0f35 137 int value = (LedDisplay[row][0] ? 0x0001 : 0) |
matsujirushi 0:24c8585f0f35 138 (LedDisplay[row][1] ? 0x0002 : 0) |
matsujirushi 0:24c8585f0f35 139 (LedDisplay[row][2] ? 0x0004 : 0) |
matsujirushi 0:24c8585f0f35 140 (LedDisplay[row][3] ? 0x0008 : 0) |
matsujirushi 0:24c8585f0f35 141 (LedDisplay[row][4] ? 0x0010 : 0) |
matsujirushi 0:24c8585f0f35 142 (LedDisplay[row][5] ? 0x0020 : 0) |
matsujirushi 0:24c8585f0f35 143 (LedDisplay[row][6] ? 0x0040 : 0) |
matsujirushi 0:24c8585f0f35 144 (LedDisplay[row][7] ? 0x0080 : 0) |
matsujirushi 0:24c8585f0f35 145 (LedDisplay[row][8] ? 0x0100 : 0);
matsujirushi 0:24c8585f0f35 146
matsujirushi 0:24c8585f0f35 147 MicrobitHwLedMatrix(row, value);
matsujirushi 0:24c8585f0f35 148 }
matsujirushi 0:24c8585f0f35 149
matsujirushi 0:24c8585f0f35 150 int main()
matsujirushi 0:24c8585f0f35 151 {
matsujirushi 0:24c8585f0f35 152 MicrobitHwInitialize();
matsujirushi 0:24c8585f0f35 153
matsujirushi 0:24c8585f0f35 154 pc.baud(115200);
matsujirushi 0:24c8585f0f35 155 pc.printf("Start a chibi:bit firmata."DLM);
matsujirushi 0:24c8585f0f35 156
matsujirushi 0:24c8585f0f35 157 Ticker ticker;
matsujirushi 0:24c8585f0f35 158 ticker.attach_us(flip, 1000);
matsujirushi 0:24c8585f0f35 159
matsujirushi 0:24c8585f0f35 160 BleInitialize();
matsujirushi 0:24c8585f0f35 161 ble.startAdvertising();
matsujirushi 0:24c8585f0f35 162 for(;;) {
matsujirushi 0:24c8585f0f35 163 ble.waitForEvent();
matsujirushi 0:24c8585f0f35 164 }
matsujirushi 0:24c8585f0f35 165 }