42 #include "sys/clock.h" 51 #include "driverlib/rf_ble_cmd.h" 52 #include "driverlib/rf_common_cmd.h" 61 #define PRINTF(...) printf(__VA_ARGS__) 67 #define BLE_ADV_INTERVAL (CLOCK_SECOND * 5) 68 #define BLE_ADV_DUTY_CYCLE (CLOCK_SECOND / 10) 69 #define BLE_ADV_MESSAGES 10 72 #define BLE_ADV_TYPE_DEVINFO 0x01 73 #define BLE_ADV_TYPE_NAME 0x09 74 #define BLE_ADV_TYPE_MANUFACTURER 0xFF 75 #define BLE_ADV_NAME_BUF_LEN BLE_ADV_MAX_SIZE 76 #define BLE_ADV_PAYLOAD_BUF_LEN 64 77 #define BLE_UUID_SIZE 16 79 static unsigned char ble_params_buf[32] CC_ALIGN(4);
80 static uint8_t ble_mode_on = RF_BLE_IDLE;
81 static struct etimer ble_adv_et;
82 static uint8_t payload[BLE_ADV_PAYLOAD_BUF_LEN];
87 static struct ble_beacond_config {
88 clock_time_t interval;
89 char adv_name[BLE_ADV_NAME_BUF_LEN];
90 } beacond_config = { .interval = BLE_ADV_INTERVAL };
92 #ifdef RF_BLE_CONF_BOARD_OVERRIDES 93 #define RF_BLE_BOARD_OVERRIDES RF_BLE_CONF_BOARD_OVERRIDES 95 #define RF_BLE_BOARD_OVERRIDES 99 static uint32_t ble_overrides[] = {
106 RF_BLE_BOARD_OVERRIDES
111 typedef struct output_config {
116 static const output_config_t output_power[] = {
132 #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) 135 #define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm) 136 #define OUTPUT_POWER_MAX (output_power[0].dbm) 137 #define OUTPUT_POWER_UNKNOWN 0xFFFF 140 static const output_config_t *tx_power_current = &output_power[0];
142 PROCESS(rf_ble_beacon_process,
"CC13xx / CC26xx RF BLE Beacon Process");
145 send_ble_adv_nc(
int channel, uint8_t *adv_payload,
int adv_payload_len)
148 rfc_CMD_BLE_ADV_NC_t cmd;
149 rfc_bleAdvPar_t *params;
151 params = (rfc_bleAdvPar_t *)ble_params_buf;
154 memset(&cmd, 0x00,
sizeof(cmd));
155 memset(ble_params_buf, 0x00,
sizeof(ble_params_buf));
158 cmd.commandNo = CMD_BLE_ADV_NC;
159 cmd.condition.rule = COND_NEVER;
160 cmd.whitening.bOverride = 0;
161 cmd.whitening.init = 0;
162 cmd.pParams = params;
163 cmd.channel = channel;
166 params->pDeviceAddress = (uint16_t *)BLE_ADDRESS_PTR;
167 params->endTrigger.triggerType = TRIG_NEVER;
168 params->endTime = TRIG_NEVER;
171 params = (rfc_bleAdvPar_t *)ble_params_buf;
172 params->advLen = adv_payload_len;
173 params->pAdvData = adv_payload;
176 PRINTF(
"send_ble_adv_nc: Chan=%d CMDSTA=0x%08lx, status=0x%04x\n",
177 channel, cmd_status, cmd.status);
178 return RF_CORE_CMD_ERROR;
183 PRINTF(
"send_ble_adv_nc: Chan=%d CMDSTA=0x%08lx, status=0x%04x\n",
184 channel, cmd_status, cmd.status);
185 return RF_CORE_CMD_ERROR;
188 return RF_CORE_CMD_OK;
195 return tx_power_current->dbm;
210 for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
211 if(power <= output_power[i].dbm) {
212 tx_power_current = &output_power[i];
221 if(RF_BLE_ENABLED == 0) {
226 if(strlen(name) == 0 || strlen(name) >= BLE_ADV_NAME_BUF_LEN) {
230 memset(beacond_config.adv_name, 0, BLE_ADV_NAME_BUF_LEN);
231 memcpy(beacond_config.adv_name, name, strlen(name));
235 beacond_config.interval = interval;
242 if(RF_BLE_ENABLED == 0) {
243 return RF_CORE_CMD_ERROR;
246 if(ti_lib_chipinfo_supports_ble() ==
false) {
247 return RF_CORE_CMD_ERROR;
250 if(beacond_config.adv_name[0] == 0) {
251 return RF_CORE_CMD_ERROR;
254 ble_mode_on = RF_BLE_IDLE;
258 return RF_CORE_CMD_OK;
276 rfc_CMD_RADIO_SETUP_t cmd;
278 rf_switch_select_path(RF_SWITCH_PATH_2_4GHZ);
283 cmd.txPower = tx_power_current->tx_power;
284 cmd.pRegOverride = ble_overrides;
285 cmd.config.frontEndMode = RF_CORE_RADIO_SETUP_FRONT_END_MODE;
286 cmd.config.biasMode = RF_CORE_RADIO_SETUP_BIAS_MODE;
291 PRINTF(
"rf_radio_setup: CMDSTA=0x%08lx, status=0x%04x\n",
292 cmd_status, cmd.status);
293 return RF_CORE_CMD_ERROR;
298 PRINTF(
"rf_radio_setup: wait, CMDSTA=0x%08lx, status=0x%04x\n",
299 cmd_status, cmd.status);
300 return RF_CORE_CMD_ERROR;
303 return RF_CORE_CMD_OK;
311 bool interrupts_disabled;
312 uint8_t j, channel_selected;
316 if(len > BLE_ADV_NAME_BUF_LEN) {
317 len = BLE_ADV_NAME_BUF_LEN;
324 interrupts_disabled = ti_lib_int_master_disable();
325 ble_mode_on = RF_BLE_ACTIVE;
326 if(!interrupts_disabled) {
327 ti_lib_int_master_enable();
346 if(NETSTACK_RADIO.receiving_packet()) {
347 PRINTF(
"rf_ble_beacon_single: We were receiving\n");
361 PRINTF(
"rf_ble_beacon_single: rf_core_boot() failed\n");
368 if(rf_radio_setup() != RF_CORE_CMD_OK) {
370 PRINTF(
"rf_ble_beacon_single: Error entering BLE mode\n");
373 for(j = 0; j < 3; j++) {
374 channel_selected = (channel >> j) & 0x01;
375 if(channel_selected == 1) {
376 if(send_ble_adv_nc(37 + j, data, len) != RF_CORE_CMD_OK) {
378 PRINTF(
"rf_ble_beacon_single: Channel=%d, " 379 "Error advertising\n", 37 + j);
386 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_STOP), &cmd_status) != RF_CORE_CMD_OK) {
388 PRINTF(
"rf_ble_beacon_single: status=0x%08lx\n", cmd_status);
402 interrupts_disabled = ti_lib_int_master_disable();
404 ble_mode_on = RF_BLE_IDLE;
406 if(!interrupts_disabled) {
407 ti_lib_int_master_enable();
417 etimer_set(&ble_adv_et, beacond_config.interval);
421 if(ev == PROCESS_EVENT_EXIT) {
429 memset(payload, 0, BLE_ADV_PAYLOAD_BUF_LEN);
431 payload[p++] = BLE_ADV_TYPE_DEVINFO;
433 payload[p++] = 1 + strlen(beacond_config.adv_name);
434 payload[p++] = BLE_ADV_TYPE_NAME;
435 memcpy(&payload[p], beacond_config.adv_name,
436 strlen(beacond_config.adv_name));
437 p += strlen(beacond_config.adv_name);
443 for(i = 0; i < BLE_ADV_MESSAGES; i++) {
450 if(i < BLE_ADV_MESSAGES - 1) {
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 rf_ble_beacond_stop()
Stop the BLE advertisement/beacon daemon.
#define PROCESS(name, strname)
Declare a process.
Header file with macros which rename TI CC26xxware functions.
#define PROCESS_BEGIN()
Define the beginning of a process.
Header file for the link-layer address representation
#define PROCESS_END()
Define the end of a process.
radio_value_t rf_ble_get_tx_power(void)
Get TX power for BLE advertisements.
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
void rf_ble_beacond_config(clock_time_t interval, const char *name)
Set the device name to use with the BLE advertisement/beacon daemon.
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
void rf_ble_set_tx_power(radio_value_t power)
Set TX power for BLE advertisements.
Header file for the CC13xx/CC26xx RF core driver.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
void rf_core_primary_mode_abort()
Abort the currently running primary radio op.
void process_exit(struct process *p)
Cause a process to exit.
Header file for the CC13xx/CC26xx oscillator control.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
void rf_ble_beacon_single(uint8_t channel, uint8_t *data, uint8_t len)
Transmit a single BLE advertisement in one or more advertisement channels.
Header file for the Contiki process interface.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
void rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command)
Prepare a buffer to host a Radio Op.
uint8_t rf_ble_is_active()
Check whether the BLE beacond is currently active.
uint8_t rf_core_primary_mode_restore()
Abort the currently running primary radio op.
Header file for the CC13xx/CC26xx BLE driver.
Header file with definitions related to RF switch support.
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
Include file for the Contiki low-layer network stack (NETSTACK)
Default definitions of C compiler quirk work-arounds.
uint8_t rf_ble_beacond_start()
Start the BLE advertisement/beacon daemon.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
uint8_t rf_core_boot()
Boot the RF Core.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
void process_start(struct process *p, process_data_t data)
Start a process.
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.
#define PROCESS_EXIT()
Exit the currently running process.