CAN to BLE translator - and back

Dependencies:   BLE_API CANnucleo X_NUCLEO_IDB0XA1 mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "ble/BLE.h"
00003 #include "CAN.h"
00004 
00005 #define TARGET_NUCLEO_F072RB 1
00006 #define   LED_PIN   PA_5
00007 
00008 #define BLE_GATT_CHAR_PROPERTIES_NOTIFY 0x10
00009 
00010 uint8_t CANId2BLESlot(unsigned int   id);
00011 unsigned int BLESlot2CANId(uint8_t   id);
00012 void onMsgReceived(void);
00013 
00014 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params);
00015 void writeCharCallback(const GattWriteCallbackParams  *params);
00016 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params);
00017 void onBleInitError(BLE &ble, ble_error_t error);
00018 
00019 void periodicCallback(void);
00020 
00021 
00022 void initMEM(void);
00023 void dumpMEM(void);
00024 
00025 CANMessage      rxMsg;
00026 CANMessage      txMsg;
00027 
00028 BLE ble;
00029 
00030 char shareddata[64][8]= { };
00031 
00032 DigitalOut      led(LED_PIN),CAN_show(PC_12);
00033 DigitalIn button(PC_13);
00034 
00035 const uint8_t firstBleRdPointer=1;
00036 const uint8_t lastBleRdPointer=14;
00037 const uint8_t firstCanRdPointer=57;
00038 const uint8_t lastCanRdPointer=63;
00039 
00040 const static char     DEVICE_NAME[]        = "STNucleo - RGM - FM";
00041 const static uint16_t uuid16_list[]        = {0xFFFF};
00042 
00043 static volatile bool  triggerSensorPolling = false;
00044 
00045 uint8_t canWrPointer= 255;
00046 uint8_t canRdPointer= 255;
00047 uint8_t bleWrPointerA= 255;
00048 uint8_t bleRdPointerA= 255;
00049 uint8_t bleWrPointerB= 255;
00050 uint8_t bleRdPointerB= 255;
00051 
00052 uint8_t canRdLastPointer= 255; // puntatore per sapere che cosa ho mandato per ultimo. a runtime devo andare a modificarlo per sapere al ciclo dopo cosa ho già mandato
00053 uint8_t bleRdLastPointer= 255; // puntatore per sapere che cosa ho mandato per ultimo. a runtime devo andare a modificarlo per sapere al ciclo dopo cosa ho già mandato
00054 
00055 Ticker ticker;      //synchronous counter - IRQ enabled
00056 Timer           timerA; //unsynchronous counter  - no IRQ 
00057 
00058 //CAN             can(PB_8, PB_9);  // alternatives for CAN Rx pin name, CAN Tx pin name
00059 
00060 uint16_t customServiceUUID  = 0xA000; // service UUID
00061 uint16_t readCharUUID       = 0xA001; // read characteristic UUID
00062 uint16_t writeCharUUID      = 0xA002; // write characteristic UUID
00063 
00064 static uint8_t readValue[128] = {0};
00065 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
00066 
00067 static uint8_t writeValue[128] = {0};
00068 WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue);
00069 
00070 GattCharacteristic *characteristics[] = {&readChar, &writeChar};
00071 GattService         customService(customServiceUUID, characteristics,  sizeof(characteristics) / sizeof(GattCharacteristic *));
00072 
00073 uint8_t retry=1;
00074 char symbol=' ';
00075 
00076 volatile bool   CANmsgAvailable = false;
00077 volatile bool   BLExmit = false;
00078 bool signal=true;
00079 
00080 float stopTimer=2.0;
00081 
00082 uint8_t readdata[20]= {}; //BLE data
00083 char kantMsg[8]= {0};   //CAN data
00084 
00085 int main()
00086 {
00087     uint8_t j=0,k=0;
00088     int mcan=0;
00089     initMEM();
00090     printf("\r\nBoard started\r\n");
00091     led = 1;       // turn LED on
00092     bleRdLastPointer=lastBleRdPointer;
00093     canRdPointer=lastCanRdPointer;
00094     BLE::Instance().init(bleInitComplete);
00095     CAN             can(PA_11, PA_12);  // CAN Rx pin name, CAN Tx pin name
00096 
00097     //canRdLastPointer=lastCanRdPointer;
00098     can.frequency(500000);                     // set bit rate to 500kbps as S018
00099     printf("CAN started at 500kbps\r\n");
00100     timerA.start();
00101     can.attach(&onMsgReceived, CAN::RxIrq);     // attach 'CAN receive-complete' interrupt handler
00102     while(true) {
00103         //  if(ble.getGapState().connected) {
00104         if(triggerSensorPolling && ble.getGapState().connected) {
00105             triggerSensorPolling=false;
00106         } else {
00107             ble.waitForEvent();
00108         }
00109 
00110         if(ble.gap().getState().connected) {
00111             stopTimer=0.1;
00112 
00113         } else {
00114 
00115             stopTimer=1;
00116             //stopTimer=5;
00117             //  ble.waitForEvent();
00118 
00119         }
00120 
00121         if(timerA.read()>=stopTimer) {
00122             //   BLExmit=ble.getGapState().connected;
00123             BLExmit=ble.gap().getState().connected;
00124             timerA.stop();
00125             timerA.reset();
00126             led=!led.read();
00127             timerA.start();
00128             if(!button) dumpMEM();
00129             
00130             
00131             if(++canRdPointer>lastCanRdPointer) {
00132                 canRdPointer=firstCanRdPointer;
00133              }
00134             mcan = BLESlot2CANId(canRdPointer);
00135              for(int m=0; m<8; m++) {
00136                 kantMsg[m] = shareddata[canRdPointer][m];
00137             }
00138             if(can.write(CANMessage(mcan, kantMsg, 8))) {              // transmit message
00139             //if(can.write(txMsg)) {              // transmit message
00140            //     printf("CAN message sent %x, 0x%.3x",canRdPointer, mcan);
00141              //    for(int c=0; c<8; c++) {
00142              //        printf(" %.2x",kantMsg[c]);
00143              //    }
00144              //    printf("\r\n");
00145             }
00146 
00147 
00148         }
00149         if(CANmsgAvailable) {
00150             CANmsgAvailable = false;               // reset flag for next use
00151             can.read(rxMsg);                    // read message into Rx message storage
00152             j=CANId2BLESlot(rxMsg.id);
00153             if(j!=bleRdPointerA && j!=bleRdPointerB) {
00154                 //  printf("CAN message rcvd %.2x, 0x%.3x \r\n",j,rxMsg.id);
00155                 for(int i = 0; i < rxMsg.len; i++) {
00156                     shareddata[j][i]=rxMsg.data[i];
00157                     // printf(" %.2x",rxMsg.data[i]);
00158                 }
00159                 //printf("\r\n");
00160             }
00161         }
00162         if(BLExmit) {
00163             BLExmit=false;
00164             retry++;
00165             if(retry==0xff) ble.gap().startAdvertising();
00166           //  printf ("%#x  ",retry);
00167             k++;
00168             if(k>lastBleRdPointer)
00169                 k=firstBleRdPointer;
00170             readValue[0]=k;
00171           //  printf (" <%.2x ---",readValue[0]);
00172             for(int i=1; i<8; i++) {
00173                 readValue[i]=shareddata[k][i];
00174           //      printf ("%.2x ",readValue[i]);
00175             }
00176             readValue[8]= ++k;;
00177           //  printf ("> <%.2x ---",readValue[8]);
00178 
00179             for(int i=9; i<18; i++) {
00180                 readValue[i]=shareddata[k][i-9];
00181            //     printf ("%.2x ",readValue[i]);
00182             }
00183            // printf (">\n\r");
00184             ble.updateCharacteristicValue(readChar.getValueHandle(), readValue,18);
00185         }
00186     }
00187 }
00188 
00189 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00190 {
00191     BLE&        ble   = params->ble;
00192     ble_error_t error = params->error;
00193 
00194     if (error != BLE_ERROR_NONE) {
00195         onBleInitError(ble, error);
00196         return;
00197     }
00198 
00199     if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00200         return;
00201     }
00202 
00203     ble.gap().onDisconnection(disconnectionCallback);
00204 
00205     /* Setup primary service. */
00206 
00207     /* Setup advertising. */
00208     printf("Setup of BLE Advertising\r\n");
00209     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00210     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00211     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00212     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00213     ble.gap().setAdvertisingInterval(1000);// 1000ms
00214     ble.gap().startAdvertising();
00215     ble.onDataWritten(writeCharCallback);
00216     ble.addService(customService);
00217     ticker.detach();
00218     ticker.attach(periodicCallback, 1); // blink LED every second
00219 
00220     printf("Starting Loop\r\n");
00221 
00222 
00223 }
00224 void onBleInitError(BLE &ble, ble_error_t error)
00225 {
00226     (void)ble;
00227     (void)error;
00228     printf(" ### BLE init error ###\r\n");
00229 
00230 
00231     /* Initialization error handling should go here */
00232 }
00233 void onMsgReceived(void)
00234 {
00235     CANmsgAvailable = true;
00236 }
00237 
00238 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
00239 {
00240     (void)params;
00241     printf("\r\nTarget loss... wait for reconnection \r\n");
00242 
00243     BLE::Instance().gap().startAdvertising(); // restart advertising
00244     dumpMEM();
00245 }
00246 
00247 void writeCharCallback(const GattWriteCallbackParams  *params)
00248 {
00249 
00250     uint8_t j=0;
00251 
00252     // check to see what characteristic was written, by handle
00253     if(params->handle  == writeChar.getValueHandle()) {
00254         j= BLESlot2CANId(params->data[0]);
00255         printf("\n\r Data received: length = %d, data = ",params->len);
00256         if(canRdPointer != j && canRdPointer != j+1) {
00257             bleWrPointerA=j;
00258             bleWrPointerB=j+1;
00259             for(int x=0; x < 9; x++) {
00260                 printf("%c",params->data[x]);
00261                 shareddata[j][x]=params->data[x];
00262             }
00263             for(int x=9; x < 18; x++) {
00264                 printf("%c",params->data[x]);
00265                 shareddata[j+1][x-9]=params->data[x];
00266             }
00267             bleWrPointerA=255;
00268             bleWrPointerB=255;
00269         }
00270     }
00271 }
00272 void periodicCallback(void)
00273 {
00274     if(!ble.getGapState().connected) {
00275         printf("? ");
00276         ticker.attach(periodicCallback, 1); // blink LED every 5 second
00277     } else
00278         ticker.attach(periodicCallback, 0.1); // blink LED every second
00279 
00280     triggerSensorPolling = true;
00281 }
00282 
00283 uint8_t CANId2BLESlot(unsigned int   id)
00284 {
00285     uint8_t retval=0;
00286     switch(id) {
00287         case 0x313:
00288             retval=1;
00289             break;
00290         case 0x314:
00291             retval=2;
00292             break;
00293         case 0x310:
00294             retval=3;
00295             break;
00296         case 0x315:
00297             retval=4;
00298             break;
00299         case 0x111:
00300             retval=5;
00301             break;
00302         case 0x112:
00303             retval=6;
00304             break;
00305         case 0x400:
00306             retval=7;
00307             break;
00308         case 0x450:
00309             retval=8;
00310             break;
00311         case 0x451:
00312             retval=9;
00313             break;
00314         case 0x452:
00315             retval=10;
00316             break;
00317         case 0x453:
00318             retval=11;
00319             break;
00320         case 0x454:
00321             retval=12;
00322             break;
00323         case 0x455:
00324             retval=13;
00325             break;
00326         default:
00327             retval=0;
00328             break;
00329     }
00330     return retval;
00331 }
00332 unsigned int BLESlot2CANId(uint8_t   id)
00333 {
00334     unsigned int retval=0;
00335     switch(id) {
00336         case 63:
00337             retval=0x301;
00338             break;
00339         case 62:
00340             retval=0x302;
00341             break;
00342         case 61:
00343             retval=0x303;
00344             break;
00345         case 60:
00346             retval=0x304;
00347             break;
00348         case 59:
00349             retval=0x101;
00350             break;
00351         case 58:
00352             retval=0x102
00353             ;
00354             break;
00355         case 57:
00356             retval=0x040;
00357             break;
00358         default:
00359             retval=0x0;
00360             break;
00361     }
00362     return retval;
00363 }
00364 void initMEM(void)
00365 {
00366     for(int im = 0; im<64; im++) {
00367         for (int jm=0; jm<8; jm++) {
00368             shareddata[im][jm]=0x00;
00369         }
00370     }
00371     for (int jm=0; jm<8; jm++) {
00372         kantMsg[jm]=0;
00373     }
00374 }
00375 void dumpMEM(void)
00376 {
00377     printf("\r\n --- Memory Dump ---");
00378     for(int im = 0; im<64; im++) {
00379         printf("\r\n%.2x", im);
00380         for (int jm=0; jm<8; jm++) {
00381             printf(" %.2x", shareddata[im][jm]);
00382         }
00383     }
00384     printf("\r\n --- End of Dump ---\r\n");
00385 }