
https://youtu.be/99cUIxc72h0
Dependencies: BLE_API mbed nRF51822
main.cpp@0:24c8585f0f35, 2017-07-14 (annotated)
- Committer:
- matsujirushi
- Date:
- Fri Jul 14 10:35:54 2017 +0000
- Revision:
- 0:24c8585f0f35
1st commit.
Who changed what in which revision?
User | Revision | Line number | New 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 | } |