From dd52b8ea02da44b58dd16b8304fec16a15b24648 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 11 Aug 2017 09:36:57 +0200 Subject: [PATCH] Bluetooth: controller: Fix first connection interval timing Due to varying remainder value, first interval will need to consider the remainder value used in microsecond timing from the start of the initiator window. Also the tx chain delay and ready delay must be substract after the window offset is calculated. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ctrl.c | 34 ++++++++++++++++-------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.c b/subsys/bluetooth/controller/ll_sw/ctrl.c index acbc496140b..a981667114f 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.c +++ b/subsys/bluetooth/controller/ll_sw/ctrl.c @@ -1329,14 +1329,24 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id, access_addr[0], &conn->access_addr[0], 4); memcpy(&pdu_adv_tx->payload.connect_ind.lldata.crc_init[0], &conn->crc_init[0], 3); - pdu_adv_tx->payload.connect_ind.lldata. win_size = 1; + pdu_adv_tx->payload.connect_ind.lldata.win_size = 1; 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); + + /* The ticker module generates the timeout callbacks with a + * +/- half the 32KHz clock resolution. In order to achieve + * a microsecond resolution, in the case of negative remainder, + * the radio packet timer is started one 32KHz tick early, + * hence substract one tick unit from the measurement of the + * packet end. + */ + if (!_radio.remainder_anchor || + (_radio.remainder_anchor & BIT(31))) { + conn_offset_us -= TICKER_TICKS_TO_US(1); + } if (_radio.scanner.win_offset_us == 0) { conn_space_us = conn_offset_us; @@ -1349,14 +1359,17 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id, } pdu_adv_tx->payload.connect_ind.lldata.win_offset = (conn_space_us - conn_offset_us) / 1250; + pdu_adv_tx->payload.connect_ind.lldata.win_size++; } + conn_space_us -= radio_tx_ready_delay_get(0, 0); + conn_space_us -= radio_tx_chain_delay_get(0, 0); + /* Workaround: Due to the missing remainder param in - * ticker_start function for first interval; add half a - * tick in microseconds so as to restrict the offset - * within the +/- 16us jitter for the offset. + * ticker_start function for first interval; add a + * tick so as to use the ceiled value. */ - conn_space_us += (30517578125UL/1000000000UL) >> 1; + conn_space_us += TICKER_TICKS_TO_US(1); pdu_adv_tx->payload.connect_ind.lldata.interval = _radio.scanner.conn_interval; @@ -6178,11 +6191,10 @@ static inline u32_t event_conn_update_prep(struct connection *conn, TICKER_US_TO_TICKS(conn->llcp.connection_update.win_offset_us); /* Workaround: Due to the missing remainder param in - * ticker_start function for first interval; add half a - * tick in microseconds so as to restrict the offset - * within the +/- 16us jitter for the offset. + * ticker_start function for first interval; add a + * tick so as to use the ceiled value. */ - ticks_win_offset += (30517578125UL/1000000000UL) >> 1; + ticks_win_offset += TICKER_TICKS_TO_US(1); } conn->conn_interval = conn->llcp.connection_update.interval; conn->latency = conn->llcp.connection_update.latency;