TEST

Dependencies:   max32630fthr Adafruit_FeatherOLED USBDevice

Committer:
gmehmet
Date:
Wed Apr 10 14:56:25 2019 +0300
Revision:
1:f60eafbf009a
Child:
3:2fe2ff1ca0dc
upload from local

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gmehmet 1:f60eafbf009a 1 #include "BLE_ICARUS.h"
gmehmet 1:f60eafbf009a 2
gmehmet 1:f60eafbf009a 3 #include "../../Utilities/mxm_assert.h"
gmehmet 1:f60eafbf009a 4 #include "queue.h"
gmehmet 1:f60eafbf009a 5 #include "Peripherals.h"
gmehmet 1:f60eafbf009a 6 #include "../../version.h"
gmehmet 1:f60eafbf009a 7
gmehmet 1:f60eafbf009a 8
gmehmet 1:f60eafbf009a 9 UUID customServiceUUID("00001523-1212-efde-1523-785feabcd123");
gmehmet 1:f60eafbf009a 10 UUID notifyCharUUID( "00001011-1212-efde-1523-785feabcd123");
gmehmet 1:f60eafbf009a 11 UUID configRWCharUUID("00001027-1212-efde-1523-785feabcd123");
gmehmet 1:f60eafbf009a 12
gmehmet 1:f60eafbf009a 13 const static char DEVICE_NAME[] = FIRMWARE_VERSION;
gmehmet 1:f60eafbf009a 14 static const uint16_t uuid16_list[] = {0xFFFF}; //Custom UUID, FFFF is reserved for development
gmehmet 1:f60eafbf009a 15
gmehmet 1:f60eafbf009a 16 // BLE defines
gmehmet 1:f60eafbf009a 17 #define BLE_TICKER_PERIOD 0.050 //Ticker period in order of seconds
gmehmet 1:f60eafbf009a 18 #define BLE_CONN_INT_PACKET 2 //Ticker period in order of seconds
gmehmet 1:f60eafbf009a 19 #define BLE_NOTIFY_CHAR_ARR_SIZE 20
gmehmet 1:f60eafbf009a 20 #define BLE_READWRITE_CHAR_ARR_SIZE 16
gmehmet 1:f60eafbf009a 21 #define MAX_BLE_QUEUE 128
gmehmet 1:f60eafbf009a 22 // end of BLE defines
gmehmet 1:f60eafbf009a 23
gmehmet 1:f60eafbf009a 24 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER)
gmehmet 1:f60eafbf009a 25 Ticker TICKER_BLE;
gmehmet 1:f60eafbf009a 26 static volatile unsigned char BLE_CAN_TRANSFER = 0;
gmehmet 1:f60eafbf009a 27
gmehmet 1:f60eafbf009a 28 static void Ble_Can_Transfer_Toggle(){
gmehmet 1:f60eafbf009a 29 BLE_CAN_TRANSFER = true;
gmehmet 1:f60eafbf009a 30 }
gmehmet 1:f60eafbf009a 31
gmehmet 1:f60eafbf009a 32 static inline char Ble_Can_Transfer_Check(){
gmehmet 1:f60eafbf009a 33 return BLE_CAN_TRANSFER;
gmehmet 1:f60eafbf009a 34 }
gmehmet 1:f60eafbf009a 35
gmehmet 1:f60eafbf009a 36 static inline void Ble_Can_Transfer_Set(unsigned char en){
gmehmet 1:f60eafbf009a 37 BLE_CAN_TRANSFER = en;
gmehmet 1:f60eafbf009a 38 }
gmehmet 1:f60eafbf009a 39
gmehmet 1:f60eafbf009a 40 #endif
gmehmet 1:f60eafbf009a 41
gmehmet 1:f60eafbf009a 42 /* Set Up custom Characteristics */
gmehmet 1:f60eafbf009a 43 static uint8_t notifyValue[BLE_NOTIFY_CHAR_ARR_SIZE] = {0};
gmehmet 1:f60eafbf009a 44 GattCharacteristic notifyChar(notifyCharUUID, notifyValue, BLE_NOTIFY_CHAR_ARR_SIZE, BLE_NOTIFY_CHAR_ARR_SIZE, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
gmehmet 1:f60eafbf009a 45
gmehmet 1:f60eafbf009a 46 static uint8_t configValue[BLE_READWRITE_CHAR_ARR_SIZE] = {3,0,254,37};
gmehmet 1:f60eafbf009a 47 ReadWriteArrayGattCharacteristic<uint8_t, sizeof(configValue)> writeChar(configRWCharUUID, configValue);
gmehmet 1:f60eafbf009a 48
gmehmet 1:f60eafbf009a 49 /* Set up custom service */
gmehmet 1:f60eafbf009a 50 GattCharacteristic *characteristics[] = {&writeChar,&notifyChar};
gmehmet 1:f60eafbf009a 51 GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
gmehmet 1:f60eafbf009a 52
gmehmet 1:f60eafbf009a 53 // Temporary Fixes to be removed
gmehmet 1:f60eafbf009a 54 volatile BLE_State bleState = BLE_STARTING;
gmehmet 1:f60eafbf009a 55
gmehmet 1:f60eafbf009a 56 // end of Temporary Fixes to be removed
gmehmet 1:f60eafbf009a 57
gmehmet 1:f60eafbf009a 58 // sc...
gmehmet 1:f60eafbf009a 59 struct queue_t BLEQUEUE;
gmehmet 1:f60eafbf009a 60 static uint8_t BLEOutBuffer[BLE_NOTIFY_CHAR_ARR_SIZE * MAX_BLE_QUEUE];
gmehmet 1:f60eafbf009a 61
gmehmet 1:f60eafbf009a 62 static DSInterface *BLE_DS_INTERFACE;
gmehmet 1:f60eafbf009a 63
gmehmet 1:f60eafbf009a 64
gmehmet 1:f60eafbf009a 65 /*
gmehmet 1:f60eafbf009a 66 * Handle writes to writeCharacteristic
gmehmet 1:f60eafbf009a 67 */
gmehmet 1:f60eafbf009a 68 void writeCharCallback(const GattWriteCallbackParams *params)
gmehmet 1:f60eafbf009a 69 {
gmehmet 1:f60eafbf009a 70 uint8_t data[BLE_READWRITE_CHAR_ARR_SIZE] = {0};
gmehmet 1:f60eafbf009a 71 /* Check to see what characteristic was written, by handle */
gmehmet 1:f60eafbf009a 72 printf("writeCharCallback %p\r\n", Thread::gettid());
gmehmet 1:f60eafbf009a 73 if(params->handle == writeChar.getValueHandle()) {
gmehmet 1:f60eafbf009a 74 printf("Data received: length = %d, data = 0x",params->len);
gmehmet 1:f60eafbf009a 75 for(int x=0; x < params->len; x++) {
gmehmet 1:f60eafbf009a 76 if ((BLE_DS_INTERFACE != NULL) && (params->data[x] != 0)) {
gmehmet 1:f60eafbf009a 77 BLE_DS_INTERFACE->build_command((char)params->data[x]);
gmehmet 1:f60eafbf009a 78 }
gmehmet 1:f60eafbf009a 79 printf("%x-", params->data[x]);
gmehmet 1:f60eafbf009a 80 }
gmehmet 1:f60eafbf009a 81 printf("\n\r");
gmehmet 1:f60eafbf009a 82 }
gmehmet 1:f60eafbf009a 83 /* Update the notifyChar with the value of writeChar */
gmehmet 1:f60eafbf009a 84 BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(writeChar.getValueHandle(), data, BLE_READWRITE_CHAR_ARR_SIZE);
gmehmet 1:f60eafbf009a 85 }
gmehmet 1:f60eafbf009a 86
gmehmet 1:f60eafbf009a 87 /**
gmehmet 1:f60eafbf009a 88 * This function is called when the ble initialization process has failed
gmehmet 1:f60eafbf009a 89 */
gmehmet 1:f60eafbf009a 90 void onBleInitError(BLE &ble, ble_error_t error)
gmehmet 1:f60eafbf009a 91 {
gmehmet 1:f60eafbf009a 92 printf("errro %d\r\n", __LINE__);
gmehmet 1:f60eafbf009a 93 /* Avoid compiler warnings */
gmehmet 1:f60eafbf009a 94 (void) ble;
gmehmet 1:f60eafbf009a 95 (void) error;
gmehmet 1:f60eafbf009a 96 /* Initialization error handling should go here */
gmehmet 1:f60eafbf009a 97 }
gmehmet 1:f60eafbf009a 98
gmehmet 1:f60eafbf009a 99 /* Restart Advertising on disconnection*/
gmehmet 1:f60eafbf009a 100 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
gmehmet 1:f60eafbf009a 101 {
gmehmet 1:f60eafbf009a 102 pr_debug("disconnectionCallback %p\r\n", Thread::gettid());
gmehmet 1:f60eafbf009a 103 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER)
gmehmet 1:f60eafbf009a 104 TICKER_BLE.detach();
gmehmet 1:f60eafbf009a 105 pr_debug("detached disconnectionCallback\r\n");
gmehmet 1:f60eafbf009a 106 Ble_Can_Transfer_Set(false);
gmehmet 1:f60eafbf009a 107 #endif
gmehmet 1:f60eafbf009a 108 bleState = BLE_DISCONNECTED;
gmehmet 1:f60eafbf009a 109 BLE::Instance().gap().startAdvertising();
gmehmet 1:f60eafbf009a 110 BLE_DS_INTERFACE->ds_set_ble_status(false);
gmehmet 1:f60eafbf009a 111 queue_reset(&BLEQUEUE);
gmehmet 1:f60eafbf009a 112 }
gmehmet 1:f60eafbf009a 113
gmehmet 1:f60eafbf009a 114 /* Connection */
gmehmet 1:f60eafbf009a 115 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
gmehmet 1:f60eafbf009a 116 {
gmehmet 1:f60eafbf009a 117 pr_err("connectionCallback %p\r\n", Thread::gettid());
gmehmet 1:f60eafbf009a 118
gmehmet 1:f60eafbf009a 119 Gap::ConnectionParams_t newParams = {
gmehmet 1:f60eafbf009a 120 .minConnectionInterval = 6, /**< Minimum Connection Interval in 1.25 ms units, see BLE_GAP_CP_LIMITS.*/
gmehmet 1:f60eafbf009a 121 .maxConnectionInterval = 9, /**< Maximum Connection Interval in 1.25 ms units, see BLE_GAP_CP_LIMITS.*/
gmehmet 1:f60eafbf009a 122 .slaveLatency = 0, /**< Slave Latency in number of connection events, see BLE_GAP_CP_LIMITS.*/
gmehmet 1:f60eafbf009a 123 .connectionSupervisionTimeout = 600 /**< Connection Supervision Timeout in 10 ms units, see BLE_GAP_CP_LIMITS.*/
gmehmet 1:f60eafbf009a 124 };
gmehmet 1:f60eafbf009a 125
gmehmet 1:f60eafbf009a 126 BLE::Instance().gap().updateConnectionParams(params->handle, &newParams);
gmehmet 1:f60eafbf009a 127 BLE::Instance().gap().stopAdvertising();
gmehmet 1:f60eafbf009a 128 BLE_DS_INTERFACE->ds_set_ble_status(true);
gmehmet 1:f60eafbf009a 129 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER)
gmehmet 1:f60eafbf009a 130 TICKER_BLE.attach(&Ble_Can_Transfer_Toggle, BLE_TICKER_PERIOD);
gmehmet 1:f60eafbf009a 131 pr_debug("Attached connectionCallback\r\n");
gmehmet 1:f60eafbf009a 132 #endif
gmehmet 1:f60eafbf009a 133 //m.sensor_enable(1);
gmehmet 1:f60eafbf009a 134 bleState = BLE_CONNECTED;
gmehmet 1:f60eafbf009a 135 }
gmehmet 1:f60eafbf009a 136
gmehmet 1:f60eafbf009a 137 /**
gmehmet 1:f60eafbf009a 138 * Callback triggered when the ble initialization process has finished
gmehmet 1:f60eafbf009a 139 */
gmehmet 1:f60eafbf009a 140 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
gmehmet 1:f60eafbf009a 141 {
gmehmet 1:f60eafbf009a 142 int ret;
gmehmet 1:f60eafbf009a 143 BLE& ble = params->ble;
gmehmet 1:f60eafbf009a 144 ble_error_t error = params->error;
gmehmet 1:f60eafbf009a 145
gmehmet 1:f60eafbf009a 146 if (error != BLE_ERROR_NONE) {
gmehmet 1:f60eafbf009a 147 printf("errro %d\r\n", __LINE__);
gmehmet 1:f60eafbf009a 148 /* In case of error, forward the error handling to onBleInitError */
gmehmet 1:f60eafbf009a 149 onBleInitError(ble, error);
gmehmet 1:f60eafbf009a 150 printf("errro %d\r\n", __LINE__);
gmehmet 1:f60eafbf009a 151 return;
gmehmet 1:f60eafbf009a 152 }
gmehmet 1:f60eafbf009a 153 /* Ensure that it is the default instance of BLE */
gmehmet 1:f60eafbf009a 154 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
gmehmet 1:f60eafbf009a 155 printf("errro %d\r\n", __LINE__);
gmehmet 1:f60eafbf009a 156 return;
gmehmet 1:f60eafbf009a 157 }
gmehmet 1:f60eafbf009a 158 ble.gap().onDisconnection(disconnectionCallback);
gmehmet 1:f60eafbf009a 159 ble.gap().onConnection(connectionCallback);
gmehmet 1:f60eafbf009a 160 ble.gattServer().onDataWritten(writeCharCallback);
gmehmet 1:f60eafbf009a 161 /* Setup advertising */
gmehmet 1:f60eafbf009a 162 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT
gmehmet 1:f60eafbf009a 163 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type
gmehmet 1:f60eafbf009a 164 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name
gmehmet 1:f60eafbf009a 165 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet
gmehmet 1:f60eafbf009a 166 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG);
gmehmet 1:f60eafbf009a 167 ble.gap().setAdvertisingInterval(100); // 100ms.
gmehmet 1:f60eafbf009a 168 /* Add our custom service */
gmehmet 1:f60eafbf009a 169 ble.gattServer().addService(customService);
gmehmet 1:f60eafbf009a 170 printf("bleInitComplete\n");
gmehmet 1:f60eafbf009a 171 ble.gap().startAdvertising();
gmehmet 1:f60eafbf009a 172
gmehmet 1:f60eafbf009a 173 ret = queue_init(&BLEQUEUE, BLEOutBuffer, BLE_NOTIFY_CHAR_ARR_SIZE, BLE_NOTIFY_CHAR_ARR_SIZE * MAX_BLE_QUEUE);
gmehmet 1:f60eafbf009a 174 if(ret != 0)
gmehmet 1:f60eafbf009a 175 printf("queue_init has failed\r\n");
gmehmet 1:f60eafbf009a 176 }
gmehmet 1:f60eafbf009a 177
gmehmet 1:f60eafbf009a 178 int BLE_Icarus_TransferData(uint8_t data_transfer[20]){
gmehmet 1:f60eafbf009a 179 int ret;
gmehmet 1:f60eafbf009a 180 ret = BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(notifyChar.getValueHandle(), data_transfer, 20);
gmehmet 1:f60eafbf009a 181 return ret;
gmehmet 1:f60eafbf009a 182 }
gmehmet 1:f60eafbf009a 183
gmehmet 1:f60eafbf009a 184 int BLE_Icarus_TransferDataFromQueue(){
gmehmet 1:f60eafbf009a 185 int ret;
gmehmet 1:f60eafbf009a 186 uint8_t data_transfer[20];
gmehmet 1:f60eafbf009a 187 unsigned char i;
gmehmet 1:f60eafbf009a 188
gmehmet 1:f60eafbf009a 189 if (BLEQUEUE.num_item >= 1) {
gmehmet 1:f60eafbf009a 190 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER)
gmehmet 1:f60eafbf009a 191 if(!Ble_Can_Transfer_Check())
gmehmet 1:f60eafbf009a 192 return 0;
gmehmet 1:f60eafbf009a 193 #endif
gmehmet 1:f60eafbf009a 194 for(i = 0; i < BLE_CONN_INT_PACKET; ++i){
gmehmet 1:f60eafbf009a 195 ret = dequeue(&BLEQUEUE, data_transfer);
gmehmet 1:f60eafbf009a 196 if(ret < 0)
gmehmet 1:f60eafbf009a 197 break;
gmehmet 1:f60eafbf009a 198 pr_debug("dequeued data for tx, %d remain\r\n", BLEQUEUE.num_item);
gmehmet 1:f60eafbf009a 199 BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(notifyChar.getValueHandle(), data_transfer, 20);
gmehmet 1:f60eafbf009a 200 }
gmehmet 1:f60eafbf009a 201 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER)
gmehmet 1:f60eafbf009a 202 TICKER_BLE.attach(&Ble_Can_Transfer_Toggle, BLE_TICKER_PERIOD);
gmehmet 1:f60eafbf009a 203 Ble_Can_Transfer_Set(false);
gmehmet 1:f60eafbf009a 204 #endif
gmehmet 1:f60eafbf009a 205 }
gmehmet 1:f60eafbf009a 206
gmehmet 1:f60eafbf009a 207 return 0;
gmehmet 1:f60eafbf009a 208 }
gmehmet 1:f60eafbf009a 209
gmehmet 1:f60eafbf009a 210
gmehmet 1:f60eafbf009a 211 //TODO: check that function for memory safety (no overflow should occur)
gmehmet 1:f60eafbf009a 212 int BLE_Icarus_AddtoQueue(uint8_t *data_transfer, int32_t buf_size, int32_t data_size) {
gmehmet 1:f60eafbf009a 213 int ret = 0;
gmehmet 1:f60eafbf009a 214 //printf("size is: %d\r\n", size);
gmehmet 1:f60eafbf009a 215 // TODO: Append a known character to the byte array in case size is
gmehmet 1:f60eafbf009a 216 // less than 20 bytes
gmehmet 1:f60eafbf009a 217 while ((data_size % BLE_NOTIFY_CHAR_ARR_SIZE) && data_size < buf_size)
gmehmet 1:f60eafbf009a 218 data_transfer[data_size++] = 0;
gmehmet 1:f60eafbf009a 219 mxm_assert_msg(!(data_size % 20), "BLE packet size must be multiple of 20 bytes");
gmehmet 1:f60eafbf009a 220
gmehmet 1:f60eafbf009a 221 while(data_size > 0){
gmehmet 1:f60eafbf009a 222 ret = enqueue(&BLEQUEUE, data_transfer);
gmehmet 1:f60eafbf009a 223 data_size -= BLE_NOTIFY_CHAR_ARR_SIZE;
gmehmet 1:f60eafbf009a 224 data_transfer += BLE_NOTIFY_CHAR_ARR_SIZE;
gmehmet 1:f60eafbf009a 225 }
gmehmet 1:f60eafbf009a 226
gmehmet 1:f60eafbf009a 227 if(ret != 0)
gmehmet 1:f60eafbf009a 228 printf("BLE_Icarus_AddtoQueue has failed\r\n");
gmehmet 1:f60eafbf009a 229
gmehmet 1:f60eafbf009a 230 return ret;
gmehmet 1:f60eafbf009a 231 }
gmehmet 1:f60eafbf009a 232
gmehmet 1:f60eafbf009a 233
gmehmet 1:f60eafbf009a 234 int BLE_Icarus_SetDSInterface(DSInterface *comm_obj) {
gmehmet 1:f60eafbf009a 235 BLE_DS_INTERFACE = comm_obj;
gmehmet 1:f60eafbf009a 236 return 0;
gmehmet 1:f60eafbf009a 237 }
gmehmet 1:f60eafbf009a 238
gmehmet 1:f60eafbf009a 239 bool BLE_Icarus_Interface_Exists()
gmehmet 1:f60eafbf009a 240 {
gmehmet 1:f60eafbf009a 241 return (bleState == BLE_CONNECTED);
gmehmet 1:f60eafbf009a 242 }
gmehmet 1:f60eafbf009a 243
gmehmet 1:f60eafbf009a 244 int BLE_ICARUS_Get_Mac_Address(char MacAdress[6]){
gmehmet 1:f60eafbf009a 245 /* Print out device MAC address to the console*/
gmehmet 1:f60eafbf009a 246 Gap::AddressType_t addr_type;
gmehmet 1:f60eafbf009a 247 Gap::Address_t address;
gmehmet 1:f60eafbf009a 248 if(BLE::Instance().gap().getAddress(&addr_type, address) != 0)
gmehmet 1:f60eafbf009a 249 return -1;
gmehmet 1:f60eafbf009a 250 for (int i = 5; i >= 0; i--){
gmehmet 1:f60eafbf009a 251 MacAdress[5-i] = address[i];
gmehmet 1:f60eafbf009a 252 }
gmehmet 1:f60eafbf009a 253 pr_info("BLE_ADV_NAME:%s", DEVICE_NAME);
gmehmet 1:f60eafbf009a 254 return 0;
gmehmet 1:f60eafbf009a 255 }