CAN to BLE translator - and back
Dependencies: BLE_API CANnucleo X_NUCLEO_IDB0XA1 mbed
main.cpp@1:43ff0e4d56cc, 2016-04-07 (annotated)
- Committer:
- filippomontano
- Date:
- Thu Apr 07 14:36:30 2016 +0000
- Revision:
- 1:43ff0e4d56cc
- Parent:
- 0:345c72cbcd60
Second skeletal: BLE init
Who changed what in which revision?
User | Revision | Line number | New 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 | 1:43ff0e4d56cc | 5 | #define TARGET_NUCLEO_F072RB 1 |
filippomontano | 0:345c72cbcd60 | 6 | #define LED_PIN PA_5 |
filippomontano | 0:345c72cbcd60 | 7 | |
filippomontano | 1:43ff0e4d56cc | 8 | #define BLE_GATT_CHAR_PROPERTIES_NOTIFY 0x10 |
filippomontano | 1:43ff0e4d56cc | 9 | |
filippomontano | 0:345c72cbcd60 | 10 | uint8_t CANId2BLESlot(unsigned int id); |
filippomontano | 0:345c72cbcd60 | 11 | unsigned int BLESlot2CANId(uint8_t id); |
filippomontano | 0:345c72cbcd60 | 12 | void onMsgReceived(void); |
filippomontano | 0:345c72cbcd60 | 13 | void initCAN(void); |
filippomontano | 0:345c72cbcd60 | 14 | |
filippomontano | 1:43ff0e4d56cc | 15 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params); |
filippomontano | 1:43ff0e4d56cc | 16 | void writeCharCallback(const GattWriteCallbackParams *params); |
filippomontano | 1:43ff0e4d56cc | 17 | void bleInitComplete(BLE::InitializationCompleteCallbackContext *params); |
filippomontano | 1:43ff0e4d56cc | 18 | void onBleInitError(BLE &ble, ble_error_t error); |
filippomontano | 1:43ff0e4d56cc | 19 | void initBLE(void); |
filippomontano | 1:43ff0e4d56cc | 20 | |
filippomontano | 1:43ff0e4d56cc | 21 | |
filippomontano | 0:345c72cbcd60 | 22 | DigitalOut led(LED_PIN); |
filippomontano | 0:345c72cbcd60 | 23 | |
filippomontano | 0:345c72cbcd60 | 24 | |
filippomontano | 1:43ff0e4d56cc | 25 | const static char DEVICE_NAME[] = "STNucleo - RGM - FM"; |
filippomontano | 1:43ff0e4d56cc | 26 | static const uint16_t uuid16_list[] = {0xFFFF}; |
filippomontano | 1:43ff0e4d56cc | 27 | |
filippomontano | 0:345c72cbcd60 | 28 | //const unsigned int RX_ID = 0x10; |
filippomontano | 0:345c72cbcd60 | 29 | //const unsigned int TX_ID = 0x11; |
filippomontano | 0:345c72cbcd60 | 30 | |
filippomontano | 0:345c72cbcd60 | 31 | char shareddata[64][8]= { }; |
filippomontano | 0:345c72cbcd60 | 32 | |
filippomontano | 0:345c72cbcd60 | 33 | uint8_t canWrPointer= 255; |
filippomontano | 0:345c72cbcd60 | 34 | uint8_t canRdPointer= 255; |
filippomontano | 0:345c72cbcd60 | 35 | uint8_t bleWrPointerA= 255; |
filippomontano | 0:345c72cbcd60 | 36 | uint8_t bleRdPointerA= 255; |
filippomontano | 0:345c72cbcd60 | 37 | uint8_t bleWrPointerB= 255; |
filippomontano | 0:345c72cbcd60 | 38 | uint8_t bleRdPointerB= 255; |
filippomontano | 0:345c72cbcd60 | 39 | |
filippomontano | 0:345c72cbcd60 | 40 | Timer timerA, timerB; //questi due contatori servono solo per dire: appena è passato un po' di tempo -> esegui |
filippomontano | 0:345c72cbcd60 | 41 | |
filippomontano | 0:345c72cbcd60 | 42 | CAN can(PB_8, PB_9); // CAN Rx pin name, CAN Tx pin name |
filippomontano | 0:345c72cbcd60 | 43 | CANMessage rxMsg; |
filippomontano | 0:345c72cbcd60 | 44 | CANMessage txMsg; |
filippomontano | 0:345c72cbcd60 | 45 | |
filippomontano | 1:43ff0e4d56cc | 46 | BLE ble; |
filippomontano | 1:43ff0e4d56cc | 47 | |
filippomontano | 1:43ff0e4d56cc | 48 | uint16_t customServiceUUID = 0xA000; // service UUID |
filippomontano | 1:43ff0e4d56cc | 49 | uint16_t readCharUUID = 0xA001; // read characteristic UUID |
filippomontano | 1:43ff0e4d56cc | 50 | uint16_t writeCharUUID = 0xA002; // write characteristic UUID |
filippomontano | 1:43ff0e4d56cc | 51 | |
filippomontano | 1:43ff0e4d56cc | 52 | static uint8_t readValue[128] = {0}; |
filippomontano | 1:43ff0e4d56cc | 53 | 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 | 1:43ff0e4d56cc | 54 | |
filippomontano | 1:43ff0e4d56cc | 55 | static uint8_t writeValue[128] = {0}; |
filippomontano | 1:43ff0e4d56cc | 56 | WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue); |
filippomontano | 1:43ff0e4d56cc | 57 | |
filippomontano | 1:43ff0e4d56cc | 58 | GattCharacteristic *characteristics[] = {&readChar, &writeChar}; |
filippomontano | 1:43ff0e4d56cc | 59 | GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); |
filippomontano | 1:43ff0e4d56cc | 60 | |
filippomontano | 1:43ff0e4d56cc | 61 | |
filippomontano | 0:345c72cbcd60 | 62 | volatile bool CANmsgAvailable = false; |
filippomontano | 1:43ff0e4d56cc | 63 | volatile bool BLExmit = false; |
filippomontano | 0:345c72cbcd60 | 64 | |
filippomontano | 0:345c72cbcd60 | 65 | int main() |
filippomontano | 0:345c72cbcd60 | 66 | { |
filippomontano | 0:345c72cbcd60 | 67 | uint8_t j=0; |
filippomontano | 0:345c72cbcd60 | 68 | printf("\r\nBoard started\r\n"); |
filippomontano | 0:345c72cbcd60 | 69 | led = 1; // turn LED on |
filippomontano | 0:345c72cbcd60 | 70 | initCAN(); |
filippomontano | 0:345c72cbcd60 | 71 | timerA.start(); |
filippomontano | 0:345c72cbcd60 | 72 | timerB.start(); |
filippomontano | 0:345c72cbcd60 | 73 | while(1) { |
filippomontano | 0:345c72cbcd60 | 74 | if(timerA.read()>=1.0) { |
filippomontano | 0:345c72cbcd60 | 75 | timerA.stop(); |
filippomontano | 0:345c72cbcd60 | 76 | timerA.reset(); |
filippomontano | 0:345c72cbcd60 | 77 | led=!led.read(); |
filippomontano | 0:345c72cbcd60 | 78 | timerA.start(); |
filippomontano | 0:345c72cbcd60 | 79 | } |
filippomontano | 1:43ff0e4d56cc | 80 | if(timerB.read()>=0.1) { |
filippomontano | 0:345c72cbcd60 | 81 | timerB.stop(); |
filippomontano | 0:345c72cbcd60 | 82 | timerB.reset(); |
filippomontano | 1:43ff0e4d56cc | 83 | |
filippomontano | 1:43ff0e4d56cc | 84 | if(ble.getGapState().connected) BLExmit=true; |
filippomontano | 1:43ff0e4d56cc | 85 | |
filippomontano | 0:345c72cbcd60 | 86 | timerB.start(); |
filippomontano | 0:345c72cbcd60 | 87 | } |
filippomontano | 0:345c72cbcd60 | 88 | if(CANmsgAvailable) { |
filippomontano | 0:345c72cbcd60 | 89 | CANmsgAvailable = false; // reset flag for next use |
filippomontano | 0:345c72cbcd60 | 90 | can.read(rxMsg); // read message into Rx message storage |
filippomontano | 0:345c72cbcd60 | 91 | j=CANId2BLESlot(rxMsg.id); |
filippomontano | 0:345c72cbcd60 | 92 | if(j!=bleRdPointerA && j!=bleRdPointerB) { |
filippomontano | 0:345c72cbcd60 | 93 | //write if BLE is not reading |
filippomontano | 0:345c72cbcd60 | 94 | canWrPointer=j; |
filippomontano | 0:345c72cbcd60 | 95 | printf("CAN message received:\r\n"); |
filippomontano | 0:345c72cbcd60 | 96 | printf(" ID = %#x -> %d \r\n", rxMsg.id, j); |
filippomontano | 0:345c72cbcd60 | 97 | // printf(" Type = %d\r\n", rxMsg.type); |
filippomontano | 0:345c72cbcd60 | 98 | // printf(" Format = %d\r\n", rxMsg.format); |
filippomontano | 0:345c72cbcd60 | 99 | // printf(" Length = %d\r\n", rxMsg.len); |
filippomontano | 0:345c72cbcd60 | 100 | printf(" Data ="); |
filippomontano | 0:345c72cbcd60 | 101 | for(int i = 0; i < rxMsg.len; i++) { |
filippomontano | 0:345c72cbcd60 | 102 | shareddata[j][i]=rxMsg.data[i]; |
filippomontano | 0:345c72cbcd60 | 103 | printf(" %x", rxMsg.data[i]); |
filippomontano | 0:345c72cbcd60 | 104 | } |
filippomontano | 0:345c72cbcd60 | 105 | printf("\r\n"); |
filippomontano | 0:345c72cbcd60 | 106 | canWrPointer=255; |
filippomontano | 1:43ff0e4d56cc | 107 | } else { |
filippomontano | 1:43ff0e4d56cc | 108 | printf("CAN message %#x dropped because BLE read\r\n",rxMsg.id); |
filippomontano | 0:345c72cbcd60 | 109 | } |
filippomontano | 1:43ff0e4d56cc | 110 | } |
filippomontano | 1:43ff0e4d56cc | 111 | if(BLExmit) { |
filippomontano | 1:43ff0e4d56cc | 112 | BLExmit=false; |
filippomontano | 0:345c72cbcd60 | 113 | } |
filippomontano | 0:345c72cbcd60 | 114 | } |
filippomontano | 0:345c72cbcd60 | 115 | } |
filippomontano | 0:345c72cbcd60 | 116 | void initCAN(void) |
filippomontano | 0:345c72cbcd60 | 117 | { |
filippomontano | 0:345c72cbcd60 | 118 | can.frequency(500000); // set bit rate to 500kbps as S018 |
filippomontano | 0:345c72cbcd60 | 119 | can.attach(&onMsgReceived, CAN::RxIrq); // attach 'CAN receive-complete' interrupt handler |
filippomontano | 0:345c72cbcd60 | 120 | printf("\r\nCAN started at 500kbps\r\n"); |
filippomontano | 0:345c72cbcd60 | 121 | } |
filippomontano | 1:43ff0e4d56cc | 122 | void initBLE(void) |
filippomontano | 1:43ff0e4d56cc | 123 | { |
filippomontano | 1:43ff0e4d56cc | 124 | BLE::Instance().init(bleInitComplete); |
filippomontano | 1:43ff0e4d56cc | 125 | } |
filippomontano | 1:43ff0e4d56cc | 126 | void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) |
filippomontano | 1:43ff0e4d56cc | 127 | { |
filippomontano | 1:43ff0e4d56cc | 128 | BLE& ble = params->ble; |
filippomontano | 1:43ff0e4d56cc | 129 | ble_error_t error = params->error; |
filippomontano | 1:43ff0e4d56cc | 130 | |
filippomontano | 1:43ff0e4d56cc | 131 | if (error != BLE_ERROR_NONE) { |
filippomontano | 1:43ff0e4d56cc | 132 | onBleInitError(ble, error); |
filippomontano | 1:43ff0e4d56cc | 133 | return; |
filippomontano | 1:43ff0e4d56cc | 134 | } |
filippomontano | 1:43ff0e4d56cc | 135 | |
filippomontano | 1:43ff0e4d56cc | 136 | if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { |
filippomontano | 1:43ff0e4d56cc | 137 | return; |
filippomontano | 1:43ff0e4d56cc | 138 | } |
filippomontano | 1:43ff0e4d56cc | 139 | |
filippomontano | 1:43ff0e4d56cc | 140 | ble.gap().onDisconnection(disconnectionCallback); |
filippomontano | 1:43ff0e4d56cc | 141 | |
filippomontano | 1:43ff0e4d56cc | 142 | /* Setup primary service. */ |
filippomontano | 1:43ff0e4d56cc | 143 | |
filippomontano | 1:43ff0e4d56cc | 144 | /* Setup advertising. */ |
filippomontano | 1:43ff0e4d56cc | 145 | printf("Setup of Advertising\r\n"); |
filippomontano | 1:43ff0e4d56cc | 146 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
filippomontano | 1:43ff0e4d56cc | 147 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); |
filippomontano | 1:43ff0e4d56cc | 148 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
filippomontano | 1:43ff0e4d56cc | 149 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
filippomontano | 1:43ff0e4d56cc | 150 | ble.gap().setAdvertisingInterval(1000); /* 1000ms */ |
filippomontano | 1:43ff0e4d56cc | 151 | ble.gap().startAdvertising(); |
filippomontano | 1:43ff0e4d56cc | 152 | ble.onDataWritten(writeCharCallback); |
filippomontano | 1:43ff0e4d56cc | 153 | ble.addService(customService); |
filippomontano | 1:43ff0e4d56cc | 154 | } |
filippomontano | 1:43ff0e4d56cc | 155 | void onBleInitError(BLE &ble, ble_error_t error) |
filippomontano | 1:43ff0e4d56cc | 156 | { |
filippomontano | 1:43ff0e4d56cc | 157 | (void)ble; |
filippomontano | 1:43ff0e4d56cc | 158 | (void)error; |
filippomontano | 1:43ff0e4d56cc | 159 | /* Initialization error handling should go here */ |
filippomontano | 1:43ff0e4d56cc | 160 | } |
filippomontano | 0:345c72cbcd60 | 161 | void onMsgReceived(void) |
filippomontano | 0:345c72cbcd60 | 162 | { |
filippomontano | 0:345c72cbcd60 | 163 | CANmsgAvailable = true; |
filippomontano | 0:345c72cbcd60 | 164 | } |
filippomontano | 0:345c72cbcd60 | 165 | uint8_t CANId2BLESlot(unsigned int id) |
filippomontano | 0:345c72cbcd60 | 166 | { |
filippomontano | 0:345c72cbcd60 | 167 | uint8_t retval=0; |
filippomontano | 0:345c72cbcd60 | 168 | switch(id) { |
filippomontano | 0:345c72cbcd60 | 169 | case 0x313: |
filippomontano | 0:345c72cbcd60 | 170 | retval=1; |
filippomontano | 0:345c72cbcd60 | 171 | break; |
filippomontano | 0:345c72cbcd60 | 172 | case 0x314: |
filippomontano | 0:345c72cbcd60 | 173 | retval=2; |
filippomontano | 0:345c72cbcd60 | 174 | break; |
filippomontano | 0:345c72cbcd60 | 175 | case 0x310: |
filippomontano | 0:345c72cbcd60 | 176 | retval=3; |
filippomontano | 0:345c72cbcd60 | 177 | break; |
filippomontano | 0:345c72cbcd60 | 178 | case 0x315: |
filippomontano | 0:345c72cbcd60 | 179 | retval=4; |
filippomontano | 0:345c72cbcd60 | 180 | break; |
filippomontano | 0:345c72cbcd60 | 181 | case 0x111: |
filippomontano | 0:345c72cbcd60 | 182 | retval=5; |
filippomontano | 0:345c72cbcd60 | 183 | break; |
filippomontano | 0:345c72cbcd60 | 184 | case 0x112: |
filippomontano | 0:345c72cbcd60 | 185 | retval=6; |
filippomontano | 0:345c72cbcd60 | 186 | break; |
filippomontano | 0:345c72cbcd60 | 187 | case 0x400: |
filippomontano | 0:345c72cbcd60 | 188 | retval=7; |
filippomontano | 0:345c72cbcd60 | 189 | break; |
filippomontano | 0:345c72cbcd60 | 190 | case 0x450: |
filippomontano | 0:345c72cbcd60 | 191 | retval=8; |
filippomontano | 0:345c72cbcd60 | 192 | break; |
filippomontano | 0:345c72cbcd60 | 193 | case 0x451: |
filippomontano | 0:345c72cbcd60 | 194 | retval=9; |
filippomontano | 0:345c72cbcd60 | 195 | break; |
filippomontano | 0:345c72cbcd60 | 196 | case 0x452: |
filippomontano | 0:345c72cbcd60 | 197 | retval=10; |
filippomontano | 0:345c72cbcd60 | 198 | break; |
filippomontano | 0:345c72cbcd60 | 199 | case 0x453: |
filippomontano | 0:345c72cbcd60 | 200 | retval=11; |
filippomontano | 0:345c72cbcd60 | 201 | break; |
filippomontano | 0:345c72cbcd60 | 202 | case 0x454: |
filippomontano | 0:345c72cbcd60 | 203 | retval=12; |
filippomontano | 0:345c72cbcd60 | 204 | break; |
filippomontano | 0:345c72cbcd60 | 205 | case 0x455: |
filippomontano | 0:345c72cbcd60 | 206 | retval=13; |
filippomontano | 0:345c72cbcd60 | 207 | break; |
filippomontano | 0:345c72cbcd60 | 208 | default: |
filippomontano | 0:345c72cbcd60 | 209 | retval=0; |
filippomontano | 0:345c72cbcd60 | 210 | break; |
filippomontano | 0:345c72cbcd60 | 211 | } |
filippomontano | 0:345c72cbcd60 | 212 | return retval; |
filippomontano | 0:345c72cbcd60 | 213 | } |
filippomontano | 0:345c72cbcd60 | 214 | unsigned int BLESlot2CANId(uint8_t id) |
filippomontano | 0:345c72cbcd60 | 215 | { |
filippomontano | 0:345c72cbcd60 | 216 | unsigned int retval=0; |
filippomontano | 0:345c72cbcd60 | 217 | switch(id) { |
filippomontano | 0:345c72cbcd60 | 218 | case 63: |
filippomontano | 0:345c72cbcd60 | 219 | retval=0x303; |
filippomontano | 0:345c72cbcd60 | 220 | break; |
filippomontano | 0:345c72cbcd60 | 221 | case 62: |
filippomontano | 0:345c72cbcd60 | 222 | retval=0x304; |
filippomontano | 0:345c72cbcd60 | 223 | break; |
filippomontano | 0:345c72cbcd60 | 224 | default: |
filippomontano | 0:345c72cbcd60 | 225 | retval=0x0; |
filippomontano | 0:345c72cbcd60 | 226 | break; |
filippomontano | 0:345c72cbcd60 | 227 | } |
filippomontano | 0:345c72cbcd60 | 228 | return retval; |
filippomontano | 1:43ff0e4d56cc | 229 | } |
filippomontano | 1:43ff0e4d56cc | 230 | |
filippomontano | 1:43ff0e4d56cc | 231 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) |
filippomontano | 1:43ff0e4d56cc | 232 | { |
filippomontano | 1:43ff0e4d56cc | 233 | (void)params; |
filippomontano | 1:43ff0e4d56cc | 234 | printf("\r\nTarget loss... wait for reconnection \r\n"); |
filippomontano | 1:43ff0e4d56cc | 235 | |
filippomontano | 1:43ff0e4d56cc | 236 | BLE::Instance().gap().startAdvertising(); // restart advertising |
filippomontano | 1:43ff0e4d56cc | 237 | } |
filippomontano | 1:43ff0e4d56cc | 238 | |
filippomontano | 1:43ff0e4d56cc | 239 | void writeCharCallback(const GattWriteCallbackParams *params) |
filippomontano | 1:43ff0e4d56cc | 240 | { |
filippomontano | 1:43ff0e4d56cc | 241 | /* |
filippomontano | 1:43ff0e4d56cc | 242 | int terminale=params->len; |
filippomontano | 1:43ff0e4d56cc | 243 | // check to see what characteristic was written, by handle |
filippomontano | 1:43ff0e4d56cc | 244 | if(params->handle == writeChar.getValueHandle()) { |
filippomontano | 1:43ff0e4d56cc | 245 | daerdata[0]=terminale; |
filippomontano | 1:43ff0e4d56cc | 246 | |
filippomontano | 1:43ff0e4d56cc | 247 | printf("\n\r Data received: length = %d, data = ",terminale); |
filippomontano | 1:43ff0e4d56cc | 248 | for(int x=0; x < terminale; x++) { |
filippomontano | 1:43ff0e4d56cc | 249 | printf("%c",params->data[x]); |
filippomontano | 1:43ff0e4d56cc | 250 | daerdata[x+1]=params->data[x]; |
filippomontano | 1:43ff0e4d56cc | 251 | } |
filippomontano | 1:43ff0e4d56cc | 252 | |
filippomontano | 1:43ff0e4d56cc | 253 | ble.updateCharacteristicValue(readChar.getValueHandle(),daerdata,terminale+1); |
filippomontano | 1:43ff0e4d56cc | 254 | |
filippomontano | 1:43ff0e4d56cc | 255 | }*/ |
filippomontano | 1:43ff0e4d56cc | 256 | } |