CAN to BLE translator - and back

Dependencies:   BLE_API CANnucleo X_NUCLEO_IDB0XA1 mbed

main.cpp

Committer:
filippomontano
Date:
2016-04-08
Revision:
5:9f30eba41c77
Parent:
4:8c2cd88d2545
Child:
6:f85bc6e59111

File content as of revision 5:9f30eba41c77:

#include "mbed.h"
#include "ble/BLE.h"
#include "CAN.h"

#define TARGET_NUCLEO_F072RB 1
#define   LED_PIN   PA_5

#define BLE_GATT_CHAR_PROPERTIES_NOTIFY 0x10

//void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params);
void writeCharCallback(const GattWriteCallbackParams  *params);
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params);
void onBleInitError(BLE &ble, ble_error_t error);
void initBLE(void);

void periodicCallback(void);
static volatile bool  triggerSensorPolling = false;


DigitalOut      led(LED_PIN),CAN_show(PC_12);


const static char     DEVICE_NAME[]        = "STNucleo - RGM - FM";
static const uint16_t uuid16_list[]        = {0xFFFF};

//const unsigned int RX_ID = 0x10;
//const unsigned int TX_ID = 0x11;

char shareddata[64][8]= { };
Ticker ticker;

Timer           timerA; //questo contatoro serve solo per dire: appena è passato un po' di tempo -> esegui

BLE ble;

uint16_t customServiceUUID  = 0xA000; // service UUID
uint16_t readCharUUID       = 0xA001; // read characteristic UUID
uint16_t writeCharUUID      = 0xA002; // write characteristic UUID

static uint8_t readValue[128] = {0};

//static uint8_t readValue[6]="HELLO";


ReadOnlyArrayGattCharacteristic<uint8_t,  sizeof(readValue)> readChar(readCharUUID, readValue, BLE_GATT_CHAR_PROPERTIES_NOTIFY , NULL,0); //aggiunto il BLE_GATT_CHAR_PROPERTIES_NOTIFY => appena arriva lo rimanda

static uint8_t writeValue[128] = {0};
WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue);

GattCharacteristic *characteristics[] = {&readChar, &writeChar};
GattService         customService(customServiceUUID, characteristics,  sizeof(characteristics) / sizeof(GattCharacteristic *));
uint8_t retry=1;
uint8_t readdata[20]= {};
char symbol=' ';
volatile bool   CANmsgAvailable = false;
volatile bool   BLExmit = false;
float stopTimer=2.0;
uint8_t j=0,k=1;
    
int main()
{
    // printf("\r\nBoard started\r\n");
    led = 1;       // turn LED on
     BLE::Instance().init(bleInitComplete);
     /*
     while (true) {
        // check for trigger from periodicCallback()
        if (triggerSensorPolling && ble.getGapState().connected) {
            triggerSensorPolling = false;

            // Do blocking calls or whatever is necessary for sensor polling.
            // In our case, we simply update the HRM measurement.

        } else {
            ble.waitForEvent(); // low power wait for event
        }
    }*/
     
  
    timerA.start();
  //  can.attach(&onMsgReceived, CAN::RxIrq);     // attach 'CAN receive-complete' interrupt handler

    while(true) {
        //  if(ble.getGapState().connected) {
        if(triggerSensorPolling && ble.getGapState().connected)
        {
               triggerSensorPolling=false;
           //    printf("^");
        }
        else { 
         // printf("v");
           ble.waitForEvent();
        }
        
        if(ble.gap().getState().connected) {
            stopTimer=0.2;
            symbol='!';
        } else {
            stopTimer=3;
          //  ble.waitForEvent();
            symbol='.';
        }

        if(timerA.read()>=stopTimer) {
            //   BLExmit=ble.getGapState().connected;
            BLExmit=ble.gap().getState().connected;
            timerA.stop();
            timerA.reset();
            led=!led.read();
            printf("%c\r\n",symbol);
            timerA.start();

        }
    
        if(BLExmit) {
            BLExmit=false;
            retry++;
            if(retry==0xff) ble.gap().startAdvertising();
            printf ("%#x  ",retry);
            printf("@");
            k++;
            if(k>1)
                k=1;
            readValue[0]=k;
            for(int i=1; i<8; i++) {
                readValue[i]=shareddata[k][i];
            }
            for(int i=0; i<8; i++) {
                printf ("%x",readValue[i]);
            }
            ble.updateCharacteristicValue(readChar.getValueHandle(), readValue,9);
        }
    }
}

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    (void)params;
    printf("\r\nTarget loss... wait for reconnection \r\n");

    BLE::Instance().gap().startAdvertising(); // restart advertising
}
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE&        ble   = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        onBleInitError(ble, error);
        return;
    }

    if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
        return;
    }

    ble.gap().onDisconnection(disconnectionCallback);

    /* Setup primary service. */

    /* Setup advertising. */
    printf("Setup of Advertising\r\n");
    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();
    ble.onDataWritten(writeCharCallback);
    ble.addService(customService);
    ticker.detach();
    ticker.attach(periodicCallback, 1); // blink LED every second

    printf("Starting Loop\r\n");
  
}
void onBleInitError(BLE &ble, ble_error_t error)
{
    (void)ble;
    (void)error;
    printf(" ### BLE init error ###\r\n");


    /* Initialization error handling should go here */
}
void periodicCallback(void)
{
    led = !led; /* Do blinky on LED1 while we're waiting for BLE events */
    /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
     * heavy-weight sensor polling from the main thread. */
    if(!ble.getGapState().connected) {
        printf("? ");
        ticker.attach(periodicCallback, 1); // blink LED every 5 second
    } else
        ticker.attach(periodicCallback, 0.1); // blink LED every second

    triggerSensorPolling = true;
}
void writeCharCallback(const GattWriteCallbackParams  *params)
{

    uint8_t j=0;

    // check to see what characteristic was written, by handle
 /*   if(params->handle  == writeChar.getValueHandle()) {
        BLESlot2CANId(params->data[0]);
        printf("\n\r Data received: length = %d, data = ",params->len);
        if(canRdPointer != j && canRdPointer != j+1) {
            bleWrPointerA=j;
            bleWrPointerB=j+1;
            for(int x=0; x < 9; x++) {
                printf("%c",params->data[x]);
                shareddata[j][x]=params->data[x];
            }
            for(int x=9; x < 18; x++) {
                printf("%c",params->data[x]);
                shareddata[j+1][x-9]=params->data[x];
            }
            bleWrPointerA=255;
            bleWrPointerB=255;
        }
    }*/
}