CAN to BLE translator - and back

Dependencies:   BLE_API CANnucleo X_NUCLEO_IDB0XA1 mbed

Committer:
filippomontano
Date:
Fri Apr 08 14:30:50 2016 +0000
Revision:
5:9f30eba41c77
Parent:
4:8c2cd88d2545
Child:
6:f85bc6e59111
ble senza can;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
filippomontano 0:345c72cbcd60 1 #include "mbed.h"
filippomontano 0:345c72cbcd60 2 #include "ble/BLE.h"
filippomontano 0:345c72cbcd60 3 #include "CAN.h"
filippomontano 0:345c72cbcd60 4
filippomontano 3:5bce2e8d2797 5 #define TARGET_NUCLEO_F072RB 1
filippomontano 0:345c72cbcd60 6 #define LED_PIN PA_5
filippomontano 0:345c72cbcd60 7
filippomontano 3:5bce2e8d2797 8 #define BLE_GATT_CHAR_PROPERTIES_NOTIFY 0x10
filippomontano 3:5bce2e8d2797 9
filippomontano 5:9f30eba41c77 10 //void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params);
filippomontano 3:5bce2e8d2797 11 void writeCharCallback(const GattWriteCallbackParams *params);
filippomontano 3:5bce2e8d2797 12 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params);
filippomontano 3:5bce2e8d2797 13 void onBleInitError(BLE &ble, ble_error_t error);
filippomontano 3:5bce2e8d2797 14 void initBLE(void);
filippomontano 0:345c72cbcd60 15
filippomontano 5:9f30eba41c77 16 void periodicCallback(void);
filippomontano 5:9f30eba41c77 17 static volatile bool triggerSensorPolling = false;
filippomontano 5:9f30eba41c77 18
filippomontano 0:345c72cbcd60 19
filippomontano 3:5bce2e8d2797 20 DigitalOut led(LED_PIN),CAN_show(PC_12);
filippomontano 3:5bce2e8d2797 21
filippomontano 3:5bce2e8d2797 22
filippomontano 3:5bce2e8d2797 23 const static char DEVICE_NAME[] = "STNucleo - RGM - FM";
filippomontano 3:5bce2e8d2797 24 static const uint16_t uuid16_list[] = {0xFFFF};
filippomontano 3:5bce2e8d2797 25
filippomontano 0:345c72cbcd60 26 //const unsigned int RX_ID = 0x10;
filippomontano 0:345c72cbcd60 27 //const unsigned int TX_ID = 0x11;
filippomontano 0:345c72cbcd60 28
filippomontano 0:345c72cbcd60 29 char shareddata[64][8]= { };
filippomontano 5:9f30eba41c77 30 Ticker ticker;
filippomontano 3:5bce2e8d2797 31
filippomontano 3:5bce2e8d2797 32 Timer timerA; //questo contatoro serve solo per dire: appena è passato un po' di tempo -> esegui
filippomontano 0:345c72cbcd60 33
filippomontano 3:5bce2e8d2797 34 BLE ble;
filippomontano 3:5bce2e8d2797 35
filippomontano 3:5bce2e8d2797 36 uint16_t customServiceUUID = 0xA000; // service UUID
filippomontano 3:5bce2e8d2797 37 uint16_t readCharUUID = 0xA001; // read characteristic UUID
filippomontano 3:5bce2e8d2797 38 uint16_t writeCharUUID = 0xA002; // write characteristic UUID
filippomontano 3:5bce2e8d2797 39
filippomontano 3:5bce2e8d2797 40 static uint8_t readValue[128] = {0};
filippomontano 3:5bce2e8d2797 41
filippomontano 3:5bce2e8d2797 42 //static uint8_t readValue[6]="HELLO";
filippomontano 3:5bce2e8d2797 43
filippomontano 3:5bce2e8d2797 44
filippomontano 3:5bce2e8d2797 45 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
filippomontano 3:5bce2e8d2797 46
filippomontano 3:5bce2e8d2797 47 static uint8_t writeValue[128] = {0};
filippomontano 3:5bce2e8d2797 48 WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue);
filippomontano 3:5bce2e8d2797 49
filippomontano 3:5bce2e8d2797 50 GattCharacteristic *characteristics[] = {&readChar, &writeChar};
filippomontano 3:5bce2e8d2797 51 GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
filippomontano 3:5bce2e8d2797 52 uint8_t retry=1;
filippomontano 3:5bce2e8d2797 53 uint8_t readdata[20]= {};
filippomontano 3:5bce2e8d2797 54 char symbol=' ';
filippomontano 0:345c72cbcd60 55 volatile bool CANmsgAvailable = false;
filippomontano 3:5bce2e8d2797 56 volatile bool BLExmit = false;
filippomontano 3:5bce2e8d2797 57 float stopTimer=2.0;
filippomontano 5:9f30eba41c77 58 uint8_t j=0,k=1;
filippomontano 5:9f30eba41c77 59
filippomontano 0:345c72cbcd60 60 int main()
filippomontano 0:345c72cbcd60 61 {
filippomontano 3:5bce2e8d2797 62 // printf("\r\nBoard started\r\n");
filippomontano 0:345c72cbcd60 63 led = 1; // turn LED on
filippomontano 5:9f30eba41c77 64 BLE::Instance().init(bleInitComplete);
filippomontano 5:9f30eba41c77 65 /*
filippomontano 5:9f30eba41c77 66 while (true) {
filippomontano 5:9f30eba41c77 67 // check for trigger from periodicCallback()
filippomontano 5:9f30eba41c77 68 if (triggerSensorPolling && ble.getGapState().connected) {
filippomontano 5:9f30eba41c77 69 triggerSensorPolling = false;
filippomontano 3:5bce2e8d2797 70
filippomontano 5:9f30eba41c77 71 // Do blocking calls or whatever is necessary for sensor polling.
filippomontano 5:9f30eba41c77 72 // In our case, we simply update the HRM measurement.
filippomontano 3:5bce2e8d2797 73
filippomontano 5:9f30eba41c77 74 } else {
filippomontano 5:9f30eba41c77 75 ble.waitForEvent(); // low power wait for event
filippomontano 5:9f30eba41c77 76 }
filippomontano 5:9f30eba41c77 77 }*/
filippomontano 5:9f30eba41c77 78
filippomontano 5:9f30eba41c77 79
filippomontano 0:345c72cbcd60 80 timerA.start();
filippomontano 5:9f30eba41c77 81 // can.attach(&onMsgReceived, CAN::RxIrq); // attach 'CAN receive-complete' interrupt handler
filippomontano 3:5bce2e8d2797 82
filippomontano 3:5bce2e8d2797 83 while(true) {
filippomontano 5:9f30eba41c77 84 // if(ble.getGapState().connected) {
filippomontano 5:9f30eba41c77 85 if(triggerSensorPolling && ble.getGapState().connected)
filippomontano 5:9f30eba41c77 86 {
filippomontano 5:9f30eba41c77 87 triggerSensorPolling=false;
filippomontano 5:9f30eba41c77 88 // printf("^");
filippomontano 5:9f30eba41c77 89 }
filippomontano 5:9f30eba41c77 90 else {
filippomontano 5:9f30eba41c77 91 // printf("v");
filippomontano 5:9f30eba41c77 92 ble.waitForEvent();
filippomontano 5:9f30eba41c77 93 }
filippomontano 5:9f30eba41c77 94
filippomontano 5:9f30eba41c77 95 if(ble.gap().getState().connected) {
filippomontano 3:5bce2e8d2797 96 stopTimer=0.2;
filippomontano 3:5bce2e8d2797 97 symbol='!';
filippomontano 3:5bce2e8d2797 98 } else {
filippomontano 3:5bce2e8d2797 99 stopTimer=3;
filippomontano 5:9f30eba41c77 100 // ble.waitForEvent();
filippomontano 3:5bce2e8d2797 101 symbol='.';
filippomontano 3:5bce2e8d2797 102 }
filippomontano 3:5bce2e8d2797 103
filippomontano 3:5bce2e8d2797 104 if(timerA.read()>=stopTimer) {
filippomontano 5:9f30eba41c77 105 // BLExmit=ble.getGapState().connected;
filippomontano 5:9f30eba41c77 106 BLExmit=ble.gap().getState().connected;
filippomontano 0:345c72cbcd60 107 timerA.stop();
filippomontano 0:345c72cbcd60 108 timerA.reset();
filippomontano 0:345c72cbcd60 109 led=!led.read();
filippomontano 3:5bce2e8d2797 110 printf("%c\r\n",symbol);
filippomontano 0:345c72cbcd60 111 timerA.start();
filippomontano 3:5bce2e8d2797 112
filippomontano 0:345c72cbcd60 113 }
filippomontano 5:9f30eba41c77 114
filippomontano 3:5bce2e8d2797 115 if(BLExmit) {
filippomontano 3:5bce2e8d2797 116 BLExmit=false;
filippomontano 3:5bce2e8d2797 117 retry++;
filippomontano 5:9f30eba41c77 118 if(retry==0xff) ble.gap().startAdvertising();
filippomontano 5:9f30eba41c77 119 printf ("%#x ",retry);
filippomontano 3:5bce2e8d2797 120 printf("@");
filippomontano 3:5bce2e8d2797 121 k++;
filippomontano 5:9f30eba41c77 122 if(k>1)
filippomontano 5:9f30eba41c77 123 k=1;
filippomontano 3:5bce2e8d2797 124 readValue[0]=k;
filippomontano 3:5bce2e8d2797 125 for(int i=1; i<8; i++) {
filippomontano 3:5bce2e8d2797 126 readValue[i]=shareddata[k][i];
filippomontano 0:345c72cbcd60 127 }
filippomontano 5:9f30eba41c77 128 for(int i=0; i<8; i++) {
filippomontano 5:9f30eba41c77 129 printf ("%x",readValue[i]);
filippomontano 5:9f30eba41c77 130 }
filippomontano 3:5bce2e8d2797 131 ble.updateCharacteristicValue(readChar.getValueHandle(), readValue,9);
filippomontano 0:345c72cbcd60 132 }
filippomontano 0:345c72cbcd60 133 }
filippomontano 0:345c72cbcd60 134 }
filippomontano 3:5bce2e8d2797 135
filippomontano 5:9f30eba41c77 136 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
filippomontano 5:9f30eba41c77 137 {
filippomontano 5:9f30eba41c77 138 (void)params;
filippomontano 5:9f30eba41c77 139 printf("\r\nTarget loss... wait for reconnection \r\n");
filippomontano 5:9f30eba41c77 140
filippomontano 5:9f30eba41c77 141 BLE::Instance().gap().startAdvertising(); // restart advertising
filippomontano 5:9f30eba41c77 142 }
filippomontano 3:5bce2e8d2797 143 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
filippomontano 0:345c72cbcd60 144 {
filippomontano 3:5bce2e8d2797 145 BLE& ble = params->ble;
filippomontano 3:5bce2e8d2797 146 ble_error_t error = params->error;
filippomontano 3:5bce2e8d2797 147
filippomontano 3:5bce2e8d2797 148 if (error != BLE_ERROR_NONE) {
filippomontano 3:5bce2e8d2797 149 onBleInitError(ble, error);
filippomontano 3:5bce2e8d2797 150 return;
filippomontano 3:5bce2e8d2797 151 }
filippomontano 3:5bce2e8d2797 152
filippomontano 3:5bce2e8d2797 153 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
filippomontano 3:5bce2e8d2797 154 return;
filippomontano 3:5bce2e8d2797 155 }
filippomontano 5:9f30eba41c77 156
filippomontano 3:5bce2e8d2797 157 ble.gap().onDisconnection(disconnectionCallback);
filippomontano 3:5bce2e8d2797 158
filippomontano 3:5bce2e8d2797 159 /* Setup primary service. */
filippomontano 3:5bce2e8d2797 160
filippomontano 3:5bce2e8d2797 161 /* Setup advertising. */
filippomontano 3:5bce2e8d2797 162 printf("Setup of Advertising\r\n");
filippomontano 3:5bce2e8d2797 163 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
filippomontano 3:5bce2e8d2797 164 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
filippomontano 3:5bce2e8d2797 165 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
filippomontano 3:5bce2e8d2797 166 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
filippomontano 3:5bce2e8d2797 167 ble.gap().setAdvertisingInterval(1000);// 1000ms
filippomontano 3:5bce2e8d2797 168 ble.gap().startAdvertising();
filippomontano 3:5bce2e8d2797 169 ble.onDataWritten(writeCharCallback);
filippomontano 3:5bce2e8d2797 170 ble.addService(customService);
filippomontano 5:9f30eba41c77 171 ticker.detach();
filippomontano 5:9f30eba41c77 172 ticker.attach(periodicCallback, 1); // blink LED every second
filippomontano 3:5bce2e8d2797 173
filippomontano 3:5bce2e8d2797 174 printf("Starting Loop\r\n");
filippomontano 5:9f30eba41c77 175
filippomontano 3:5bce2e8d2797 176 }
filippomontano 3:5bce2e8d2797 177 void onBleInitError(BLE &ble, ble_error_t error)
filippomontano 3:5bce2e8d2797 178 {
filippomontano 3:5bce2e8d2797 179 (void)ble;
filippomontano 3:5bce2e8d2797 180 (void)error;
filippomontano 3:5bce2e8d2797 181 printf(" ### BLE init error ###\r\n");
filippomontano 3:5bce2e8d2797 182
filippomontano 3:5bce2e8d2797 183
filippomontano 3:5bce2e8d2797 184 /* Initialization error handling should go here */
filippomontano 0:345c72cbcd60 185 }
filippomontano 5:9f30eba41c77 186 void periodicCallback(void)
filippomontano 0:345c72cbcd60 187 {
filippomontano 5:9f30eba41c77 188 led = !led; /* Do blinky on LED1 while we're waiting for BLE events */
filippomontano 5:9f30eba41c77 189 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
filippomontano 5:9f30eba41c77 190 * heavy-weight sensor polling from the main thread. */
filippomontano 5:9f30eba41c77 191 if(!ble.getGapState().connected) {
filippomontano 5:9f30eba41c77 192 printf("? ");
filippomontano 5:9f30eba41c77 193 ticker.attach(periodicCallback, 1); // blink LED every 5 second
filippomontano 5:9f30eba41c77 194 } else
filippomontano 5:9f30eba41c77 195 ticker.attach(periodicCallback, 0.1); // blink LED every second
filippomontano 5:9f30eba41c77 196
filippomontano 5:9f30eba41c77 197 triggerSensorPolling = true;
filippomontano 0:345c72cbcd60 198 }
filippomontano 3:5bce2e8d2797 199 void writeCharCallback(const GattWriteCallbackParams *params)
filippomontano 3:5bce2e8d2797 200 {
filippomontano 3:5bce2e8d2797 201
filippomontano 3:5bce2e8d2797 202 uint8_t j=0;
filippomontano 3:5bce2e8d2797 203
filippomontano 3:5bce2e8d2797 204 // check to see what characteristic was written, by handle
filippomontano 5:9f30eba41c77 205 /* if(params->handle == writeChar.getValueHandle()) {
filippomontano 3:5bce2e8d2797 206 BLESlot2CANId(params->data[0]);
filippomontano 3:5bce2e8d2797 207 printf("\n\r Data received: length = %d, data = ",params->len);
filippomontano 3:5bce2e8d2797 208 if(canRdPointer != j && canRdPointer != j+1) {
filippomontano 3:5bce2e8d2797 209 bleWrPointerA=j;
filippomontano 3:5bce2e8d2797 210 bleWrPointerB=j+1;
filippomontano 3:5bce2e8d2797 211 for(int x=0; x < 9; x++) {
filippomontano 3:5bce2e8d2797 212 printf("%c",params->data[x]);
filippomontano 3:5bce2e8d2797 213 shareddata[j][x]=params->data[x];
filippomontano 3:5bce2e8d2797 214 }
filippomontano 3:5bce2e8d2797 215 for(int x=9; x < 18; x++) {
filippomontano 3:5bce2e8d2797 216 printf("%c",params->data[x]);
filippomontano 3:5bce2e8d2797 217 shareddata[j+1][x-9]=params->data[x];
filippomontano 3:5bce2e8d2797 218 }
filippomontano 3:5bce2e8d2797 219 bleWrPointerA=255;
filippomontano 3:5bce2e8d2797 220 bleWrPointerB=255;
filippomontano 3:5bce2e8d2797 221 }
filippomontano 5:9f30eba41c77 222 }*/
filippomontano 3:5bce2e8d2797 223 }