1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18
19 #include "../../stack/ble/ble.h"
20 #include "../../stack/ble/ble_format.h"
21 #include "b91_bt_buffer.h"
22 #include "b91_bt_init.h"
23
24 #define B91_BT_SLEEP_AJUSTMENT (2)
25
26 #ifdef CONFIG_PM
27 #include "ext_driver/ext_pm.h"
28 #endif /* CONFIG_PM */
29
30 #if CONFIG_B91_BLE_CTRL_EXT_ADV
31
32 /** Number of Supported Advertising Sets, no exceed "ADV_SETS_NUMBER_MAX" */
33 #define APP_ADV_SETS_NUMBER CONFIG_B91_BLE_CTRL_EXT_ADV_SETS_NUM
34
35 /** Maximum Advertising Data Length, (if legacy ADV, max length 31 bytes is enough) */
36 #define APP_MAX_LENGTH_ADV_DATA CONFIG_B91_BLE_CTRL_EXT_ADV_DATA_LEN_MAX
37
38 /** Maximum Scan Response Data Length, (if legacy ADV, max length 31 bytes is enough) */
39 #define APP_MAX_LENGTH_SCAN_RESPONSE_DATA CONFIG_B91_BLE_CTRL_EXT_ADV_SCAN_DATA_LEN_MAX
40
41 _attribute_ble_data_retention_ u8 app_advSet_buffer[ADV_SET_PARAM_LENGTH * APP_ADV_SETS_NUMBER];
42 _attribute_ble_data_retention_ u8 app_advData_buffer[APP_MAX_LENGTH_ADV_DATA * APP_ADV_SETS_NUMBER];
43 _attribute_ble_data_retention_ u8
44 app_scanRspData_buffer[APP_MAX_LENGTH_SCAN_RESPONSE_DATA * APP_ADV_SETS_NUMBER];
45
46 #endif /* CONFIG_B91_BLE_CTRL_EXT_ADV */
47
48 #if CONFIG_B91_BLE_CTRL_PER_ADV
49
50 /** Number of Supported Periodic Advertising Sets, no exceed "PERIODIC_ADV_NUMBER_MAX" */
51 #define APP_PER_ADV_SETS_NUMBER CONFIG_B91_BLE_CTRL_PER_ADV_SETS_NUM
52
53 /** Maximum Periodic Advertising Data Length */
54 #define APP_MAX_LENGTH_PER_ADV_DATA CONFIG_B91_BLE_CTRL_PER_ADV_DATA_LEN_MAX
55
56 _attribute_ble_data_retention_ u8
57 app_perdAdvSet_buffer[PERD_ADV_PARAM_LENGTH * APP_PER_ADV_SETS_NUMBER];
58 _attribute_ble_data_retention_ u8
59 app_perdAdvData_buffer[APP_MAX_LENGTH_PER_ADV_DATA * APP_PER_ADV_SETS_NUMBER];
60
61 #endif /* CONFIG_B91_BLE_CTRL_PER_ADV */
62
63 /**
64 * @brief This function is used to initialize the MAC address
65 * @param[in] flash_addr - flash address for MAC address
66 * @param[in] mac_public - public address
67 * @param[in] mac_random_static - random static MAC address
68 * @return none
69 */
b91_bt_blc_mac_init(int flash_addr,u8 * mac_public,u8 * mac_random_static)70 _attribute_no_inline_ static void b91_bt_blc_mac_init(int flash_addr, u8 *mac_public,
71 u8 *mac_random_static)
72 {
73 if (flash_addr == 0) {
74 return;
75 }
76
77 u8 mac_read[8];
78 flash_read_page(flash_addr, 8, mac_read);
79
80 u8 value_rand[5];
81 generateRandomNum(5, value_rand);
82
83 u8 ff_six_byte[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
84 if (memcmp(mac_read, ff_six_byte, 6)) {
85 memcpy(mac_public, mac_read, 6); /* copy public address from flash */
86 } else { /* no public address in flash */
87 mac_public[0] = value_rand[0];
88 mac_public[1] = value_rand[1];
89 mac_public[2] = value_rand[2];
90 mac_public[3] = 0x38; /* company id: 0xA4C138 */
91 mac_public[4] = 0xC1;
92 mac_public[5] = 0xA4;
93
94 flash_write_page(flash_addr, 6, mac_public);
95 }
96
97 mac_random_static[0] = mac_public[0];
98 mac_random_static[1] = mac_public[1];
99 mac_random_static[2] = mac_public[2];
100 mac_random_static[5] = 0xC0; /* for random static */
101
102 u16 high_2_byte = (mac_read[6] | mac_read[7] << 8);
103 if (high_2_byte != 0xFFFF) {
104 memcpy((u8 *)(mac_random_static + 3), (u8 *)(mac_read + 6), 2);
105 } else {
106 mac_random_static[3] = value_rand[3];
107 mac_random_static[4] = value_rand[4];
108
109 flash_write_page(flash_addr + 6, 2, (u8 *)(mac_random_static + 3));
110 }
111 }
112
113 #ifdef CONFIG_PM
114 /**
115 * @brief Telink B91 BLE sleep implementation
116 * @param[in] sleep_mode - sleep mode to enter
117 * @param[in] wakeup_src - wake up source
118 * @param[in] wakeup_tick - wake up stimer tick
119 * @return wake up source
120 */
b91_bt_zephyr_wakeup(SleepMode_TypeDef sleep_mode,SleepWakeupSrc_TypeDef wakeup_src,unsigned int wakeup_tick)121 static int b91_bt_zephyr_wakeup(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src,
122 unsigned int wakeup_tick)
123 {
124 k_sched_lock();
125 unsigned int sys_tick = stimer_get_tick();
126 int64_t ktime_ms = k_uptime_get();
127 k_sched_unlock();
128
129 systimer_irq_enable();
130
131 ktime_ms += (wakeup_tick - sys_tick) / SYSTEM_TIMER_TICK_1MS - B91_BT_SLEEP_AJUSTMENT;
132 k_sleep(K_TIMEOUT_ABS_MS(ktime_ms));
133
134 int src = pm_get_wakeup_src();
135
136 if (src & WAKEUP_STATUS_TIMER) {
137 src |= STATUS_ENTER_SUSPEND;
138 }
139
140 return src;
141 }
142 #endif /* CONFIG_PM */
143
144 /**
145 * @brief Telink B91 BLE Controller initialization
146 * @param[in] prx - HCI RX callback
147 * @param[in] ptx -HCI TX callback
148 * @return Status - 0: command succeeded; -1: command failed
149 */
b91_bt_blc_init(void * prx,void * ptx)150 int b91_bt_blc_init(void *prx, void *ptx)
151 {
152 /* random number generator must be initiated here(in the beginning of user_init_nromal).
153 * When deepSleep retention wakeUp, no need initialize again */
154 random_generator_init();
155
156 /* for 512K Flash, mac_address equals to 0x76000
157 * for 1M Flash, mac_address equals to 0xFF000 */
158 u8 mac_public[BLE_ADDR_LEN];
159 u8 mac_random_static[BLE_ADDR_LEN];
160 b91_bt_blc_mac_init(CONFIG_B91_BLE_CTRL_MAC_FLASH_ADDR, mac_public, mac_random_static);
161
162 blc_ll_initBasicMCU();
163
164 #ifdef CONFIG_B91_BLE_CTRL_MAC_PUBLIC
165 blc_ll_initStandby_module(mac_public);
166 #else
167 blc_ll_initStandby_module(mac_random_static);
168 #endif /* CONFIG_B91_BLE_CTRL_MAC_PUBLIC */
169
170 blc_ll_initLegacyAdvertising_module(); // adv module: mandatory for BLE slave,
171
172 blc_ll_initLegacyScanning_module(); // scan module: mandatory for BLE master
173
174 blc_ll_initInitiating_module(); // initiate module: mandatory for BLE master
175
176 blc_ll_initAclConnection_module();
177 #ifdef CONFIG_BT_CENTRAL
178 blc_ll_initAclMasterRole_module();
179 #endif /* CONFIG_BT_CENTRAL */
180 #ifdef CONFIG_BT_PERIPHERAL
181 blc_ll_initAclSlaveRole_module();
182 #endif /* CONFIG_BT_PERIPHERAL */
183
184 #if CONFIG_B91_BLE_CTRL_EXT_ADV
185 blc_ll_initExtendedAdvertising_module();
186 blc_ll_initExtendedAdvSetBuffer(app_advSet_buffer, APP_ADV_SETS_NUMBER);
187 blc_ll_initExtAdvDataBuffer(app_advData_buffer, APP_MAX_LENGTH_ADV_DATA);
188 blc_ll_initExtScanRspDataBuffer(app_scanRspData_buffer, APP_MAX_LENGTH_SCAN_RESPONSE_DATA);
189 #endif /* CONFIG_B91_BLE_CTRL_EXT_ADV */
190
191 #if CONFIG_B91_BLE_CTRL_PER_ADV
192 blc_ll_initPeriodicAdvertising_module();
193 blc_ll_initPeriodicAdvParamBuffer(app_perdAdvSet_buffer, APP_PER_ADV_SETS_NUMBER);
194 blc_ll_initPeriodicAdvDataBuffer(app_perdAdvData_buffer, APP_MAX_LENGTH_PER_ADV_DATA);
195 #endif /* CONFIG_B91_BLE_CTRL_PER_ADV */
196
197 #if CONFIG_B91_BLE_CTRL_EXT_SCAN
198 blc_ll_initExtendedScanning_module();
199 #endif /* CONFIG_B91_BLE_CTRL_EXT_SCAN */
200
201 #if CONFIG_B91_BLE_CTRL_PER_ADV_SYNC
202 blc_ll_initPeriodicAdvertisingSynchronization_module();
203 #endif /* CONFIG_B91_BLE_CTRL_PER_ADV_SYNC */
204
205 blc_ll_setAclConnMaxOctetsNumber(ACL_CONN_MAX_RX_OCTETS, ACL_MASTER_MAX_TX_OCTETS,
206 ACL_SLAVE_MAX_TX_OCTETS);
207
208 /* all ACL connection share same RX FIFO */
209 if (blc_ll_initAclConnRxFifo(app_acl_rxfifo, ACL_RX_FIFO_SIZE, ACL_RX_FIFO_NUM) !=
210 BLE_SUCCESS) {
211 return INIT_FAILED;
212 }
213
214 #ifdef CONFIG_BT_CENTRAL
215 /* ACL Master TX FIFO */
216 if (blc_ll_initAclConnMasterTxFifo(app_acl_mstTxfifo, ACL_MASTER_TX_FIFO_SIZE,
217 ACL_MASTER_TX_FIFO_NUM,
218 CONFIG_B91_BLE_CTRL_MASTER_MAX_NUM) != BLE_SUCCESS) {
219 return INIT_FAILED;
220 }
221 #endif /* CONFIG_BT_CENTRAL */
222
223 #ifdef CONFIG_BT_PERIPHERAL
224 /* ACL Slave TX FIFO */
225 if (blc_ll_initAclConnSlaveTxFifo(app_acl_slvTxfifo, ACL_SLAVE_TX_FIFO_SIZE,
226 ACL_SLAVE_TX_FIFO_NUM,
227 CONFIG_B91_BLE_CTRL_SLAVE_MAX_NUM) != BLE_SUCCESS) {
228 return INIT_FAILED;
229 }
230 #endif /* CONFIG_BT_PERIPHERAL */
231
232 blc_ll_ConfigLegacyAdvEnable_by_API_only(LEG_ADV_STRATEGY_2);
233 blc_ll_ConfigLegacyScanEnable_by_API_only(LEG_SCAN_STRATEGY_2);
234
235 blc_ll_setMaxConnectionNumber(CONFIG_B91_BLE_CTRL_MASTER_MAX_NUM,
236 CONFIG_B91_BLE_CTRL_SLAVE_MAX_NUM);
237 blc_ll_setAclMasterConnectionInterval(CONFIG_B91_BLE_CTRL_CONNECTION_INTERVAL_IDX);
238 blc_ll_setCreateConnectionTimeout(CONFIG_B91_BLE_CTRL_CONNECTION_TIMEOUT_MS);
239
240 rf_set_power_level_index(CONFIG_B91_BLE_CTRL_RF_POWER);
241
242 blc_ll_initChannelSelectionAlgorithm_2_feature();
243 blc_ll_init2MPhyCodedPhy_feature();
244
245 /* HCI RX FIFO */
246 if (blc_ll_initHciRxFifo(app_hci_rxfifo, HCI_RX_FIFO_SIZE, HCI_RX_FIFO_NUM) !=
247 BLE_SUCCESS) {
248 return INIT_FAILED;
249 }
250
251 /* HCI TX FIFO */
252 if (blc_ll_initHciTxFifo(app_hci_txfifo, HCI_TX_FIFO_SIZE, HCI_TX_FIFO_NUM) !=
253 BLE_SUCCESS) {
254 return INIT_FAILED;
255 }
256
257 /* HCI RX ACL FIFO */
258 if (blc_ll_initHciAclDataFifo(app_hci_rxAclfifo, HCI_RX_ACL_FIFO_SIZE,
259 HCI_RX_ACL_FIFO_NUM) != BLE_SUCCESS) {
260 return INIT_FAILED;
261 }
262
263 /* HCI Data && Event */
264 blc_hci_registerControllerDataHandler(blc_hci_sendACLData2Host);
265 blc_hci_registerControllerEventHandler(
266 blc_hci_send_data); // controller hci event to host all processed in this func
267
268 /* bluetooth event */
269 blc_hci_setEventMask_cmd(HCI_EVT_MASK_DISCONNECTION_COMPLETE);
270
271 /* bluetooth low energy(LE) event, all enable */
272 blc_hci_le_setEventMask_cmd(0xFFFFFFFF);
273 blc_hci_le_setEventMask_2_cmd(0x7FFFFFFF);
274
275 u8 check_status = blc_controller_check_appBufferInitialization();
276 if (check_status != BLE_SUCCESS) {
277 return INIT_FAILED;
278 }
279
280 /* HCI configuration */
281 blc_register_hci_handler(prx, ptx);
282
283 #ifdef CONFIG_PM
284 /* Enable PM for BLE stack */
285 blc_ll_initPowerManagement_module();
286
287 /* Select the sleep source for BLE stack */
288 blc_pm_set_extern_wakeup_recover(b91_bt_zephyr_wakeup, pm_tim_recover_32k_rc);
289
290 /* Enable the sleep masks for BLE stack thread */
291 blc_pm_setSleepMask(PM_SLEEP_LEG_ADV | PM_SLEEP_LEG_SCAN | PM_SLEEP_ACL_SLAVE |
292 PM_SLEEP_ACL_MASTER);
293 #endif /* CONFIG_PM */
294
295 return INIT_OK;
296 }
297