diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index ab96cb9c7..fe7004423 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -238,6 +238,9 @@ static inline int ble_ll_phy_to_phy_mode(int phy, int phy_options) #if MYNEWT_VAL(BLE_LL_DTM) void ble_phy_enable_dtm(void); void ble_phy_disable_dtm(void); +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) +int ble_phy_dtm_carrier(uint8_t rf_channel); +#endif #endif #ifdef __cplusplus diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 07e25fe2f..c57a1357a 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -342,6 +342,18 @@ ble_ll_dtm_tx_create_ctx(uint8_t packet_payload, uint8_t len, case 0x07: byte_pattern = 0xAA; break; +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) + case 0xff: + ble_ll_tx_power_set(g_ble_ll_tx_power); + rc = ble_phy_dtm_carrier(channel_rf_to_index[rf_channel]); + if (rc) { + return 1; + } + + /* this is special as it doesn't involve scheduling */ + g_ble_ll_dtm_ctx.active = 1; + return 0; +#endif default: return 1; } @@ -478,10 +490,20 @@ ble_ll_dtm_tx_test(uint8_t tx_chan, uint8_t len, uint8_t packet_payload, return BLE_ERR_INV_HCI_CMD_PARMS; } - if (tx_chan > 0x27 || packet_payload > 0x07) { + if (tx_chan > 0x27) { return BLE_ERR_INV_HCI_CMD_PARMS; } + if (packet_payload > 0x07) { +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) + if (packet_payload != 255) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#else + return BLE_ERR_INV_HCI_CMD_PARMS; +#endif + } + if (ble_ll_dtm_tx_create_ctx(packet_payload, len, tx_chan, phy_mode, interval, pkt_count)) { return BLE_ERR_UNSPECIFIED; diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 938455bbb..d146e07e3 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1796,4 +1796,12 @@ ble_phy_disable_dtm(void) { g_ble_phy_data.phy_whitening = 1; } + +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) +int +ble_phy_dtm_carrier(uint8_t rf_channel) +{ + return 1; +} +#endif #endif diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 481ed619d..cea18144a 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -2286,6 +2286,22 @@ void ble_phy_disable_dtm(void) /* Enable whitening */ NRF_RADIO->PCNF1 |= RADIO_PCNF1_WHITEEN_Msk; } + +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) +int +ble_phy_dtm_carrier(uint8_t rf_channel) +{ + /* based on Nordic DTM sample */ + ble_phy_disable(); + ble_phy_enable_dtm(); + ble_phy_mode_apply(BLE_PHY_MODE_1M); + nrf_radio_shorts_enable(NRF_RADIO, NRF_RADIO_SHORT_READY_START_MASK); + NRF_RADIO->FREQUENCY = g_ble_phy_chan_freq[rf_channel]; + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN); + + return 0; +} +#endif #endif void