1 /*
2  * Copyright (c) 2018-2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdbool.h>
8 
9 #include <zephyr/toolchain.h>
10 #include <zephyr/types.h>
11 #include <zephyr/sys/util.h>
12 
13 #include "hal/ccm.h"
14 #include "hal/radio.h"
15 #include "hal/ticker.h"
16 
17 #include "util/util.h"
18 #include "util/memq.h"
19 
20 #include "pdu_vendor.h"
21 #include "pdu.h"
22 
23 #include "lll.h"
24 #include "lll_vendor.h"
25 #include "lll_df_types.h"
26 #include "lll_conn.h"
27 #include "lll_peripheral.h"
28 #include "lll_chan.h"
29 
30 #include "lll_internal.h"
31 #include "lll_tim_internal.h"
32 
33 #include <soc.h>
34 #include "hal/debug.h"
35 
36 static int init_reset(void);
37 static int prepare_cb(struct lll_prepare_param *p);
38 
lll_periph_init(void)39 int lll_periph_init(void)
40 {
41 	int err;
42 
43 	err = init_reset();
44 	if (err) {
45 		return err;
46 	}
47 
48 	return 0;
49 }
50 
lll_periph_reset(void)51 int lll_periph_reset(void)
52 {
53 	int err;
54 
55 	err = init_reset();
56 	if (err) {
57 		return err;
58 	}
59 
60 	return 0;
61 }
62 
lll_periph_prepare(void * param)63 void lll_periph_prepare(void *param)
64 {
65 	struct lll_prepare_param *p;
66 	struct lll_conn *lll;
67 	int err;
68 
69 	err = lll_clk_on();
70 	LL_ASSERT(!err || err == -EINPROGRESS);
71 
72 	p = param;
73 
74 	lll = p->param;
75 
76 	/* Accumulate window widening */
77 	lll->periph.window_widening_prepare_us +=
78 	    lll->periph.window_widening_periodic_us * (p->lazy + 1);
79 	if (lll->periph.window_widening_prepare_us >
80 	    lll->periph.window_widening_max_us) {
81 		lll->periph.window_widening_prepare_us =
82 			lll->periph.window_widening_max_us;
83 	}
84 
85 	/* Invoke common pipeline handling of prepare */
86 	err = lll_prepare(lll_is_abort_cb, lll_conn_abort_cb, prepare_cb, 0, p);
87 	LL_ASSERT(!err || err == -EINPROGRESS);
88 }
89 
init_reset(void)90 static int init_reset(void)
91 {
92 	return 0;
93 }
94 
prepare_cb(struct lll_prepare_param * p)95 static int prepare_cb(struct lll_prepare_param *p)
96 {
97 	uint32_t ticks_at_event;
98 	uint32_t ticks_at_start;
99 	uint16_t event_counter;
100 	uint32_t remainder_us;
101 	uint8_t data_chan_use;
102 	struct lll_conn *lll;
103 	struct ull_hdr *ull;
104 	uint32_t remainder;
105 	uint32_t hcto;
106 
107 	DEBUG_RADIO_START_S(1);
108 
109 	lll = p->param;
110 
111 	/* Reset connection event global variables */
112 	lll_conn_prepare_reset();
113 
114 	/* Calculate the current event latency */
115 	lll->latency_event = lll->latency_prepare + p->lazy;
116 
117 	/* Calculate the current event counter value */
118 	event_counter = lll->event_counter + lll->latency_event;
119 
120 	/* Update event counter to next value */
121 	lll->event_counter = (event_counter + 1);
122 
123 	/* Reset accumulated latencies */
124 	lll->latency_prepare = 0;
125 
126 	if (lll->data_chan_sel) {
127 #if defined(CONFIG_BT_CTLR_CHAN_SEL_2)
128 		data_chan_use = lll_chan_sel_2(event_counter, lll->data_chan_id,
129 					       &lll->data_chan_map[0],
130 					       lll->data_chan_count);
131 #else /* !CONFIG_BT_CTLR_CHAN_SEL_2 */
132 		data_chan_use = 0;
133 		LL_ASSERT(0);
134 #endif /* !CONFIG_BT_CTLR_CHAN_SEL_2 */
135 	} else {
136 		data_chan_use = lll_chan_sel_1(&lll->data_chan_use,
137 					       lll->data_chan_hop,
138 					       lll->latency_event,
139 					       &lll->data_chan_map[0],
140 					       lll->data_chan_count);
141 	}
142 
143 	/* current window widening */
144 	lll->periph.window_widening_event_us +=
145 		lll->periph.window_widening_prepare_us;
146 	lll->periph.window_widening_prepare_us = 0;
147 	if (lll->periph.window_widening_event_us >
148 	    lll->periph.window_widening_max_us) {
149 		lll->periph.window_widening_event_us =
150 			lll->periph.window_widening_max_us;
151 	}
152 
153 	/* current window size */
154 	lll->periph.window_size_event_us +=
155 		lll->periph.window_size_prepare_us;
156 	lll->periph.window_size_prepare_us = 0;
157 
158 	/* Start setting up Radio h/w */
159 	radio_reset();
160 	/* TODO: other Tx Power settings */
161 	radio_tx_power_set(RADIO_TXP_DEFAULT);
162 
163 	lll_conn_rx_pkt_set(lll);
164 
165 	radio_aa_set(lll->access_addr);
166 	radio_crc_configure(((0x5bUL) | ((0x06UL) << 8) | ((0x00UL) << 16)),
167 			    (((uint32_t)lll->crc_init[2] << 16) |
168 			     ((uint32_t)lll->crc_init[1] << 8) |
169 			     ((uint32_t)lll->crc_init[0])));
170 
171 	lll_chan_set(data_chan_use);
172 
173 	radio_isr_set(lll_conn_isr_rx, lll);
174 
175 	radio_tmr_tifs_set(EVENT_IFS_US);
176 
177 #if defined(CONFIG_BT_CTLR_PHY)
178 	radio_switch_complete_and_tx(lll->phy_rx, 0, lll->phy_tx,
179 				     lll->phy_flags);
180 #else /* !CONFIG_BT_CTLR_PHY */
181 	radio_switch_complete_and_tx(0, 0, 0, 0);
182 #endif /* !CONFIG_BT_CTLR_PHY */
183 
184 	ticks_at_event = p->ticks_at_expire;
185 	ull = HDR_LLL2ULL(lll);
186 	ticks_at_event += lll_event_offset_get(ull);
187 
188 	ticks_at_start = ticks_at_event;
189 	ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
190 
191 	remainder = p->remainder;
192 	remainder_us = radio_tmr_start(0, ticks_at_start, remainder);
193 
194 	radio_tmr_aa_capture();
195 	radio_tmr_aa_save(0);
196 
197 	hcto = remainder_us + EVENT_JITTER_US + (EVENT_JITTER_US << 2) +
198 	       (lll->periph.window_widening_event_us << 1) +
199 	       lll->periph.window_size_event_us;
200 
201 #if defined(CONFIG_BT_CTLR_PHY)
202 	hcto += radio_rx_ready_delay_get(lll->phy_rx, 1);
203 	hcto += addr_us_get(lll->phy_rx);
204 	hcto += radio_rx_chain_delay_get(lll->phy_rx, 1);
205 #else /* !CONFIG_BT_CTLR_PHY */
206 	hcto += radio_rx_ready_delay_get(0, 0);
207 	hcto += addr_us_get(0);
208 	hcto += radio_rx_chain_delay_get(0, 0);
209 #endif /* !CONFIG_BT_CTLR_PHY */
210 
211 	radio_tmr_hcto_configure(hcto);
212 
213 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
214 	radio_gpio_lna_setup();
215 
216 #if defined(CONFIG_BT_CTLR_PHY)
217 	radio_gpio_pa_lna_enable(remainder_us +
218 				 radio_rx_ready_delay_get(lll->phy_rx, 1) -
219 				 HAL_RADIO_GPIO_LNA_OFFSET);
220 #else /* !CONFIG_BT_CTLR_PHY */
221 	radio_gpio_pa_lna_enable(remainder_us +
222 				 radio_rx_ready_delay_get(0, 0) -
223 				 HAL_RADIO_GPIO_LNA_OFFSET);
224 #endif /* !CONFIG_BT_CTLR_PHY */
225 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
226 
227 #if defined(CONFIG_BT_CTLR_PROFILE_ISR) || \
228 	defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
229 	radio_tmr_end_capture();
230 #endif /* CONFIG_BT_CTLR_PROFILE_ISR */
231 
232 #if defined(CONFIG_BT_CTLR_CONN_RSSI)
233 	radio_rssi_measure();
234 #endif /* CONFIG_BT_CTLR_CONN_RSSI */
235 
236 #if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
237 	(EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
238 	/* check if preempt to start has changed */
239 	if (lll_preempt_calc(ull, (TICKER_ID_CONN_BASE + lll->handle),
240 			     ticks_at_event)) {
241 		radio_isr_set(lll_conn_isr_abort, lll);
242 		radio_disable();
243 	} else
244 #endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
245 	{
246 		uint32_t ret;
247 
248 		ret = lll_prepare_done(lll);
249 		LL_ASSERT(!ret);
250 	}
251 
252 	DEBUG_RADIO_START_S(1);
253 
254 	return 0;
255 }
256