Contiki-NG
rf-ble-cmd.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, Graz University of Technology
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /**
32  * \file
33  * BLE commands for the TI CC26xx BLE radio.
34  * These functions are specific to the TI CC26xx and cannot be
35  * reused by other BLE radios.
36  *
37  * \author
38  * Michael Spoerk <michael.spoerk@tugraz.at>
39  */
40 /*---------------------------------------------------------------------------*/
41 #include "contiki.h"
42 
43 #include "rf_ble_cmd.h"
44 #include "rf-core/rf-core.h"
46 
47 /*---------------------------------------------------------------------------*/
48 #include "sys/log.h"
49 #define LOG_MODULE "BLE-RADIO"
50 #define LOG_LEVEL LOG_LEVEL_MAIN
51 /*---------------------------------------------------------------------------*/
52 #define CMD_GET_STATUS(X) (((rfc_radioOp_t *)X)->status)
53 /*---------------------------------------------------------------------------*/
54 /* values for a selection of available TX powers (values from SmartRF Studio) */
55 /*static uint16_t tx_power = 0x9330; / * +5 dBm * / */
56 static uint16_t tx_power = 0x3161; /* 0 dBm */
57 /*static uint16_t tx_power = 0x0CCB; / * -15 dBm * / */
58 /*---------------------------------------------------------------------------*/
59 /* BLE overrides */
60 static uint32_t ble_overrides[] = {
61  0x00364038, /* Synth: Set RTRIM (POTAILRESTRIM) to 6 */
62  0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */
63  0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */
64  0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */
65  0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */
66  0x00456088, /* Adjust AGC reference level */
67  0x008F88B3, /* GPIO mode: https://e2e.ti.com/support/wireless_connectivity/proprietary_sub_1_ghz_simpliciti/f/156/t/488244?*/
68  0xFFFFFFFF, /* End of override list */
69 };
70 /*---------------------------------------------------------------------------*/
71 unsigned short
72 rf_ble_cmd_send(uint8_t *command)
73 {
74  uint32_t cmdsta;
75  rfc_radioOp_t *cmd = (rfc_radioOp_t *)command;
76 
77  if(rf_core_send_cmd((uint32_t)cmd, &cmdsta) != RF_CORE_CMD_OK) {
78  LOG_ERR("rf_ble_cmd_send() could not send cmd. status: 0x%04X\n",
79  CMD_GET_STATUS(cmd));
80  return RF_BLE_CMD_ERROR;
81  }
82  return RF_BLE_CMD_OK;
83 }
84 /*---------------------------------------------------------------------------*/
85 unsigned short
86 rf_ble_cmd_wait(uint8_t *command)
87 {
88  rfc_radioOp_t *cmd = (rfc_radioOp_t *)command;
89  if(rf_core_wait_cmd_done((void *)cmd) != RF_CORE_CMD_OK) {
90  LOG_ERR("rf_ble_cmd_wait() could not wait. status: 0x%04X\n",
91  CMD_GET_STATUS(cmd));
92  return RF_BLE_CMD_ERROR;
93  }
94  return RF_BLE_CMD_OK;
95 }
96 /*---------------------------------------------------------------------------*/
97 unsigned short
99 {
100  rfc_CMD_RADIO_SETUP_t cmd;
101 
102  /* Create radio setup command */
103  rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_RADIO_SETUP);
104 
105  cmd.txPower = tx_power;
106  cmd.pRegOverride = ble_overrides;
107  cmd.mode = 0;
108 
109  /* Send Radio setup to RF Core */
110  if(rf_ble_cmd_send((uint8_t *)&cmd) != RF_BLE_CMD_OK) {
111  return RF_BLE_CMD_ERROR;
112  }
113 
114  /* Wait until radio setup is done */
115  return rf_ble_cmd_wait((uint8_t *)&cmd);
116 }
117 /*---------------------------------------------------------------------------*/
118 /* ADVERTISING functions */
119 void
120 rf_ble_cmd_create_adv_cmd(uint8_t *command, uint8_t channel,
121  uint8_t *param, uint8_t *output)
122 {
123  rfc_CMD_BLE_ADV_t *c = (rfc_CMD_BLE_ADV_t *)command;
124 
125  memset(c, 0x00, sizeof(rfc_CMD_BLE_ADV_t));
126  c->commandNo = CMD_BLE_ADV;
127  c->condition.rule = COND_NEVER;
128  c->whitening.bOverride = 0;
129  c->channel = channel;
130  c->pParams = (rfc_bleAdvPar_t *)param;
131  c->startTrigger.triggerType = TRIG_NOW;
132  c->pOutput = (rfc_bleAdvOutput_t *)output;
133 }
134 /*---------------------------------------------------------------------------*/
135 void
136 rf_ble_cmd_create_adv_params(uint8_t *param, dataQueue_t *rx_queue,
137  uint8_t adv_data_len, uint8_t *adv_data,
138  uint8_t scan_resp_data_len, uint8_t *scan_resp_data,
139  ble_addr_type_t own_addr_type, uint8_t *own_addr)
140 {
141  rfc_bleAdvPar_t *p = (rfc_bleAdvPar_t *)param;
142 
143  memset(p, 0x00, sizeof(rfc_bleAdvPar_t));
144 
145  p->pRxQ = rx_queue;
146  p->rxConfig.bAutoFlushIgnored = 1;
147  p->rxConfig.bAutoFlushCrcErr = 0;
148  p->rxConfig.bAutoFlushEmpty = 1;
149  p->rxConfig.bIncludeLenByte = 1;
150  p->rxConfig.bIncludeCrc = 0;
151  p->rxConfig.bAppendRssi = 1;
152  p->rxConfig.bAppendStatus = 1;
153  p->rxConfig.bAppendTimestamp = 1;
154  p->advConfig.advFilterPolicy = 0;
155  p->advConfig.bStrictLenFilter = 0;
156  p->advConfig.deviceAddrType = own_addr_type;
157  p->pDeviceAddress = (uint16_t *)own_addr;
158  p->advLen = adv_data_len;
159  p->scanRspLen = scan_resp_data_len;
160  p->pAdvData = adv_data;
161  p->pScanRspData = scan_resp_data;
162  p->endTrigger.triggerType = TRIG_NEVER;
163 }
164 /*---------------------------------------------------------------------------*/
165 /* CONNECTION slave functions */
166 /*---------------------------------------------------------------------------*/
167 void
168 rf_ble_cmd_create_slave_cmd(uint8_t *cmd, uint8_t channel, uint8_t *params,
169  uint8_t *output, uint32_t start_time)
170 {
171  rfc_CMD_BLE_SLAVE_t *c = (rfc_CMD_BLE_SLAVE_t *)cmd;
172 
173  memset(c, 0x00, sizeof(rfc_CMD_BLE_SLAVE_t));
174 
175  c->commandNo = CMD_BLE_SLAVE;
176  c->condition.rule = COND_NEVER;
177  c->whitening.bOverride = 0;
178  c->channel = channel;
179  c->pParams = (rfc_bleSlavePar_t *)params;
180  c->startTrigger.triggerType = TRIG_ABSTIME;
181  c->startTrigger.pastTrig = 0;
182  c->startTime = start_time;
183  c->pOutput = (rfc_bleMasterSlaveOutput_t *)output;
184 }
185 /*---------------------------------------------------------------------------*/
186 void
187 rf_ble_cmd_create_slave_params(uint8_t *params, dataQueue_t *rx_queue,
188  dataQueue_t *tx_queue, uint32_t access_address,
189  uint8_t crc_init_0, uint8_t crc_init_1,
190  uint8_t crc_init_2, uint32_t win_size,
191  uint32_t window_widening, uint8_t first_packet)
192 {
193  rfc_bleSlavePar_t *p = (rfc_bleSlavePar_t *)params;
194 
195  p->pRxQ = rx_queue;
196  p->pTxQ = tx_queue;
197  p->rxConfig.bAutoFlushIgnored = 1;
198  p->rxConfig.bAutoFlushCrcErr = 1;
199  p->rxConfig.bAutoFlushEmpty = 1;
200  p->rxConfig.bIncludeLenByte = 1;
201  p->rxConfig.bIncludeCrc = 0;
202  p->rxConfig.bAppendRssi = 1;
203  p->rxConfig.bAppendStatus = 1;
204  p->rxConfig.bAppendTimestamp = 1;
205 
206  if(first_packet) {
207  /* set parameters for first packet according to TI Technical Reference Manual */
208  p->seqStat.lastRxSn = 1;
209  p->seqStat.lastTxSn = 1;
210  p->seqStat.nextTxSn = 0;
211  p->seqStat.bFirstPkt = 1;
212  p->seqStat.bAutoEmpty = 0;
213  p->seqStat.bLlCtrlTx = 0;
214  p->seqStat.bLlCtrlAckRx = 0;
215  p->seqStat.bLlCtrlAckPending = 0;
216  }
217 
218  p->maxNack = 0;
219  p->maxPkt = 0;
220  p->accessAddress = access_address;
221  p->crcInit0 = crc_init_0;
222  p->crcInit1 = crc_init_1;
223  p->crcInit2 = crc_init_2;
224  p->timeoutTrigger.triggerType = TRIG_REL_START;
225  if(first_packet) {
226  p->timeoutTime = (uint32_t)(10 * win_size);
227  } else {
228  p->timeoutTime = (uint32_t)(win_size + 2 * window_widening);
229  }
230  p->endTrigger.triggerType = TRIG_NEVER;
231 }
232 /*---------------------------------------------------------------------------*/
233 /* DATA queue functions */
234 /*---------------------------------------------------------------------------*/
235 unsigned short
236 rf_ble_cmd_add_data_queue_entry(dataQueue_t *q, uint8_t *e)
237 {
238  uint32_t cmdsta;
239 
240  rfc_CMD_ADD_DATA_ENTRY_t cmd;
241  cmd.commandNo = CMD_ADD_DATA_ENTRY;
242  cmd.pQueue = q;
243  cmd.pEntry = e;
244 
245  if(rf_core_send_cmd((uint32_t)&cmd, &cmdsta) != RF_CORE_CMD_OK) {
246  LOG_ERR("could not add entry to data queue. status: 0x%04X\n",
247  CMD_GET_STATUS(&cmd));
248  return RF_BLE_CMD_ERROR;
249  }
250  return RF_BLE_CMD_OK;
251 }
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...
Definition: rf-ble-cmd.c:136
unsigned short rf_ble_cmd_send(uint8_t *command)
Sends a BLE radio command to the radio.
Definition: rf-ble-cmd.c:72
Header file for the CC13xx/CC26xx RF core driver.
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.
Definition: sicslowpan.c:1549
BLE commands for the TI CC26xx BLE radio.
unsigned short rf_ble_cmd_setup_ble_mode(void)
Initializes the radio core to be used as a BLE radio.
Definition: rf-ble-cmd.c:98
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...
Definition: rf-ble-cmd.c:187
void rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command)
Prepare a buffer to host a Radio Op.
Definition: rf-core.c:506
unsigned short rf_ble_cmd_wait(uint8_t *command)
Waits for a running BLE radio command to be finished.
Definition: rf-ble-cmd.c:86
unsigned short rf_ble_cmd_add_data_queue_entry(dataQueue_t *q, uint8_t *e)
Adds a data buffer to a BLE transmission queue.
Definition: rf-ble-cmd.c:236
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
Definition: rf-core.c:129
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...
Definition: rf-ble-cmd.c:168
Header file for the logging system
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...
Definition: rf-ble-cmd.c:120
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.
Definition: rf-core.c:195