Keypad

Dependencies:   BLE_API mbed nRF51822

Fork of EmtpyProgram by Cataract Gemuese

main.cpp

Committer:
Cataract
Date:
2016-07-12
Revision:
1:115afdfbaa84
Parent:
0:4817f7301801
Child:
2:343f39defab2

File content as of revision 1:115afdfbaa84:

#include "mbed.h"
#include "ble/BLE.h"
#include "ble/UUID.h"
#include "ble/GattAttribute.h"
#include "ble/GattService.h"

DigitalOut alivenessLED(LED1, 0);
DigitalOut alivenessLED2(LED2, 1);
DigitalOut alivenessLED3(LED3, 1);
DigitalOut alivenessLED4(LED4, 1);

Ticker ticker;

const static char     DEVICE_NAME[]        = "KeyOpener3k";
static const char * uuid16_list[] = {"9085495d-f273-443d-9e37-e27c9194f63b"};

Serial pc(USBTX, USBRX);

SPI device(P0_14,P0_13,P0_15);
DigitalOut cs(P0_12);

char * message;
char * cpy = (char*) malloc(21);

void sendToken()
{
    pc.printf("Token");
    alivenessLED4 = !alivenessLED4;
    
    //init SPI
    cs = 1;
    device.format(8,3);
    device.frequency(2000000);
    
    int len = strlen(message);
    
    // Write the length of the message
    cs = 0;
    device.write( *((char*) (&len)) );
    device.write( *((char*) (&len)+1) );
    device.write( *((char*) (&len)+2) );
    device.write( *((char*) (&len)+3) );
    cs = 1;
    
    // Write the message
    for(int i=0;i<len;i++){
        cs = 0;
        device.write(*(message+i));
        cs = 1;
    }
    
    // Free Memory
    free(message);

    // Reset board to unblock the BLE-connection
    NVIC_SystemReset();
}

uint32_t countdata = 0; // Number of 20-byte blocks to be written.


// Callback for the BLE connection
void onDataWrittenCallback(const GattWriteCallbackParams* params) 
{
    pc.printf("read");
    alivenessLED3 = !alivenessLED3;
    // if countdata == 0 the data will be interpretated as the Number of 20-byte blocks to be written.
    if (countdata == 0){
            
        pc.printf("%u\r\n",*(uint32_t *) params->data);
        
        countdata = *(uint32_t *) params->data;
        
        //Malloc the size of the data to be written. +1 for the 0x00 byte.
        message = (char*) malloc(sizeof(char)*20*countdata + 1);
    } else {
        
        //If countdata is set the data will be interpretated as a string and concatenated to the previously recieved message
        pc.printf("Data: %s\r\n %d",params->data,countdata);
        memcpy(cpy, params->data, 20);
        cpy[20] = '\0'; 
        strcat(message,cpy);
        countdata--;
        
        // if every block was send over BLE send the token via SPI to the other board.
        if (countdata == 0){
            sendToken();
        }
    }    
}

void periodicCallback(void)
{
    alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */
}

//Write the "reset" byte to the other board and reset
void resetCallback(void)
{
    cs = 0;
    device.write( 0x11 );
    cs = 1;
    NVIC_SystemReset();
}

void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
    // Start a timer for autoreset to "unblock" the board automaticly
    // after a bad connection
    ticker.attach(resetCallback,30);
    alivenessLED2 = !alivenessLED2;
    pc.printf("Connected!\r\n");  
}

UUID uuid = UUID("9085495d-f273-443d-9e37-e27c9194f63b");
UUID uuid_message = UUID("8085495d-f273-443d-9e37-e27c9194f63b");

//Buffer for the service
char data[21];

// Init a service with "uuid" and a "20 char" characteristic with "uuid_message"
void initService(BLE &ble)
{
    //Note: 20 bytes are the max. length for BLE
    WriteOnlyArrayGattCharacteristic<char, 20> messagecharacter = WriteOnlyArrayGattCharacteristic<char, 20>(uuid_message,data);
    
    GattCharacteristic * chars[] = {&messagecharacter};
    GattService service = GattService(uuid,chars,1);
    ble.gattServer().addService(service);
}

void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE &ble          = params->ble;
    ble_error_t error = params->error;
 
    if (error != BLE_ERROR_NONE) {
        return;
    }
    
    ble.gap().onConnection(connectionCallback);
    ble.gattServer().onDataWritten(onDataWrittenCallback);
    
    initService(ble);
    
    /* Setup advertising. */
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingInterval(1000); /* 1000ms */
    ble.gap().startAdvertising();
}

int main(void)
{   
    //Init BLE
    BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
    ble.init(bleInitComplete);
    
    while (ble.hasInitialized()  == false) { /* spin loop */ }
     
    ticker.attach(periodicCallback, 1); /* Blink LED every second */
    
    pc.printf("init\r\n");
    while (1) {
        ble.waitForEvent();
    }
}