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