From cd1fd05778eeb5ed08f6bf824b2edab37601acbf Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 May 2017 15:24:29 +0200 Subject: [PATCH] Bluetooth: controller: nRF5 radio timings abstractions Added HAL Radio abstractions to use SoC specific Radio Timings as documented in SoC's electrical characteristics. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/hal/nrf5/radio.c | 165 ++++++++++++++++-- subsys/bluetooth/controller/hal/radio.h | 20 +-- subsys/bluetooth/controller/ll_sw/ctrl.c | 167 +++++++++++++------ 3 files changed, 274 insertions(+), 78 deletions(-) diff --git a/subsys/bluetooth/controller/hal/nrf5/radio.c b/subsys/bluetooth/controller/hal/nrf5/radio.c index 3a7b11794ea..116e456ba53 100644 --- a/subsys/bluetooth/controller/hal/nrf5/radio.c +++ b/subsys/bluetooth/controller/hal/nrf5/radio.c @@ -204,6 +204,131 @@ void radio_pkt_tx_set(void *tx_packet) NRF_RADIO->PACKETPTR = (u32_t)tx_packet; } +u32_t radio_tx_ready_delay_get(u8_t phy, u8_t flags) +{ + /* Return TXEN->TXIDLE + TXIDLE->TX */ + +#if defined(CONFIG_SOC_SERIES_NRF51X) + return 140; +#elif defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_NRF52840) + switch (phy) { + default: +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + case BIT(0): + return 141; /* floor(140.1 + 1.6) */ + case BIT(1): + return 146; /* floor(145 + 1) */ +#else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + case BIT(0): + case BIT(1): + return 131; /* floor(129.5 + 1.6) */ +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + case BIT(2): + if (flags & 0x01) { + return 121; /* floor(119.6 + 2.2) */ + } else { + return 132; /* floor(130 + 2.2) */ + } + } +#else /* !CONFIG_SOC_NRF52840 */ +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + return 140; +#else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + return 131; /* floor(129.5 + 1.6) */ +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ +#endif /* !CONFIG_SOC_NRF52840 */ +#endif /* CONFIG_SOC_SERIES_NRF52X */ +} + +u32_t radio_tx_chain_delay_get(u8_t phy, u8_t flags) +{ +#if defined(CONFIG_SOC_SERIES_NRF51X) + return 1; /* ceil(1) */ +#elif defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_NRF52840) + switch (phy) { + default: + case BIT(0): + case BIT(1): + return 1; /* ceil(0.6) */ + case BIT(2): + if (flags & 0x01) { + return 1; /* TODO: different within packet */ + } else { + return 1; /* TODO: different within packet */ + } + } +#else /* !CONFIG_SOC_NRF52840 */ + return 1; /* ceil(0.6) */ +#endif /* !CONFIG_SOC_NRF52840 */ +#endif /* CONFIG_SOC_SERIES_NRF52X */ +} + +u32_t radio_rx_ready_delay_get(u8_t phy) +{ + /* Return RXEN->RXIDLE + RXIDLE->RX */ + +#if defined(CONFIG_SOC_SERIES_NRF51X) + return 138; +#elif defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_NRF52840) + switch (phy) { + default: +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + case BIT(0): + return 141; /* ceil(140.1 + 0.2) */ + case BIT(1): + return 145; /* ceil(144.6 + 0.2) */ +#else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + case BIT(0): + case BIT(1): + return 130; /* ceil(129.5 + 0.2) */ +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + case BIT(2): + return 121; /* ceil(120 + 0.2) */ + } +#else /* !CONFIG_SOC_NRF52840 */ +#if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + return 140; +#else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + return 130; /* ceil(129.5 + 0.2) */ +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ +#endif /* !CONFIG_SOC_NRF52840 */ +#endif /* CONFIG_SOC_SERIES_NRF52X */ +} + +u32_t radio_rx_chain_delay_get(u8_t phy, u8_t flags) +{ +#if defined(CONFIG_SOC_SERIES_NRF51X) + return 3; /* ceil(3) */ +#elif defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_NRF52840) + switch (phy) { + default: + case BIT(0): + return 10; /* ceil(9.4) */ + case BIT(1): + return 5; /* ceil(5) */ + case BIT(2): + if (flags & 0x01) { + return 30; /* ciel(29.6) */ + } else { + return 20; /* ciel(19.6) */ + } + } +#else /* !CONFIG_SOC_NRF52840 */ + switch (phy) { + default: + case BIT(0): + return 10; /* ceil(9.4) */ + case BIT(1): + return 5; /* ceil(5) */ + } +#endif /* !CONFIG_SOC_NRF52840 */ +#endif /* CONFIG_SOC_SERIES_NRF52X */ +} + void radio_rx_enable(void) { NRF_RADIO->TASKS_RXEN = 1; @@ -216,6 +341,12 @@ void radio_tx_enable(void) void radio_disable(void) { +#if !defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) + NRF_PPI->CHENCLR = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk; + NRF_PPI->TASKS_CHG[0].DIS = 1; + NRF_PPI->TASKS_CHG[1].DIS = 1; +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ + NRF_RADIO->SHORTS = 0; NRF_RADIO->TASKS_DISABLE = 1; } @@ -283,31 +414,46 @@ void *radio_pkt_scratch_get(void) #if !defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) static u8_t sw_tifs_toggle; -static void sw_switch(u8_t dir) +static void sw_switch(u8_t dir, u8_t phy, u8_t flags) { u8_t ppi = 12 + sw_tifs_toggle; + NRF_TIMER1->EVENTS_COMPARE[sw_tifs_toggle] = 0; + NRF_PPI->CH[11].EEP = (u32_t)&(NRF_RADIO->EVENTS_END); NRF_PPI->CH[11].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[sw_tifs_toggle].EN); - NRF_PPI->CHENSET = PPI_CHEN_CH11_Msk; NRF_PPI->CH[ppi].EEP = (u32_t) &(NRF_TIMER1->EVENTS_COMPARE[sw_tifs_toggle]); if (dir) { - NRF_TIMER1->CC[sw_tifs_toggle] -= RADIO_TX_READY_DELAY_US + - RADIO_TX_CHAIN_DELAY_US; + u32_t delay = radio_tx_ready_delay_get(phy, flags) + + radio_rx_chain_delay_get(phy, flags); + + if (delay < NRF_TIMER1->CC[sw_tifs_toggle]) { + NRF_TIMER1->CC[sw_tifs_toggle] -= delay; + } else { + NRF_TIMER1->CC[sw_tifs_toggle] = 1; + } NRF_PPI->CH[ppi].TEP = (u32_t)&(NRF_RADIO->TASKS_TXEN); } else { - NRF_TIMER1->CC[sw_tifs_toggle] -= RADIO_RX_READY_DELAY_US; + u32_t delay = radio_rx_ready_delay_get(phy); + + if (delay < NRF_TIMER1->CC[sw_tifs_toggle]) { + NRF_TIMER1->CC[sw_tifs_toggle] -= delay; + } else { + NRF_TIMER1->CC[sw_tifs_toggle] = 1; + } NRF_PPI->CH[ppi].TEP = (u32_t)&(NRF_RADIO->TASKS_RXEN); } + NRF_PPI->CHENSET = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk; + sw_tifs_toggle += 1; sw_tifs_toggle &= 1; } #endif /* CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ -void radio_switch_complete_and_rx(void) +void radio_switch_complete_and_rx(u8_t phy) { #if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | @@ -316,11 +462,11 @@ void radio_switch_complete_and_rx(void) #else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk; - sw_switch(0); + sw_switch(0, phy, 0); #endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ } -void radio_switch_complete_and_tx(void) +void radio_switch_complete_and_tx(u8_t phy, u8_t flags) { #if defined(CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW) NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | @@ -329,7 +475,7 @@ void radio_switch_complete_and_tx(void) #else /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk; - sw_switch(1); + sw_switch(1, phy, flags); #endif /* !CONFIG_BLUETOOTH_CONTROLLER_TIFS_HW */ } @@ -479,7 +625,6 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder) NRF_PPI->CH[8].EEP = (u32_t)&(NRF_RADIO->EVENTS_END); NRF_PPI->CH[8].TEP = (u32_t)&(NRF_TIMER1->TASKS_CLEAR); - NRF_PPI->CHENSET = PPI_CHEN_CH8_Msk; NRF_PPI->CH[9].EEP = (u32_t) &(NRF_TIMER1->EVENTS_COMPARE[0]); diff --git a/subsys/bluetooth/controller/hal/radio.h b/subsys/bluetooth/controller/hal/radio.h index 6790082ced4..6e3c9e0fe6b 100644 --- a/subsys/bluetooth/controller/hal/radio.h +++ b/subsys/bluetooth/controller/hal/radio.h @@ -8,18 +8,6 @@ #ifndef _RADIO_H_ #define _RADIO_H_ -/* Ramp up times from OPS. - */ -#define RADIO_TX_READY_DELAY_US 140 -#define RADIO_RX_READY_DELAY_US 138 - -/* Chain delays from OPS. - * nRF51: Tx= 1us, Rx= 3us; - * nRF52: Tx= 0.6us, Rx= 9.4us. - */ -#define RADIO_TX_CHAIN_DELAY_US 1 -#define RADIO_RX_CHAIN_DELAY_US 10 - typedef void (*radio_isr_fp) (void); void isr_radio(void); @@ -34,6 +22,10 @@ void radio_aa_set(u8_t *aa); void radio_pkt_configure(u8_t bits_len, u8_t max_len, u8_t flags); void radio_pkt_rx_set(void *rx_packet); void radio_pkt_tx_set(void *tx_packet); +uint32_t radio_tx_ready_delay_get(u8_t phy, u8_t flags); +uint32_t radio_tx_chain_delay_get(u8_t phy, u8_t flags); +uint32_t radio_rx_ready_delay_get(u8_t phy); +uint32_t radio_rx_chain_delay_get(u8_t phy, u8_t flags); void radio_rx_enable(void); void radio_tx_enable(void); void radio_disable(void); @@ -50,8 +42,8 @@ u32_t radio_crc_is_valid(void); void *radio_pkt_empty_get(void); void *radio_pkt_scratch_get(void); -void radio_switch_complete_and_rx(void); -void radio_switch_complete_and_tx(void); +void radio_switch_complete_and_rx(u8_t phy); +void radio_switch_complete_and_tx(u8_t phy, u8_t flags); void radio_switch_complete_and_disable(void); void radio_rssi_measure(void); diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.c b/subsys/bluetooth/controller/ll_sw/ctrl.c index d5a44e00343..02e93960959 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.c +++ b/subsys/bluetooth/controller/ll_sw/ctrl.c @@ -548,9 +548,9 @@ static inline u32_t addr_us_get(u8_t phy) case BIT(0): return 40; case BIT(1): - return 20; + return 24; case BIT(2): - return 336 + 64; /* TODO: Fix the hack */ + return 376; } } @@ -575,14 +575,13 @@ static inline void isr_radio_state_tx(void) _radio.state = STATE_RX; - hcto = radio_tmr_end_get() + RADIO_RX_CHAIN_DELAY_US + RADIO_TIFS - - RADIO_TX_CHAIN_DELAY_US + 4; + hcto = radio_tmr_end_get() + RADIO_TIFS + 4 + 1; /* 1us, end jitter */ radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_tx(); switch (_radio.role) { case ROLE_ADV: + radio_switch_complete_and_tx(0, 0); radio_pkt_rx_set(radio_pkt_scratch_get()); /* assert if radio packet ptr is not set and radio started rx */ @@ -592,7 +591,10 @@ static inline void isr_radio_state_tx(void) radio_ar_configure(_radio.nirk, _radio.irk); } + hcto += radio_rx_chain_delay_get(0, 0); hcto += addr_us_get(0); + hcto -= radio_tx_chain_delay_get(0, 0); + radio_tmr_hcto_configure(hcto); radio_tmr_end_capture(); @@ -603,15 +605,20 @@ static inline void isr_radio_state_tx(void) break; case ROLE_SCAN: + radio_switch_complete_and_tx(0, 0); radio_pkt_rx_set(_radio.packet_rx[_radio.packet_rx_last]-> pdu_data); /* assert if radio packet ptr is not set and radio started rx */ LL_ASSERT(!radio_is_ready()); + hcto += radio_rx_chain_delay_get(0, 0); hcto += addr_us_get(0); + hcto -= radio_tx_chain_delay_get(0, 0); + radio_tmr_hcto_configure(hcto); radio_rssi_measure(); + break; case ROLE_MASTER: @@ -625,6 +632,14 @@ static inline void isr_radio_state_tx(void) /* fall thru */ case ROLE_SLAVE: + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY) + radio_switch_complete_and_tx(_radio.conn_curr->phy_tx, + _radio.conn_curr->phy_flags); +#else /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + radio_switch_complete_and_tx(0, 0); +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + rx_packet_set(_radio.conn_curr, (struct pdu_data *)_radio. packet_rx[_radio.packet_rx_last]->pdu_data); @@ -632,9 +647,15 @@ static inline void isr_radio_state_tx(void) LL_ASSERT(!radio_is_ready()); #if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY) + hcto += radio_rx_chain_delay_get(_radio.conn_curr->phy_tx, + _radio.conn_curr->phy_flags); hcto += addr_us_get(_radio.conn_curr->phy_rx); + hcto -= radio_tx_chain_delay_get(_radio.conn_curr->phy_rx, + _radio.conn_curr->phy_flags); #else /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + hcto += radio_rx_chain_delay_get(0, 0); hcto += addr_us_get(0); + hcto -= radio_tx_chain_delay_get(0, 0); #endif /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ radio_tmr_hcto_configure(hcto); @@ -647,6 +668,7 @@ static inline void isr_radio_state_tx(void) * connection's tx list. */ packet_tx_enqueue(1); + break; case ROLE_NONE: @@ -738,10 +760,12 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok, ((_radio.fc_ena == 0) || (_radio.fc_req == _radio.fc_ack)) && (_radio.advertiser.conn)) { struct radio_le_conn_cmplt *radio_le_conn_cmplt; - u32_t ticks_slot_offset; - u32_t conn_interval_us; struct pdu_data *pdu_data; struct connection *conn; + u32_t ticks_slot_offset; + u32_t conn_interval_us; + u32_t conn_offset_us; + u32_t rx_ready_delay; u32_t ticker_status; if (IS_ENABLED(CONFIG_BLUETOOTH_CONTROLLER_CHAN_SEL_2)) { @@ -877,16 +901,18 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok, gc_lookup_ppm[conn->role.slave.sca]) * conn_interval_us) + (1000000 - 1)) / 1000000; conn->role.slave.window_widening_max_us = - (conn_interval_us >> 1) - 150; + (conn_interval_us >> 1) - RADIO_TIFS; conn->role.slave.window_size_event_us = pdu_adv->payload.connect_ind.lldata.win_size * 1250; conn->role.slave.window_size_prepare_us = 0; + rx_ready_delay = radio_rx_ready_delay_get(0); + /* calculate slave slot */ conn->hdr.ticks_slot = TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US + - RADIO_RX_READY_DELAY_US + 328 + - 328 + 150); + rx_ready_delay + 328 + RADIO_TIFS + + 328); conn->hdr.ticks_active_to_start = _radio.ticks_active_to_start; conn->hdr.ticks_xtal_to_start = TICKER_US_TO_TICKS(RADIO_TICKER_XTAL_OFFSET_US); @@ -900,6 +926,14 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok, conn_interval_us -= conn->role.slave.window_widening_periodic_us; + conn_offset_us = radio_tmr_end_get(); + conn_offset_us += + ((u64_t)pdu_adv->payload.connect_ind.lldata.win_offset + + 1) * 1250; + conn_offset_us -= radio_tx_chain_delay_get(0, 0); + conn_offset_us -= rx_ready_delay; + conn_offset_us -= RADIO_TICKER_JITTER_US << 1; + /* Stop Advertiser */ ticker_status = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO, RADIO_TICKER_USER_ID_WORKER, @@ -922,12 +956,9 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok, /* Start Slave */ ticker_status = ticker_start(RADIO_TICKER_INSTANCE_ID_RADIO, RADIO_TICKER_USER_ID_WORKER, - RADIO_TICKER_ID_FIRST_CONNECTION - + conn->handle, (_radio.ticks_anchor - ticks_slot_offset), - TICKER_US_TO_TICKS(radio_tmr_end_get() - - RADIO_TX_CHAIN_DELAY_US + (((u64_t) pdu_adv-> - payload.connect_ind.lldata.win_offset + 1) * 1250) - - RADIO_RX_READY_DELAY_US - (RADIO_TICKER_JITTER_US << 1)), + RADIO_TICKER_ID_FIRST_CONNECTION + conn->handle, + (_radio.ticks_anchor - ticks_slot_offset), + TICKER_US_TO_TICKS(conn_offset_us), TICKER_US_TO_TICKS(conn_interval_us), TICKER_REMAINDER(conn_interval_us), TICKER_NULL_LAZY, (ticks_slot_offset + conn->hdr.ticks_slot), @@ -1021,11 +1052,12 @@ static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready) TICKER_TICKS_TO_US(_radio.scanner.hdr.ticks_slot))) { struct radio_le_conn_cmplt *radio_le_conn_cmplt; struct radio_pdu_node_rx *radio_pdu_node_rx; - u32_t ticks_slot_offset; struct pdu_adv *pdu_adv_tx; struct pdu_data *pdu_data; - u32_t conn_interval_us; struct connection *conn; + u32_t ticks_slot_offset; + u32_t conn_interval_us; + u32_t conn_offset_us; u32_t ticker_status; u32_t conn_space_us; @@ -1070,24 +1102,22 @@ static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready) conn_interval_us = (u32_t)_radio.scanner.conn_interval * 1250; + + conn_offset_us = radio_tmr_end_get() + 502 + 1250; + conn_offset_us -= radio_tx_chain_delay_get(0, 0); + conn_offset_us -= radio_tx_ready_delay_get(0, 0); + if (_radio.scanner.win_offset_us == 0) { - conn_space_us = radio_tmr_end_get() - - RADIO_TX_CHAIN_DELAY_US + 502 + 1250 - - RADIO_TX_READY_DELAY_US; + conn_space_us = conn_offset_us; pdu_adv_tx->payload.connect_ind.lldata.win_offset = 0; } else { conn_space_us = _radio.scanner.win_offset_us; while ((conn_space_us & ((u32_t)1 << 31)) || - (conn_space_us < (radio_tmr_end_get() - - RADIO_TX_CHAIN_DELAY_US + - 502 + 1250 - - RADIO_TX_READY_DELAY_US))) { + (conn_space_us < conn_offset_us)) { conn_space_us += conn_interval_us; } - pdu_adv_tx->payload.connect_ind.lldata. win_offset = - (conn_space_us - radio_tmr_end_get() + - RADIO_TX_CHAIN_DELAY_US - 502 - 1250 + - RADIO_TX_READY_DELAY_US) / 1250; + pdu_adv_tx->payload.connect_ind.lldata.win_offset = + (conn_space_us - conn_offset_us) / 1250; } pdu_adv_tx->payload.connect_ind.lldata.interval = @@ -1266,9 +1296,9 @@ static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready) _radio.scanner.state = 1; _radio.state = STATE_TX; - radio_pkt_tx_set(pdu_adv_tx); radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_rx(); + radio_switch_complete_and_rx(0); + radio_pkt_tx_set(pdu_adv_tx); radio_tmr_end_capture(); return 0; @@ -2614,7 +2644,13 @@ static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done, } } else { /* if (_radio.state == STATE_TX) */ radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_rx(); + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY) + radio_switch_complete_and_rx(_radio.conn_curr->phy_rx); +#else /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + radio_switch_complete_and_rx(0); +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + radio_tmr_end_capture(); } @@ -2730,6 +2766,7 @@ static inline void isr_radio_state_rx(u8_t trx_done, u8_t crc_ok, (_radio.role == ROLE_SLAVE)))) { _radio.state = STATE_CLOSE; radio_disable(); + return; } @@ -2835,9 +2872,10 @@ static inline u32_t isr_close_scan(void) if (_radio.state == STATE_CLOSE) { dont_close = 1; - radio_pkt_rx_set(_radio.packet_rx[_radio.packet_rx_last]->pdu_data); radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_tx(); + radio_switch_complete_and_tx(0, 0); + radio_pkt_rx_set(_radio.packet_rx[_radio.packet_rx_last]-> + pdu_data); radio_rssi_measure(); if (_radio.scanner.filter_policy && _radio.nirk) { @@ -4793,7 +4831,7 @@ static void adv_setup(void) (pdu->type != PDU_ADV_TYPE_EXT_IND))) { _radio.state = STATE_TX; radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_rx(); + radio_switch_complete_and_rx(0); } else { _radio.state = STATE_CLOSE; radio_switch_complete_and_disable(); @@ -5021,9 +5059,9 @@ static void event_scan(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, _radio.scanner.chan = 0; } - radio_pkt_rx_set(_radio.packet_rx[_radio.packet_rx_last]->pdu_data); radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_tx(); + radio_switch_complete_and_tx(0, 0); + radio_pkt_rx_set(_radio.packet_rx[_radio.packet_rx_last]->pdu_data); radio_rssi_measure(); /* Setup Radio Filter */ @@ -5484,7 +5522,7 @@ static inline u32_t event_conn_update_prep(struct connection *conn, gc_lookup_ppm[conn->role.slave.sca]) * conn_interval_us) + (1000000 - 1)) / 1000000; conn->role.slave.window_widening_max_us = - (conn_interval_us >> 1) - 150; + (conn_interval_us >> 1) - RADIO_TIFS; conn->role.slave.window_size_prepare_us = conn->llcp.connection_update.win_size * 1250; conn->role.slave.ticks_to_offset = 0; @@ -6527,16 +6565,17 @@ static void event_slave(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, connection_configure(conn); + radio_tmr_tifs_set(RADIO_TIFS); + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY) + radio_switch_complete_and_tx(conn->phy_tx, conn->phy_flags); +#else /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + radio_switch_complete_and_tx(0, 0); +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + rx_packet_set(conn, (struct pdu_data *) _radio.packet_rx[_radio.packet_rx_last]->pdu_data); - radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_tx(); - -#if defined(CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI) - radio_rssi_measure(); -#endif /* CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI */ - /* Setup Radio Channel */ if (conn->data_chan_sel) { #if defined(CONFIG_BLUETOOTH_CONTROLLER_CHAN_SEL_2) @@ -6577,19 +6616,24 @@ static void event_slave(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, _radio.remainder_anchor); radio_tmr_aa_capture(); hcto = remainder_us + (RADIO_TICKER_JITTER_US << 2) + - RADIO_RX_READY_DELAY_US + (conn->role.slave.window_widening_event_us << 1) + conn->role.slave.window_size_event_us; #if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY) + hcto += radio_rx_ready_delay_get(conn->phy_rx); hcto += addr_us_get(conn->phy_rx); #else /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + hcto += radio_rx_ready_delay_get(0); hcto += addr_us_get(0); #endif /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ radio_tmr_hcto_configure(hcto); radio_tmr_end_capture(); +#if defined(CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI) + radio_rssi_measure(); +#endif /* CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI */ + #if (defined(CONFIG_BLUETOOTH_CONTROLLER_XTAL_ADVANCED) && \ (RADIO_TICKER_PREEMPT_PART_US <= RADIO_TICKER_PREEMPT_PART_MIN_US)) /* check if preempt to start has changed */ @@ -6673,9 +6717,15 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, connection_configure(conn); - tx_packet_set(conn, pdu_data_tx); radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_rx(); + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY) + radio_switch_complete_and_rx(conn->phy_rx); +#else /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + radio_switch_complete_and_rx(0); +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + + tx_packet_set(conn, pdu_data_tx); /* Setup Radio Channel */ if (conn->data_chan_sel) { @@ -6720,10 +6770,16 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, _radio.state = STATE_RX; _radio.packet_counter = 0xFF; + radio_tmr_tifs_set(RADIO_TIFS); + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY) + radio_switch_complete_and_tx(conn->phy_tx, conn->phy_flags); +#else /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + radio_switch_complete_and_tx(0, 0); +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + rx_packet_set(conn, (struct pdu_data *)_radio. packet_rx[_radio.packet_rx_last]->pdu_data); - radio_tmr_tifs_set(RADIO_TIFS); - radio_switch_complete_and_tx(); /* setup pkticker and hcto */ remainder_us = @@ -6732,11 +6788,13 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, _radio.remainder_anchor); radio_tmr_aa_capture(); - hcto = remainder_us + RADIO_TX_READY_DELAY_US + RADIO_TIFS; + hcto = remainder_us + RADIO_TIFS; #if defined(CONFIG_BLUETOOTH_CONTROLLER_PHY) + hcto += radio_tx_ready_delay_get(conn->phy_tx, conn->phy_flags); hcto += empty_pkt_us_get(conn->phy_rx); hcto += addr_us_get(conn->phy_rx); #else /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ + hcto += radio_tx_ready_delay_get(0, 0); hcto += empty_pkt_us_get(0); hcto += addr_us_get(0); #endif /* !CONFIG_BLUETOOTH_CONTROLLER_PHY */ @@ -8484,10 +8542,10 @@ u32_t radio_scan_filter_pol_get(void) u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval, u16_t latency, u16_t timeout) { - void *link; struct connection *conn; - u32_t access_addr; u32_t conn_interval_us; + u32_t access_addr; + void *link; if (_radio.scanner.conn) { return 1; @@ -8514,7 +8572,8 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval, _radio.scanner.conn_timeout = timeout; _radio.scanner.ticks_conn_slot = TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US + - RADIO_TX_READY_DELAY_US + 328 + 328 + 150); + radio_tx_ready_delay_get(0, 0) + + 328 + RADIO_TIFS + 328); conn->handle = 0xFFFF; conn->llcp_features = RADIO_BLE_FEAT;