https://youtu.be/99cUIxc72h0

Dependencies:   BLE_API mbed nRF51822

main.cpp

Committer:
matsujirushi
Date:
2017-07-14
Revision:
0:24c8585f0f35

File content as of revision 0:24c8585f0f35:

#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();
    }
}