1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #ifndef H_BLE_PHY_
21 #define H_BLE_PHY_
22
23 #include "nimble/hci_common.h"
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) && !(MYNEWT_VAL(BSP_NRF52) || MYNEWT_VAL(BSP_NRF52840))
30 #error LE 2M PHY can only be enabled on nRF52xxx
31 #endif
32
33 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) && !MYNEWT_VAL(BSP_NRF52840)
34 #error LE Coded PHY can only be enabled on nRF52840
35 #endif
36
37 /* Forward declarations */
38 struct os_mbuf;
39
40 /* Channel/Frequency defintions */
41 #define BLE_PHY_NUM_CHANS (40)
42 #define BLE_PHY_NUM_DATA_CHANS (37)
43 #define BLE_PHY_CHAN0_FREQ_MHZ (2402)
44 #define BLE_PHY_DATA_CHAN0_FREQ_MHZ (2404)
45 #define BLE_PHY_CHAN_SPACING_MHZ (2)
46 #define BLE_PHY_NUM_ADV_CHANS (3)
47 #define BLE_PHY_ADV_CHAN_START (37)
48
49 /* Power */
50 #define BLE_PHY_MAX_PWR_DBM (10)
51
52 /* Deviation */
53 #define BLE_PHY_DEV_KHZ (185)
54 #define BLE_PHY_BINARY_ZERO (-BLE_PHY_DEV)
55 #define BLE_PHY_BINARY_ONE (BLE_PHY_DEV)
56
57 /* Max. clock drift */
58 #define BLE_PHY_MAX_DRIFT_PPM (50)
59
60 /* Data rate */
61 #define BLE_PHY_BIT_RATE_BPS (1000000)
62
63 /* Macros */
64 #define BLE_IS_ADV_CHAN(chan) (chan >= BLE_PHY_ADV_CHAN_START)
65 #define BLE_IS_DATA_CHAN(chan) (chan < BLE_PHY_ADV_CHAN_START)
66
67 /* PHY states */
68 #define BLE_PHY_STATE_IDLE (0)
69 #define BLE_PHY_STATE_RX (1)
70 #define BLE_PHY_STATE_TX (2)
71
72 /* BLE PHY transitions */
73 #define BLE_PHY_TRANSITION_NONE (0)
74 #define BLE_PHY_TRANSITION_RX_TX (1)
75 #define BLE_PHY_TRANSITION_TX_RX (2)
76
77 /* PHY error codes */
78 #define BLE_PHY_ERR_RADIO_STATE (1)
79 #define BLE_PHY_ERR_INIT (2)
80 #define BLE_PHY_ERR_INV_PARAM (3)
81 #define BLE_PHY_ERR_NO_BUFS (4)
82 #define BLE_PHY_ERR_TX_LATE (5)
83 #define BLE_PHY_ERR_RX_LATE (6)
84
85 /* Maximun PDU length. Includes LL header of 2 bytes and 255 bytes payload. */
86 #define BLE_PHY_MAX_PDU_LEN (257)
87
88 /* Wait for response timer */
89 typedef void (*ble_phy_tx_end_func)(void *arg);
90
91 /* Initialize the PHY */
92 int ble_phy_init(void);
93
94 /* Reset the PHY */
95 int ble_phy_reset(void);
96
97 /* Set the PHY channel */
98 int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit);
99
100 /* Set transmit start time */
101 int ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs);
102
103 /* Set receive start time */
104 int ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs);
105
106 /* Set the transmit end callback and argument */
107 void ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg);
108
109 typedef uint8_t (*ble_phy_tx_pducb_t)(uint8_t *dptr, void *pducb_arg,
110 uint8_t *hdr_byte);
111
112 /* Place the PHY into transmit mode */
113 int ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans);
114
115 /* Place the PHY into receive mode */
116 int ble_phy_rx(void);
117
118 /* Copies the received PHY buffer into the allocated pdu */
119 void ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu);
120
121 /* Get an RSSI reading */
122 int ble_phy_rssi_get(void);
123
124 /* Set the transmit power */
125 int ble_phy_txpwr_set(int dbm);
126
127 /* Get highest allowed power from range */
128 int ble_phy_txpower_round(int dbm);
129
130 /* Get the transmit power */
131 int ble_phy_txpwr_get(void);
132
133 /* Disable the PHY */
134 void ble_phy_disable(void);
135
136 #define BLE_PHY_WFR_ENABLE_RX (0)
137 #define BLE_PHY_WFR_ENABLE_TXRX (1)
138
139 void ble_phy_stop_usec_timer(void);
140 void ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs);
141
142 /* Starts rf clock */
143 void ble_phy_rfclk_enable(void);
144
145 /* Stops rf clock */
146 void ble_phy_rfclk_disable(void);
147
148 /*
149 * Used to restart reception on same channel after wfr timer expiration or
150 * frame received.
151 */
152 void ble_phy_restart_rx(void);
153
154 /* Gets the current state of the PHY */
155 int ble_phy_state_get(void);
156
157 /* Gets current state of transceiver */
158 uint8_t ble_phy_xcvr_state_get(void);
159
160 /* Returns 'true' if a reception has started */
161 int ble_phy_rx_started(void);
162
163 /*
164 * Returns the maximum supported tx/rx PDU payload size, in bytes, for data
165 * channel PDUs (this does not apply to advertising channel PDUs). Note
166 * that the data channel PDU is composed of a 2-byte header, the payload, and
167 * an optional MIC. The maximum payload is 251 bytes.
168 */
169 uint8_t ble_phy_max_data_pdu_pyld(void);
170
171 /* Gets the current access address */
172 uint32_t ble_phy_access_addr_get(void);
173
174 /* Enable encryption */
175 void ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key,
176 uint8_t is_master);
177
178 /* Disable encryption */
179 void ble_phy_encrypt_disable(void);
180
181 /* Set the packet counters and dir used by LE encyption */
182 void ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir);
183
184 /* Enable phy resolving list */
185 void ble_phy_resolv_list_enable(void);
186
187 /* Disable phy resolving list */
188 void ble_phy_resolv_list_disable(void);
189
190 /*
191 * These definitions are used for the 'phy' parameters in the API listed below.
192 * These are numbered in a specific order to save code. The HCI definitions for
193 * the PHY modes for 1Mbps and 2Mbps are the same here. For the coded phy
194 * they need to be translated from the HCI number to either 0 or 3. This
195 * was done in order to save code when translating between the HCI phy value
196 * and the phy API.
197 */
198 #define BLE_PHY_MODE_1M (1)
199 #define BLE_PHY_MODE_2M (2)
200 #define BLE_PHY_MODE_CODED_125KBPS (0)
201 #define BLE_PHY_MODE_CODED_500KBPS (3)
202
203 /* The number of different modes */
204 #define BLE_PHY_NUM_MODE (4)
205
206 /* PHY numbers (compatible with HCI) */
207 #define BLE_PHY_1M (BLE_HCI_LE_PHY_1M)
208 #define BLE_PHY_2M (BLE_HCI_LE_PHY_2M)
209 #define BLE_PHY_CODED (BLE_HCI_LE_PHY_CODED)
210
211 /* PHY bitmasks (compatible with HCI) */
212 #define BLE_PHY_MASK_1M (BLE_HCI_LE_PHY_1M_PREF_MASK)
213 #define BLE_PHY_MASK_2M (BLE_HCI_LE_PHY_2M_PREF_MASK)
214 #define BLE_PHY_MASK_CODED (BLE_HCI_LE_PHY_CODED_PREF_MASK)
215
216 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) || MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY))
217 uint32_t ble_phy_mode_pdu_start_off(int phy);
218 void ble_phy_mode_set(uint8_t new_phy_mode, uint8_t txtorx_phy_mode);
219 #else
220 #define ble_phy_mode_pdu_start_off(phy) (40)
221
222 #endif
223
224 int ble_phy_get_cur_phy(void);
ble_ll_phy_to_phy_mode(int phy,int phy_options)225 static inline int ble_ll_phy_to_phy_mode(int phy, int phy_options)
226 {
227 int phy_mode;
228
229 /*
230 * Mode values are set in a way that 1M, 2M and Coded(S=2) are equivalent
231 * to 1M, 2M and Coded in HCI. The only conversion is needed for Coded(S=8)
232 * which uses non-HCI value.
233 */
234
235 phy_mode = phy;
236
237 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
238 if (phy == BLE_PHY_CODED && phy_options == BLE_HCI_LE_PHY_CODED_S8_PREF) {
239 phy_mode = BLE_PHY_MODE_CODED_125KBPS;
240 }
241 #endif
242
243 return phy_mode;
244 }
245
246 #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE)
247 void ble_phy_enable_dtm(void);
248 void ble_phy_disable_dtm(void);
249 #endif
250
251 #ifdef __cplusplus
252 }
253 #endif
254
255 #endif /* H_BLE_PHY_ */
256