55 #include "rf_data_entry.h" 57 #include "rf_ble_cmd.h" 58 #include "lib/random.h" 62 #include "inc/hw_types.h" 63 #include "inc/hw_rfc_dbell.h" 69 #include "rf_patches/rf_patch_cpe_bt5.h" 73 #define LOG_MODULE "BLE-RADIO" 74 #define LOG_LEVEL LOG_LEVEL_MAIN 76 #define CMD_GET_STATUS(X) (((rfc_radioOp_t *)X)->status) 77 #define RX_ENTRY_STATUS(X) (((rfc_dataEntry_t *)X)->status) 78 #define RX_ENTRY_LENGTH(X) (((rfc_dataEntry_t *)X)->length) 79 #define RX_ENTRY_TYPE(X) (((rfc_dataEntry_t *)X)->config.type) 80 #define RX_ENTRY_NEXT_ENTRY(X) (((rfc_dataEntry_t *)X)->pNextEntry) 81 #define RX_ENTRY_DATA_LENGTH(X) ((X)[8]) 82 #define RX_ENTRY_DATA_PTR(X) (&(X)[9]) 83 #define TX_ENTRY_STATUS(X) RX_ENTRY_STATUS(X) 84 #define TX_ENTRY_LENGTH(X) RX_ENTRY_LENGTH(X) 85 #define TX_ENTRY_TYPE(X) RX_ENTRY_TYPE(X) 86 #define TX_ENTRY_NEXT_ENTRY(X) RX_ENTRY_NEXT_ENTRY(X) 87 #define TX_ENTRY_FRAME_TYPE(X) ((X)[8]) 88 #define TX_ENTRY_DATA_PTR(X) (&(X)[9]) 96 return LPM_MODE_SLEEP;
99 return LPM_MODE_MAX_SUPPORTED;
102 LPM_MODULE(cc26xx_ble_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE);
105 #define TIME_UNIT_MS 1000 106 #define TIME_UNIT_0_625_MS 1600 107 #define TIME_UNIT_1_25_MS 800 108 #define TIME_UNIT_10_MS 100 109 #define TIME_UNIT_RF_CORE 4000000 110 #define TIME_UNIT_RTIMER RTIMER_SECOND 113 ticks_from_unit(uint32_t value, uint32_t unit)
115 double temp = (((double)value) / unit) * RTIMER_SECOND;
116 return (rtimer_clock_t)temp;
119 ticks_to_unit(rtimer_clock_t value, uint32_t unit)
121 double temp = (((double)value) / RTIMER_SECOND) * unit;
122 return (uint32_t)temp;
126 #define CMD_BUFFER_SIZE 28 127 #define PARAM_BUFFER_SIZE 48 128 #define OUTPUT_BUFFER_SIZE 24 130 #define CMD_BUFFER_SIZE 24 131 #define PARAM_BUFFER_SIZE 36 132 #define OUTPUT_BUFFER_SIZE 24 136 #define ADV_RX_BUFFERS_OVERHEAD 8 137 #define ADV_RX_BUFFERS_DATA_LEN 60 138 #define ADV_RX_BUFFERS_LEN (ADV_RX_BUFFERS_OVERHEAD + ADV_RX_BUFFERS_DATA_LEN) 139 #define ADV_RX_BUFFERS_NUM 2 141 #define ADV_PREPROCESSING_TIME_TICKS 65 145 uint16_t adv_interval;
146 ble_adv_type_t adv_type;
147 ble_addr_type_t own_addr_type;
149 uint8_t adv_data_len;
150 uint8_t adv_data[BLE_ADV_DATA_LEN];
151 uint8_t scan_rsp_data_len;
152 uint8_t scan_rsp_data[BLE_ADV_DATA_LEN];
155 rtimer_clock_t start_rt;
158 uint8_t cmd_buf[CMD_BUFFER_SIZE];
159 uint8_t param_buf[PARAM_BUFFER_SIZE];
160 uint8_t output_buf[OUTPUT_BUFFER_SIZE];
161 dataQueue_t rx_queue;
162 uint8_t rx_buffers[ADV_RX_BUFFERS_NUM][ADV_RX_BUFFERS_LEN];
163 uint8_t *rx_queue_current;
166 static ble_adv_param_t adv_param;
167 static void advertising_event(
struct rtimer *t,
void *ptr);
170 #define BLE_MODE_MAX_CONNECTIONS 1 173 #ifdef BLE_MODE_CONF_CONN_MAX_PACKET_SIZE 174 #define BLE_MODE_CONN_MAX_PACKET_SIZE BLE_MODE_CONF_CONN_MAX_PACKET_SIZE 176 #define BLE_MODE_CONN_MAX_PACKET_SIZE 256 179 #define CONN_BLE_BUFFER_SIZE 27 181 #define CONN_RX_BUFFERS_OVERHEAD 8 182 #define CONN_RX_BUFFERS_DATA_LEN 60 183 #define CONN_RX_BUFFERS_LEN (CONN_RX_BUFFERS_OVERHEAD + CONN_RX_BUFFERS_DATA_LEN) 184 #define CONN_RX_BUFFERS_NUM 12 187 #define DATA_ENTRY_FREE 5 188 #define DATA_ENTRY_QUEUED 6 190 #define CONN_TX_BUFFERS_OVERHEAD 9 191 #define CONN_TX_BUFFERS_DATA_LEN 27 192 #define CONN_TX_BUFFERS_LEN (CONN_TX_BUFFERS_OVERHEAD + CONN_TX_BUFFERS_DATA_LEN) 193 #define CONN_TX_BUFFERS_NUM 12 195 #define CONN_WIN_SIZE 1 196 #define CONN_WIN_OFFSET 20 198 #define CONN_EVENT_LATENCY_THRESHOLD 10 199 #define CONN_WINDOW_WIDENING_TICKS 30 200 #define CONN_PREPROCESSING_TIME_TICKS 100 202 #define CONN_UPDATE_DELAY 6 206 uint8_t peer_address[BLE_ADDR_SIZE];
207 uint32_t access_address;
216 uint64_t channel_map;
217 uint8_t num_used_channels;
220 rtimer_clock_t timestamp_rt;
224 uint8_t unmapped_channel;
225 uint8_t mapped_channel;
226 rtimer_clock_t start_rt;
227 uint16_t conn_handle;
230 uint8_t cmd_buf[CMD_BUFFER_SIZE];
231 uint8_t param_buf[PARAM_BUFFER_SIZE];
232 uint8_t output_buf[OUTPUT_BUFFER_SIZE];
233 dataQueue_t rx_queue;
234 uint8_t rx_buffers[CONN_RX_BUFFERS_NUM][CONN_RX_BUFFERS_LEN];
235 uint8_t *rx_queue_current;
236 dataQueue_t tx_queue;
237 uint8_t tx_buffers[CONN_TX_BUFFERS_NUM][CONN_TX_BUFFERS_LEN];
238 uint8_t tx_buffers_sent;
239 uint16_t skipped_events;
241 uint64_t channel_update_channel_map;
242 uint16_t channel_update_counter;
243 uint8_t channel_update_num_used_channels;
245 uint8_t conn_update_win_size;
246 uint16_t conn_update_win_offset;
247 uint16_t conn_update_interval;
248 uint16_t conn_update_latency;
249 uint16_t conn_update_timeout;
250 uint16_t conn_update_counter;
253 static ble_conn_param_t conn_param[BLE_MODE_MAX_CONNECTIONS];
255 static uint16_t conn_counter = 0;
257 static void connection_event_slave(
struct rtimer *t,
void *ptr);
259 PROCESS(ble_hal_conn_rx_process,
"BLE/CC26xx connection RX process");
260 process_event_t rx_data_event;
266 ble_conn_param_t *conn;
268 rfc_dataEntry_t *entry;
271 memset(&adv_param, 0x00,
sizeof(ble_adv_param_t));
272 memset(&adv_param.rx_queue, 0x00,
sizeof(adv_param.rx_queue));
273 adv_param.rx_queue.pCurrEntry = adv_param.rx_buffers[0];
274 adv_param.rx_queue.pLastEntry = NULL;
275 adv_param.rx_queue_current = adv_param.rx_buffers[0];
276 for(i = 0; i < ADV_RX_BUFFERS_NUM; i++) {
277 memset(&adv_param.rx_buffers[i], 0x00, ADV_RX_BUFFERS_LEN);
278 entry = (rfc_dataEntry_t *)adv_param.rx_buffers[i];
279 entry->pNextEntry = adv_param.rx_buffers[(i + 1) % ADV_RX_BUFFERS_NUM];
280 entry->config.lenSz = 1;
281 entry->length = ADV_RX_BUFFERS_DATA_LEN;
284 memset(conn_param, 0x00,
sizeof(ble_conn_param_t) * BLE_MODE_MAX_CONNECTIONS);
285 for(conn_count = 0; conn_count < BLE_MODE_MAX_CONNECTIONS; conn_count++) {
287 conn = &conn_param[conn_count];
288 memset(&conn->rx_queue, 0x00,
sizeof(conn->rx_queue));
289 conn->rx_queue.pCurrEntry = conn->rx_buffers[0];
290 conn->rx_queue.pLastEntry = NULL;
291 conn->rx_queue_current = conn->rx_buffers[0];
293 for(i = 0; i < CONN_RX_BUFFERS_NUM; i++) {
294 memset(&conn->rx_buffers[i], 0x00, CONN_RX_BUFFERS_LEN);
295 entry = (rfc_dataEntry_t *)conn->rx_buffers[i];
296 entry->pNextEntry = conn->rx_buffers[(i + 1) % CONN_RX_BUFFERS_NUM];
297 entry->config.lenSz = 1;
298 entry->length = CONN_RX_BUFFERS_DATA_LEN;
302 memset(&conn->tx_queue, 0x00,
sizeof(conn->tx_queue));
303 conn->tx_queue.pCurrEntry = NULL;
304 conn->tx_queue.pLastEntry = NULL;
306 for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
307 memset(&conn->tx_buffers[i], 0x00, CONN_TX_BUFFERS_LEN);
308 entry = (rfc_dataEntry_t *)conn->tx_buffers[i];
309 entry->config.lenSz = 1;
310 entry->status = DATA_ENTRY_FREE;
315 static ble_conn_param_t *
316 get_connection_for_handle(uint8_t conn_handle)
319 for(i = 0; i < BLE_MODE_MAX_CONNECTIONS; i++) {
320 if(conn_param[i].conn_handle == conn_handle) {
321 return &conn_param[i];
328 tx_queue_get_buffer(ble_conn_param_t *param)
331 rfc_dataEntry_t *entry;
332 for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
333 entry = (rfc_dataEntry_t *)param->tx_buffers[i];
334 if(entry->status == DATA_ENTRY_FREE) {
335 return (uint8_t *)entry;
342 tx_queue_count_free_buffers(ble_conn_param_t *param)
345 uint16_t free_bufs = 0;
346 for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
347 if(TX_ENTRY_STATUS(param->tx_buffers[i]) == DATA_ENTRY_FREE) {
355 tx_queue_data_to_transmit(ble_conn_param_t *param)
358 for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
359 if(TX_ENTRY_STATUS(param->tx_buffers[i]) == DATA_ENTRY_QUEUED) {
375 LOG_ERR(
"rf_core_boot: rf_core_power_up() failed\n");
377 return RF_CORE_CMD_ERROR;
385 LOG_ERR(
"rf_core_boot: rf_core_start_rat() failed\n");
387 return RF_CORE_CMD_ERROR;
393 LOG_ERR(
"could not setup rf-core to BLE mode\n");
394 return BLE_RESULT_ERROR;
397 return BLE_RESULT_OK;
410 LOG_INFO(
"maximum connections: %4d\n", BLE_MODE_MAX_CONNECTIONS);
411 LOG_INFO(
"max. packet length: %4d\n", BLE_MODE_CONN_MAX_PACKET_SIZE);
415 if(
on() != BLE_RESULT_OK) {
416 return BLE_RESULT_ERROR;
423 return BLE_RESULT_OK;
427 read_bd_addr(uint8_t *
addr)
430 return BLE_RESULT_OK;
434 read_buffer_size(
unsigned int *buf_len,
unsigned int *num_buf)
437 uint16_t ll_buffers = CONN_TX_BUFFERS_NUM;
438 uint16_t packet_buffers;
439 uint16_t buffer_size;
440 for(i = 0; i < conn_counter; i++) {
441 ll_buffers = MIN(ll_buffers, tx_queue_count_free_buffers(&conn_param[i]));
443 packet_buffers = ll_buffers / (BLE_MODE_CONN_MAX_PACKET_SIZE / CONN_BLE_BUFFER_SIZE);
444 buffer_size = BLE_MODE_CONN_MAX_PACKET_SIZE;
445 memcpy(buf_len, &buffer_size, 2);
446 memcpy(num_buf, &packet_buffers, 2);
447 return BLE_RESULT_OK;
451 set_adv_param(
unsigned int adv_int, ble_adv_type_t type,
452 ble_addr_type_t own_type,
unsigned short adv_map)
454 adv_param.adv_interval = adv_int;
455 adv_param.adv_type = type;
456 adv_param.own_addr_type = own_type;
457 adv_param.channel_map = adv_map;
459 LOG_INFO(
"advertising parameter: interval: %4d, channels: %2d\n",
460 adv_param.adv_interval, adv_param.channel_map);
462 LOG_DBG(
"interval: %16u (ms)\n", adv_param.adv_interval);
463 LOG_DBG(
"type: %16u\n", adv_param.adv_type);
464 LOG_DBG(
"addr_type:%16u\n", adv_param.own_addr_type);
465 LOG_DBG(
"channels: %16u\n", adv_param.channel_map);
467 return BLE_RESULT_OK;
471 read_adv_channel_tx_power(
short *power)
473 return BLE_RESULT_NOT_SUPPORTED;
477 set_adv_data(
unsigned short data_len,
char *data)
479 if(data_len > BLE_ADV_DATA_LEN) {
480 LOG_WARN(
"BLE-HAL: adv_data too long\n");
481 return BLE_RESULT_INVALID_PARAM;
483 adv_param.adv_data_len = data_len;
484 memcpy(adv_param.adv_data, data, data_len);
485 return BLE_RESULT_OK;
489 set_scan_resp_data(
unsigned short data_len,
char *data)
491 if(data_len > BLE_SCAN_RESP_DATA_LEN) {
492 LOG_WARN(
"BLE-HAL: scan_resp_data too long\n");
493 return BLE_RESULT_INVALID_PARAM;
495 adv_param.scan_rsp_data_len = data_len;
496 memcpy(adv_param.scan_rsp_data, data, data_len);
497 return BLE_RESULT_OK;
501 set_adv_enable(
unsigned short enable)
504 if((enable) && (!adv_param.active)) {
505 adv_param.start_rt = now + ticks_from_unit(adv_param.adv_interval,
507 rtimer_set(&adv_param.timer, adv_param.start_rt,
508 0, advertising_event, (
void *)&adv_param);
510 return BLE_RESULT_OK;
514 send_frame(ble_conn_param_t *conn, uint8_t *data, uint8_t data_len, uint8_t frame_type)
516 uint8_t *tx_buffer = tx_queue_get_buffer(conn);
517 if(tx_buffer == NULL) {
518 LOG_WARN(
"BLE-HAL: send_frame: no TX buffer available (conn_handle: 0x%04X)\n", conn->conn_handle);
519 return BLE_RESULT_ERROR;
521 if(data_len > CONN_BLE_BUFFER_SIZE) {
522 LOG_WARN(
"BLE-HAL: send_frame: data too long (%d bytes)\n", data_len);
523 return BLE_RESULT_ERROR;
526 memcpy(TX_ENTRY_DATA_PTR(tx_buffer), data, data_len);
527 TX_ENTRY_LENGTH(tx_buffer) = data_len + 1;
528 TX_ENTRY_STATUS(tx_buffer) = DATA_ENTRY_QUEUED;
529 TX_ENTRY_FRAME_TYPE(tx_buffer) = frame_type;
530 return BLE_RESULT_OK;
534 connection_update(
unsigned int connection_handle,
unsigned int conn_interval,
535 unsigned int conn_latency,
unsigned int supervision_timeout)
539 ble_conn_param_t *conn = get_connection_for_handle(connection_handle);
542 return BLE_RESULT_ERROR;
545 LOG_INFO(
"connection_update: handle: 0x%04X, interval: %4d, latency: %2d, timeout: %4d\n",
546 connection_handle, conn_interval, conn_latency, supervision_timeout);
548 uint16_t instant = conn->counter + CONN_UPDATE_DELAY;
550 data[0] = BLE_LL_CONN_UPDATE_REQ;
551 data[1] = conn->win_size;
554 memcpy(&data[4], &conn_interval, 2);
555 memcpy(&data[6], &conn_latency, 2);
556 memcpy(&data[8], &supervision_timeout, 2);
557 memcpy(&data[10], &instant, 2);
560 conn->conn_update_win_size = conn->win_size;
561 conn->conn_update_interval = conn_interval;
562 conn->conn_update_latency = conn_latency;
563 conn->conn_update_timeout = supervision_timeout;
564 conn->conn_update_counter = instant;
566 if(send_frame(conn, data, len, BLE_DATA_PDU_LLID_CONTROL) != BLE_RESULT_OK) {
567 LOG_ERR(
"connection_update: send frame was NOT successful\n");
568 return BLE_RESULT_ERROR;
571 data[0] = BLE_LL_CONN_PARAM_REQ;
572 memcpy(&data[1], &conn_interval, 2);
573 memcpy(&data[3], &conn_interval, 2);
574 memcpy(&data[5], &conn_latency, 2);
575 memcpy(&data[7], &supervision_timeout, 2);
576 memcpy(&data[9], &conn_interval, 1);
577 memcpy(&data[10], &conn->counter, 2);
578 memset(&data[12], 0xFF, 12);
581 if(send_frame(conn, data, len, BLE_DATA_PDU_LLID_CONTROL) != BLE_RESULT_OK) {
582 LOG_ERR(
"connection_update: send frame was NOT successful\n");
583 return BLE_RESULT_ERROR;
586 return BLE_RESULT_OK;
590 send(
void *buf,
unsigned short buf_len)
594 ble_conn_param_t *conn;
597 linkaddr_t dest_addr;
598 linkaddr_t conn_addr;
601 linkaddr_copy(&dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
603 LOG_DBG(
"ble-hal: sending %d bytes\n", buf_len);
605 for(loop_conn = 0; loop_conn < conn_counter; loop_conn++) {
606 conn = &conn_param[loop_conn];
609 for(loop_data = 0; loop_data < buf_len; loop_data += CONN_BLE_BUFFER_SIZE) {
610 data = &((uint8_t *)buf)[loop_data];
611 data_len = MIN((buf_len - loop_data), CONN_BLE_BUFFER_SIZE);
613 result = send_frame(conn, data, data_len, BLE_DATA_PDU_LLID_DATA_MESSAGE);
615 result = send_frame(conn, data, data_len, BLE_DATA_PDU_LLID_DATA_FRAGMENT);
617 if(result != BLE_RESULT_OK) {
618 LOG_WARN(
"ble-hal: send was unsuccessful\n");
624 return BLE_RESULT_OK;
628 read_connection_interval(
unsigned int conn_handle,
unsigned int *conn_interval)
630 ble_conn_param_t *conn = get_connection_for_handle(conn_handle);
632 memset(conn_interval, 0x00,
sizeof(uint16_t));
633 return BLE_RESULT_ERROR;
635 memcpy(conn_interval, &conn->interval,
sizeof(uint16_t));
636 return BLE_RESULT_OK;
657 read_connection_interval
661 advertising_rx(ble_adv_param_t *param)
666 ble_conn_param_t *c_param = &conn_param[0];
667 rtimer_clock_t wakeup;
669 while(RX_ENTRY_STATUS(param->rx_queue_current) == DATA_ENTRY_FINISHED) {
670 rx_data = RX_ENTRY_DATA_PTR(param->rx_queue_current);
672 if(CMD_GET_STATUS(param->cmd_buf) == RF_CORE_RADIO_OP_STATUS_BLE_DONE_CONNECT) {
674 for(i = 0; i < BLE_ADDR_SIZE; i++) {
675 c_param->peer_address[i] = rx_data[BLE_ADDR_SIZE + 1 - i];
677 memcpy(&c_param->access_address, &rx_data[offset], 4);
678 memcpy(&c_param->crc_init_0, &rx_data[offset + 4], 1);
679 memcpy(&c_param->crc_init_1, &rx_data[offset + 5], 1);
680 memcpy(&c_param->crc_init_2, &rx_data[offset + 6], 1);
681 memcpy(&c_param->win_size, &rx_data[offset + 7], 1);
682 memcpy(&c_param->win_offset, &rx_data[offset + 8], 2);
683 memcpy(&c_param->interval, &rx_data[offset + 10], 2);
684 memcpy(&c_param->latency, &rx_data[offset + 12], 2);
685 memcpy(&c_param->timeout, &rx_data[offset + 14], 2);
686 memcpy(&c_param->channel_map, &rx_data[offset + 16], 5);
687 memcpy(&c_param->hop, &rx_data[offset + 21], 1);
688 memcpy(&c_param->sca, &rx_data[offset + 21], 1);
689 memcpy(&c_param->timestamp_rt, &rx_data[offset + 24], 4);
693 c_param->timestamp_rt = ticks_from_unit(c_param->timestamp_rt, TIME_UNIT_RF_CORE);
694 c_param->hop = c_param->hop & 0x1F;
695 c_param->sca = (c_param->sca >> 5) & 0x07;
697 LOG_INFO(
"connection created: conn_int: %4u, latency: %3u, channel_map: %8llX\n",
698 c_param->interval, c_param->latency, c_param->channel_map);
700 LOG_DBG(
"access address: 0x%08lX\n", c_param->access_address);
701 LOG_DBG(
"crc0: 0x%02X\n", c_param->crc_init_0);
702 LOG_DBG(
"crc1: 0x%02X\n", c_param->crc_init_1);
703 LOG_DBG(
"crc2: 0x%02X\n", c_param->crc_init_2);
704 LOG_DBG(
"win_size: %4u\n", c_param->win_size);
705 LOG_DBG(
"win_offset: %4u\n", c_param->win_offset);
706 LOG_DBG(
"interval: %4u\n", c_param->interval);
707 LOG_DBG(
"latency: %4u\n", c_param->latency);
708 LOG_DBG(
"timeout: %4u\n", c_param->timeout);
709 LOG_DBG(
"channel_map: %llX\n", c_param->channel_map);
713 wakeup = c_param->timestamp_rt + ticks_from_unit(c_param->win_offset, TIME_UNIT_1_25_MS) - CONN_WINDOW_WIDENING_TICKS;
714 wakeup += ticks_from_unit(c_param->interval, TIME_UNIT_1_25_MS) - CONN_PREPROCESSING_TIME_TICKS;
715 rtimer_set(&c_param->timer, wakeup, 0, connection_event_slave, (
void *)c_param);
718 c_param->counter = 0;
719 c_param->unmapped_channel = 0;
720 c_param->conn_handle = conn_counter;
723 LOG_INFO(
"BLE-HAL: connection (0x%04X) created\n", c_param->conn_handle);
727 RX_ENTRY_DATA_LENGTH(param->rx_queue_current) = 0;
728 RX_ENTRY_STATUS(param->rx_queue_current) = DATA_ENTRY_PENDING;
729 param->rx_queue_current = RX_ENTRY_NEXT_ENTRY(param->rx_queue_current);
734 advertising_event(
struct rtimer *t,
void *ptr)
736 ble_adv_param_t *param = (ble_adv_param_t *)ptr;
739 if(
on() != BLE_RESULT_OK) {
740 LOG_ERR(
"BLE-HAL: advertising event: could not enable rf core\n");
745 param->adv_data_len, param->adv_data,
746 param->scan_rsp_data_len, param->scan_rsp_data,
747 param->own_addr_type, (uint8_t *)BLE_ADDR_LOCATION);
750 if(param->channel_map & BLE_ADV_CHANNEL_1_MASK) {
752 param->param_buf, param->output_buf);
758 advertising_rx(param);
760 if(conn_param[0].active == 1) {
761 LOG_INFO(
"stop advertising\n");
765 param->start_rt = param->start_rt + ticks_from_unit(param->adv_interval, TIME_UNIT_MS);
766 wakeup = adv_param.start_rt - ADV_PREPROCESSING_TIME_TICKS;
767 rtimer_set(¶m->timer, wakeup, 0, advertising_event, (
void *)param);
771 update_data_channel(ble_conn_param_t *param)
779 param->unmapped_channel = (param->unmapped_channel + param->hop) % (BLE_DATA_CHANNEL_MAX + 1);
782 if(param->channel_map & (1ULL << param->unmapped_channel)) {
784 param->mapped_channel = param->unmapped_channel;
786 remap_index = param->unmapped_channel % param->num_used_channels;
788 for(i = 0; i < (BLE_DATA_CHANNEL_MAX + 1); i++) {
789 if(param->channel_map & (1ULL << i)) {
790 if(j == remap_index) {
791 param->mapped_channel = i;
800 process_ll_ctrl_msg(ble_conn_param_t *conn, uint8_t input_len, uint8_t *
input, uint8_t *output_len, uint8_t *
output)
802 uint8_t op_code = input[0];
806 uint64_t channel_map = 0;
807 uint16_t instant = 0;
810 if(op_code == BLE_LL_CONN_UPDATE_REQ) {
811 LOG_INFO(
"BLE-HAL: connection update request received\n");
812 memcpy(&conn->conn_update_win_size, &input[1], 1);
813 memcpy(&conn->conn_update_win_offset, &input[2], 2);
814 memcpy(&conn->conn_update_interval, &input[4], 2);
815 memcpy(&conn->conn_update_latency, &input[6], 2);
816 memcpy(&conn->conn_update_timeout, &input[8], 2);
817 memcpy(&conn->conn_update_counter, &input[10], 2);
818 }
else if(op_code == BLE_LL_CHANNEL_MAP_REQ) {
819 LOG_INFO(
"BLE-HAL: channel map update received\n");
820 memcpy(&channel_map, &input[1], 5);
821 memcpy(&instant, &input[6], 2);
823 conn->channel_update_channel_map = channel_map;
824 conn->channel_update_counter = instant;
825 conn->channel_update_num_used_channels = 0;
826 for(i = 0; i <= BLE_DATA_CHANNEL_MAX; i++) {
827 if(channel_map & (1ULL << i)) {
828 conn->channel_update_num_used_channels++;
831 }
else if(op_code == BLE_LL_FEATURE_REQ) {
832 LOG_INFO(
"BLE-HAL: feature request received\n");
833 output[0] = BLE_LL_FEATURE_RSP;
834 memset(&output[1], 0x00, 8);
836 }
else if(op_code == BLE_LL_VERSION_IND) {
837 LOG_INFO(
"BLE-HAL: version request received\n");
838 output[0] = BLE_LL_VERSION_IND;
840 memset(&output[2], 0xAA, 4);
842 }
else if(op_code == BLE_LL_CONN_PARAM_REQ) {
843 LOG_INFO(
"BLE-HAL: connection parameter request received\n");
844 memcpy(&interval, &input[1], 2);
845 memcpy(&latency, &input[5], 2);
846 memcpy(&timeout, &input[7], 2);
849 LOG_WARN(
"BLE-HAL: unknown LL control code: %02X\n", op_code);
854 connection_rx(ble_conn_param_t *param)
856 uint8_t header_offset = 2;
863 linkaddr_t sender_addr;
864 rfc_bleMasterSlaveOutput_t *out_buf = (rfc_bleMasterSlaveOutput_t *)param->output_buf;
866 uint8_t output_len = 0;
869 while(RX_ENTRY_STATUS(param->rx_queue_current) == DATA_ENTRY_FINISHED) {
870 rx_data = RX_ENTRY_DATA_PTR(param->rx_queue_current);
872 len = RX_ENTRY_DATA_LENGTH(param->rx_queue_current) - 7 - 2;
874 len = RX_ENTRY_DATA_LENGTH(param->rx_queue_current) - 6 - 2;
876 channel = (rx_data[len + 3] & 0x3F);
877 frame_type = rx_data[0] & 0x03;
878 more_data = (rx_data[0] & 0x10) >> 4;
880 if(frame_type == BLE_DATA_PDU_LLID_CONTROL) {
881 process_ll_ctrl_msg(param, (len - header_offset), &rx_data[header_offset], &output_len, output);
883 send_frame(param, output, output_len, BLE_DATA_PDU_LLID_CONTROL);
885 }
else if(frame_type == BLE_DATA_PDU_LLID_DATA_MESSAGE) {
889 rssi = out_buf->lastRssi;
891 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
892 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, channel);
894 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &sender_addr);
895 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME_BLE_RX_EVENT);
896 if((!more_data) || (len < CONN_BLE_BUFFER_SIZE)) {
897 NETSTACK_MAC.
input();
899 }
else if(frame_type == BLE_DATA_PDU_LLID_DATA_FRAGMENT) {
902 if((!more_data) || (len < CONN_BLE_BUFFER_SIZE)) {
903 NETSTACK_MAC.
input();
908 RX_ENTRY_DATA_LENGTH(param->rx_queue_current) = 0;
909 RX_ENTRY_STATUS(param->rx_queue_current) = DATA_ENTRY_PENDING;
910 param->rx_queue_current = RX_ENTRY_NEXT_ENTRY(param->rx_queue_current);
915 connection_event_slave(
struct rtimer *t,
void *ptr)
918 ble_conn_param_t *conn = (ble_conn_param_t *)ptr;
919 rfc_bleMasterSlaveOutput_t *output = (rfc_bleMasterSlaveOutput_t *)conn->output_buf;
920 uint8_t first_packet = 0;
921 rtimer_clock_t wakeup;
923 uint8_t tx_data = tx_queue_data_to_transmit(conn);
925 if(conn->counter == 0) {
927 conn->start_rt = conn->timestamp_rt + ticks_from_unit(conn->win_offset, TIME_UNIT_1_25_MS) - CONN_WINDOW_WIDENING_TICKS;
928 update_data_channel(conn);
934 if(conn->counter == conn->conn_update_counter) {
935 conn->start_rt += ticks_from_unit(conn->interval + conn->conn_update_win_offset, TIME_UNIT_1_25_MS);
937 conn->win_size = conn->conn_update_win_size;
938 conn->win_offset = conn->conn_update_win_offset;
939 conn->interval = conn->conn_update_interval;
940 conn->latency = conn->conn_update_latency;
941 conn->timeout = conn->conn_update_timeout;
942 conn->conn_update_win_size = 0;
943 conn->conn_update_win_offset = 0;
944 conn->conn_update_interval = 0;
945 conn->conn_update_latency = 0;
946 conn->conn_update_timeout = 0;
947 }
else if(output->pktStatus.bTimeStampValid) {
948 conn->start_rt = ticks_from_unit(output->timeStamp, TIME_UNIT_RF_CORE) +
949 ticks_from_unit(conn->interval, TIME_UNIT_1_25_MS) - CONN_WINDOW_WIDENING_TICKS;
951 conn->start_rt += ticks_from_unit(conn->interval, TIME_UNIT_1_25_MS);
955 if(conn->channel_update_counter == conn->counter) {
956 conn->channel_map = conn->channel_update_channel_map;
957 conn->num_used_channels = conn->channel_update_num_used_channels;
958 conn->channel_update_counter = 0;
959 conn->channel_update_channel_map = 0;
960 conn->channel_update_num_used_channels = 0;
962 update_data_channel(conn);
964 if(tx_data || (conn->skipped_events >= conn->latency) || (conn->counter < CONN_EVENT_LATENCY_THRESHOLD)) {
966 conn->skipped_events = 0;
968 conn->crc_init_0, conn->crc_init_1, conn->crc_init_2,
969 ticks_to_unit(ticks_from_unit(conn->win_size, TIME_UNIT_1_25_MS), TIME_UNIT_RF_CORE),
970 ticks_to_unit(CONN_WINDOW_WIDENING_TICKS, TIME_UNIT_RF_CORE), first_packet);
973 ticks_to_unit(conn->start_rt, TIME_UNIT_RF_CORE));
975 if(
on() != BLE_RESULT_OK) {
976 LOG_ERR(
"connection_event: could not enable radio core\n");
981 for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
982 if(TX_ENTRY_STATUS(conn->tx_buffers[i]) == DATA_ENTRY_QUEUED) {
983 TX_ENTRY_STATUS(conn->tx_buffers[i]) = DATA_ENTRY_PENDING;
991 if(CMD_GET_STATUS(conn->cmd_buf) != RF_CORE_RADIO_OP_STATUS_BLE_DONE_OK) {
992 LOG_DBG(
"command status: 0x%04X; connection event counter: %d, channel: %d\n",
993 CMD_GET_STATUS(conn->cmd_buf), conn->counter, conn->mapped_channel);
997 for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
998 if(TX_ENTRY_STATUS(conn->tx_buffers[i]) == DATA_ENTRY_FINISHED) {
999 TX_ENTRY_STATUS(conn->tx_buffers[i]) = DATA_ENTRY_FREE;
1000 TX_ENTRY_LENGTH(conn->tx_buffers[i]) = 0;
1001 TX_ENTRY_NEXT_ENTRY(conn->tx_buffers[i]) = NULL;
1006 conn->skipped_events++;
1007 output->pktStatus.bTimeStampValid = 0;
1009 wakeup = conn->start_rt + ticks_from_unit(conn->interval, TIME_UNIT_1_25_MS) - CONN_PREPROCESSING_TIME_TICKS;
1010 rtimer_set(&conn->timer, wakeup, 0, connection_event_slave, ptr);
1011 process_post(&ble_hal_conn_rx_process, rx_data_event, ptr);
1015 ble_conn_param_t *conn = (ble_conn_param_t *)data;
1016 rfc_bleMasterSlaveOutput_t *output = (rfc_bleMasterSlaveOutput_t *)conn->output_buf;
1017 uint8_t tx_buffers_sent;
1019 LOG_DBG(
"BLE-HAL: conn rx process start\n");
1024 tx_buffers_sent = output->nTxEntryDone - conn->tx_buffers_sent;
1025 if(tx_buffers_sent != 0) {
1026 conn->tx_buffers_sent = output->nTxEntryDone;
1028 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME_BLE_TX_EVENT);
1029 NETSTACK_MAC.
input();
1033 connection_rx(conn);
1036 if(conn->counter == conn->conn_update_counter) {
1038 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME_BLE_CONNECTION_UPDATED);
1039 NETSTACK_MAC.
input();
void oscillators_request_hf_xosc(void)
Requests the HF XOSC as the source for the HF clock, but does not perform the actual switch...
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
ble_result_t(* reset)(void)
Resets the BLE controller.
int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr)
Post a real-time task.
#define PROCESS(name, strname)
Declare a process.
Representation of a real-time task.
Header file with macros which rename TI CC26xxware functions.
void packetbuf_clear(void)
Clear and reset the packetbuf.
void rf_ble_cmd_create_adv_params(uint8_t *param, dataQueue_t *rx_queue, uint8_t adv_data_len, uint8_t *adv_data, uint8_t scan_resp_data_len, uint8_t *scan_resp_data, ble_addr_type_t own_addr_type, uint8_t *own_addr)
Creates BLE radio command parameters that are used to enable BLE advertisement on the radio core...
int process_is_running(struct process *p)
Check if a process is running.
ble_result_t(* set_adv_enable)(unsigned short enable)
Enables/disables advertising.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_END()
Define the end of a process.
int rf_core_power_up()
Turn on power to the RFC and boot it.
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
The structure of a ble radio controller driver in Contiki.
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Header file with declarations for the I/O Control module.
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
ble_result_t(* read_adv_channel_tx_power)(short *power)
Reads the used power on the advertisement channels.
void ble_addr_cpy_to(uint8_t *dst)
Copy the node's factory BLE address to a destination memory area.
unsigned short rf_ble_cmd_send(uint8_t *command)
Sends a BLE radio command to the radio.
Header file for the CC13xx/CC26xx RF core driver.
const linkaddr_t linkaddr_null
The null link-layer address.
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
BLE commands for the TI CC26xx BLE radio.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
#define RTIMER_NOW()
Get the current clock time.
Header file for the CC13xx/CC26xx oscillator control.
unsigned short rf_ble_cmd_setup_ble_mode(void)
Initializes the radio core to be used as a BLE radio.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
void(* input)(void)
Callback for getting notified of incoming packet.
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
hardware abstraction for a BLE controller
void rf_ble_cmd_create_slave_params(uint8_t *params, dataQueue_t *rx_queue, dataQueue_t *tx_queue, uint32_t access_address, uint8_t crc_init_0, uint8_t crc_init_1, uint8_t crc_init_2, uint32_t win_size, uint32_t window_widening, uint8_t first_packet)
Creates BLE radio command parameters that are used to setup a single BLE connection event on the radi...
int(* off)(void)
Turn the radio off.
ble_result_t(* set_adv_data)(unsigned short data_len, char *data)
Sets the advertising data.
Header file for the real-time timer module.
ble_result_t(* set_adv_param)(unsigned int adv_interval, ble_adv_type_t type, ble_addr_type_t own_addr_type, unsigned short adv_channel_map)
Sets the parameter for advertising.
Header file for the Contiki process interface.
ble_result_t(* read_bd_addr)(uint8_t *addr)
Reads the static BLE device address.
ble_result_t(* read_buffer_size)(unsigned int *buf_len, unsigned int *num_buf)
Reads the size of the data buffers.
unsigned short rf_ble_cmd_wait(uint8_t *command)
Waits for a running BLE radio command to be finished.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
process_event_t process_alloc_event(void)
Allocate a global event number.
unsigned short rf_ble_cmd_add_data_queue_entry(dataQueue_t *q, uint8_t *e)
Adds a data buffer to a BLE transmission queue.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
void ble_addr_to_eui64(uint8_t *dst, uint8_t *src)
Copy the node's BLE address to a destination memory area and converts it into a EUI64 address in the ...
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Header file for the Packet buffer (packetbuf) management
void rf_ble_cmd_create_slave_cmd(uint8_t *cmd, uint8_t channel, uint8_t *params, uint8_t *output, uint32_t start_time)
Creates a BLE radio command structure that sets up a single BLE connection event when sent to the rad...
#define LPM_MODULE(n, m, s, w, l)
Declare a variable to be used in order to get notifications from LPM.
void rf_core_setup_interrupts(void)
Setup RF core interrupts.
Include file for the Contiki low-layer network stack (NETSTACK)
uint8_t rf_core_start_rat(void)
Start the CM0 RAT.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Header file for the logging system
static void input(void)
Process a received 6lowpan packet.
void rf_ble_cmd_create_adv_cmd(uint8_t *command, uint8_t channel, uint8_t *param, uint8_t *output)
Creates a BLE radio command structure that enables BLE advertisement when sent to the radio core...
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
ble_result_t(* connection_update)(unsigned int connection_handle, unsigned int conn_interval, unsigned int conn_latency, unsigned int supervision_timeout)
Updates the connection parameters.
int(* on)(void)
Turn the radio on.
void process_start(struct process *p, process_data_t data)
Start a process.
void lpm_register_module(lpm_registered_module_t *module)
Register a module for LPM notifications.
ble_result_t(* set_scan_resp_data)(unsigned short data_len, char *data)
Sets the scan response data.