1 /******************************************************************************
2 *
3 * Copyright (C) 2012-2014 Broadcom Corporation
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 /******************************************************************************
20 *
21 * Vendor-specific handler for DM events
22 *
23 ******************************************************************************/
24 #include <string.h>
25 #include "nfc_hal_int.h"
26 #include "nfc_hal_post_reset.h"
27 #include "upio.h"
28 #include "userial.h"
29
30 /*****************************************************************************
31 ** Constants and types
32 *****************************************************************************/
33
34 #define NFC_HAL_I93_RW_CFG_LEN (5)
35 #define NFC_HAL_I93_RW_CFG_PARAM_LEN (3)
36 #define NFC_HAL_I93_AFI (0)
37 #define NFC_HAL_I93_ENABLE_SMART_POLL (1)
38
39 static uint8_t nfc_hal_dm_i93_rw_cfg[NFC_HAL_I93_RW_CFG_LEN] = {
40 NCI_PARAM_ID_I93_DATARATE, NFC_HAL_I93_RW_CFG_PARAM_LEN,
41 NFC_HAL_I93_FLAG_DATA_RATE, /* Bit0:Sub carrier, Bit1:Data rate,
42 Bit4:Enable/Disable AFI */
43 NFC_HAL_I93_AFI, /* AFI if Bit 4 is set in the flag byte */
44 NFC_HAL_I93_ENABLE_SMART_POLL /* Bit0:Enable/Disable smart poll */
45 };
46
47 static uint8_t nfc_hal_dm_set_fw_fsm_cmd[NCI_MSG_HDR_SIZE + 1] = {
48 NCI_MTS_CMD | NCI_GID_PROP, NCI_MSG_SET_FWFSM, 0x01, 0x00,
49 };
50 #define NCI_SET_FWFSM_OFFSET_ENABLE 3
51
52 /* length of parameters in XTAL_INDEX CMD */
53 #define NCI_PROP_PARAM_SIZE_XTAL_INDEX 3
54 #ifndef NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX
55 #define NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX 20
56 #endif
57
58 const uint8_t nfc_hal_dm_get_build_info_cmd[NCI_MSG_HDR_SIZE] = {
59 NCI_MTS_CMD | NCI_GID_PROP, NCI_MSG_GET_BUILD_INFO, 0x00};
60 #define NCI_BUILD_INFO_OFFSET_HWID 25 /* HW ID offset in build info RSP */
61
62 const uint8_t nfc_hal_dm_get_patch_version_cmd[NCI_MSG_HDR_SIZE] = {
63 NCI_MTS_CMD | NCI_GID_PROP, NCI_MSG_GET_PATCH_VERSION, 0x00};
64 /* Length of patch version string in PATCH_INFO */
65 #define NCI_PATCH_INFO_VERSION_LEN 16
66
67 /*****************************************************************************
68 ** Extern function prototypes
69 *****************************************************************************/
70 extern uint8_t* p_nfc_hal_dm_lptd_cfg;
71 extern uint8_t* p_nfc_hal_dm_pll_325_cfg;
72 extern uint8_t* p_nfc_hal_dm_start_up_cfg;
73 extern uint8_t* p_nfc_hal_dm_start_up_vsc_cfg;
74 extern tNFC_HAL_CFG* p_nfc_hal_cfg;
75 extern tNFC_HAL_DM_PRE_SET_MEM* p_nfc_hal_dm_pre_set_mem;
76
77 /*****************************************************************************
78 ** Local function prototypes
79 *****************************************************************************/
80
81 /*******************************************************************************
82 **
83 ** Function nfc_hal_dm_set_config
84 **
85 ** Description Send NCI config items to NFCC
86 **
87 ** Returns tHAL_NFC_STATUS
88 **
89 *******************************************************************************/
nfc_hal_dm_set_config(uint8_t tlv_size,uint8_t * p_param_tlvs,tNFC_HAL_NCI_CBACK * p_cback)90 tHAL_NFC_STATUS nfc_hal_dm_set_config(uint8_t tlv_size, uint8_t* p_param_tlvs,
91 tNFC_HAL_NCI_CBACK* p_cback) {
92 uint8_t *p_buff, *p;
93 uint8_t num_param = 0, param_len, rem_len, *p_tlv;
94 uint16_t cmd_len = NCI_MSG_HDR_SIZE + tlv_size + 1;
95 tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
96
97 if ((tlv_size == 0) || (p_param_tlvs == NULL)) {
98 return status;
99 }
100
101 p_buff = (uint8_t*)GKI_getbuf((uint16_t)(NCI_MSG_HDR_SIZE + tlv_size));
102 if (p_buff != NULL) {
103 p = p_buff;
104
105 NCI_MSG_BLD_HDR0(p, NCI_MT_CMD, NCI_GID_CORE);
106 NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_SET_CONFIG);
107 UINT8_TO_STREAM(p, (uint8_t)(tlv_size + 1));
108
109 rem_len = tlv_size;
110 p_tlv = p_param_tlvs;
111 while (rem_len > 1) {
112 num_param++; /* number of params */
113
114 p_tlv++; /* param type */
115 param_len = *p_tlv++; /* param length */
116
117 rem_len -= 2; /* param type and length */
118 if (rem_len >= param_len) {
119 rem_len -= param_len;
120 p_tlv += param_len; /* next param_type */
121
122 if (rem_len == 0) {
123 status = HAL_NFC_STATUS_OK;
124 break;
125 }
126 } else {
127 /* error found */
128 break;
129 }
130 }
131
132 if (status == HAL_NFC_STATUS_OK) {
133 UINT8_TO_STREAM(p, num_param);
134 ARRAY_TO_STREAM(p, p_param_tlvs, tlv_size);
135
136 nfc_hal_dm_send_nci_cmd(p_buff, cmd_len, p_cback);
137 } else {
138 HAL_TRACE_ERROR0("nfc_hal_dm_set_config ():Bad TLV");
139 }
140
141 GKI_freebuf(p_buff);
142 }
143
144 return status;
145 }
146
147 /*******************************************************************************
148 **
149 ** Function nfc_hal_dm_set_fw_fsm
150 **
151 ** Description Enable or disable FW FSM
152 **
153 ** Returns void
154 **
155 *******************************************************************************/
nfc_hal_dm_set_fw_fsm(bool enable,tNFC_HAL_NCI_CBACK * p_cback)156 void nfc_hal_dm_set_fw_fsm(bool enable, tNFC_HAL_NCI_CBACK* p_cback) {
157 if (enable)
158 nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] =
159 0x01; /* Enable, default is disabled */
160 else
161 nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x00; /* Disable */
162
163 nfc_hal_dm_send_nci_cmd(nfc_hal_dm_set_fw_fsm_cmd, NCI_MSG_HDR_SIZE + 1,
164 p_cback);
165 }
166
167 /*******************************************************************************
168 **
169 ** Function nfc_hal_dm_config_nfcc_cback
170 **
171 ** Description Callback for NCI vendor specific command complete
172 **
173 ** Returns void
174 **
175 *******************************************************************************/
nfc_hal_dm_config_nfcc_cback(tNFC_HAL_NCI_EVT event,uint16_t data_len,uint8_t * p_data)176 void nfc_hal_dm_config_nfcc_cback(tNFC_HAL_NCI_EVT event, uint16_t data_len,
177 uint8_t* p_data) {
178 if (nfc_hal_cb.dev_cb.next_dm_config == NFC_HAL_DM_CONFIG_NONE) {
179 nfc_hal_hci_enable();
180 } else {
181 nfc_hal_dm_config_nfcc();
182 }
183 }
184
185 /*******************************************************************************
186 **
187 ** Function nfc_hal_dm_send_startup_vsc
188 **
189 ** Description Send VS command before NFA start-up
190 **
191 ** Returns None
192 **
193 *******************************************************************************/
nfc_hal_dm_send_startup_vsc(void)194 void nfc_hal_dm_send_startup_vsc(void) {
195 uint8_t *p, *p_end;
196 uint16_t len;
197
198 HAL_TRACE_DEBUG0("nfc_hal_dm_send_startup_vsc ()");
199
200 /* VSC must have NCI header at least */
201 if (nfc_hal_cb.dev_cb.next_startup_vsc + NCI_MSG_HDR_SIZE - 1 <=
202 *p_nfc_hal_dm_start_up_vsc_cfg) {
203 p = p_nfc_hal_dm_start_up_vsc_cfg + nfc_hal_cb.dev_cb.next_startup_vsc;
204 len = *(p + 2);
205 p_end = p + NCI_MSG_HDR_SIZE - 1 + len;
206
207 if (p_end <=
208 p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg) {
209 /* move to next VSC */
210 nfc_hal_cb.dev_cb.next_startup_vsc += NCI_MSG_HDR_SIZE + len;
211
212 /* if this is last VSC */
213 if (p_end ==
214 p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg)
215 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE;
216
217 nfc_hal_dm_send_nci_cmd(p, (uint16_t)(NCI_MSG_HDR_SIZE + len),
218 nfc_hal_dm_config_nfcc_cback);
219 return;
220 }
221 }
222
223 HAL_TRACE_ERROR0("nfc_hal_dm_send_startup_vsc (): Bad start-up VSC");
224
225 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
226 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
227 }
228
229 /*******************************************************************************
230 **
231 ** Function nfc_hal_dm_config_nfcc
232 **
233 ** Description Send VS config before NFA start-up
234 **
235 ** Returns void
236 **
237 *******************************************************************************/
nfc_hal_dm_config_nfcc(void)238 void nfc_hal_dm_config_nfcc(void) {
239 HAL_TRACE_DEBUG1("nfc_hal_dm_config_nfcc (): next_dm_config = %d",
240 nfc_hal_cb.dev_cb.next_dm_config);
241
242 if ((p_nfc_hal_dm_lptd_cfg[0]) &&
243 (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_LPTD)) {
244 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_PLL_325;
245
246 if (nfc_hal_dm_set_config(
247 p_nfc_hal_dm_lptd_cfg[0], &p_nfc_hal_dm_lptd_cfg[1],
248 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) {
249 return;
250 } else {
251 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
252 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT,
253 HAL_NFC_STATUS_FAILED);
254 return;
255 }
256 }
257
258 if ((p_nfc_hal_dm_pll_325_cfg) &&
259 (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_PLL_325)) {
260 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP;
261
262 if (nfc_hal_dm_set_config(
263 NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN, p_nfc_hal_dm_pll_325_cfg,
264 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) {
265 return;
266 } else {
267 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
268 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT,
269 HAL_NFC_STATUS_FAILED);
270 return;
271 }
272 }
273
274 if ((p_nfc_hal_dm_start_up_cfg[0]) &&
275 (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP)) {
276 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_I93_DATA_RATE;
277 if (nfc_hal_dm_set_config(
278 p_nfc_hal_dm_start_up_cfg[0], &p_nfc_hal_dm_start_up_cfg[1],
279 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) {
280 return;
281 } else {
282 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
283 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT,
284 HAL_NFC_STATUS_FAILED);
285 return;
286 }
287 }
288
289 #if (NFC_HAL_I93_FLAG_DATA_RATE == NFC_HAL_I93_FLAG_DATA_RATE_HIGH)
290 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_I93_DATA_RATE) {
291 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_FW_FSM;
292 if (nfc_hal_dm_set_config(NFC_HAL_I93_RW_CFG_LEN, nfc_hal_dm_i93_rw_cfg,
293 nfc_hal_dm_config_nfcc_cback) ==
294 HAL_NFC_STATUS_OK) {
295 return;
296 } else {
297 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
298 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT,
299 HAL_NFC_STATUS_FAILED);
300 return;
301 }
302 }
303 #endif
304
305 /* FW FSM is disabled as default in NFCC */
306 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_FW_FSM) {
307 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP_VSC;
308 nfc_hal_dm_set_fw_fsm(NFC_HAL_DM_MULTI_TECH_RESP,
309 nfc_hal_dm_config_nfcc_cback);
310 return;
311 }
312
313 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP_VSC) {
314 if (p_nfc_hal_dm_start_up_vsc_cfg && *p_nfc_hal_dm_start_up_vsc_cfg) {
315 nfc_hal_dm_send_startup_vsc();
316 return;
317 }
318 }
319
320 /* nothing to config */
321 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE;
322 nfc_hal_dm_config_nfcc_cback(0, 0, NULL);
323 }
324
325 /*******************************************************************************
326 **
327 ** Function: nfc_hal_dm_get_xtal_index
328 **
329 ** Description: Return Xtal index and frequency
330 **
331 ** Returns: tNFC_HAL_XTAL_INDEX
332 **
333 *******************************************************************************/
nfc_hal_dm_get_xtal_index(uint32_t brcm_hw_id,uint16_t * p_xtal_freq)334 tNFC_HAL_XTAL_INDEX nfc_hal_dm_get_xtal_index(uint32_t brcm_hw_id,
335 uint16_t* p_xtal_freq) {
336 uint8_t xx;
337
338 HAL_TRACE_DEBUG1("nfc_hal_dm_get_xtal_index() brcm_hw_id:0x%x", brcm_hw_id);
339
340 for (xx = 0; xx < nfc_post_reset_cb.dev_init_config.num_xtal_cfg; xx++) {
341 if ((brcm_hw_id & BRCM_NFC_GEN_MASK) ==
342 nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].brcm_hw_id) {
343 *p_xtal_freq = nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_freq;
344 return (nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_index);
345 }
346 }
347
348 /* if not found */
349 *p_xtal_freq = 0;
350 return (NFC_HAL_XTAL_INDEX_MAX);
351 }
352
353 /*******************************************************************************
354 **
355 ** Function nfc_hal_dm_set_xtal_freq_index
356 **
357 ** Description Set crystal frequency index
358 **
359 ** Returns void
360 **
361 *******************************************************************************/
nfc_hal_dm_set_xtal_freq_index(void)362 void nfc_hal_dm_set_xtal_freq_index(void) {
363 uint8_t nci_brcm_xtal_index_cmd[NCI_MSG_HDR_SIZE +
364 NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX];
365 uint8_t* p;
366 tNFC_HAL_XTAL_INDEX xtal_index;
367 uint16_t xtal_freq;
368 uint8_t cmd_len = NCI_PROP_PARAM_SIZE_XTAL_INDEX;
369 extern uint8_t* p_nfc_hal_dm_xtal_params_cfg;
370
371 HAL_TRACE_DEBUG1("nfc_hal_dm_set_xtal_freq_index (): brcm_hw_id = 0x%x",
372 nfc_hal_cb.dev_cb.brcm_hw_id);
373
374 xtal_index =
375 nfc_hal_dm_get_xtal_index(nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq);
376 if ((xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL) &&
377 (p_nfc_hal_dm_xtal_params_cfg)) {
378 cmd_len +=
379 p_nfc_hal_dm_xtal_params_cfg[0]; /* [0] is the length of extra params */
380 }
381
382 p = nci_brcm_xtal_index_cmd;
383 UINT8_TO_STREAM(p, (NCI_MTS_CMD | NCI_GID_PROP));
384 UINT8_TO_STREAM(p, NCI_MSG_GET_XTAL_INDEX_FROM_DH);
385 UINT8_TO_STREAM(p, cmd_len);
386 UINT8_TO_STREAM(p, xtal_index);
387 UINT16_TO_STREAM(p, xtal_freq);
388 if (cmd_len > NCI_PROP_PARAM_SIZE_XTAL_INDEX) {
389 memcpy(p, &p_nfc_hal_dm_xtal_params_cfg[1],
390 p_nfc_hal_dm_xtal_params_cfg[0]);
391 }
392
393 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_XTAL_SET);
394
395 nfc_hal_dm_send_nci_cmd(nci_brcm_xtal_index_cmd, NCI_MSG_HDR_SIZE + cmd_len,
396 NULL);
397 }
398
399 /*******************************************************************************
400 **
401 ** Function nfc_hal_dm_set_power_level_zero
402 **
403 ** Description set power level to 0
404 **
405 ** Returns None
406 **
407 *******************************************************************************/
nfc_hal_dm_set_power_level_zero(void)408 void nfc_hal_dm_set_power_level_zero(void) {
409 uint8_t
410 nci_brcm_set_pwr_level_cmd[NCI_MSG_HDR_SIZE + NCI_PARAM_LEN_POWER_LEVEL];
411 uint8_t* p;
412 uint8_t cmd_len = NCI_PARAM_LEN_POWER_LEVEL;
413
414 p = nci_brcm_set_pwr_level_cmd;
415 UINT8_TO_STREAM(p, (NCI_MTS_CMD | NCI_GID_PROP));
416 UINT8_TO_STREAM(p, NCI_MSG_POWER_LEVEL);
417 UINT8_TO_STREAM(p, NCI_PARAM_LEN_POWER_LEVEL);
418 memset(p, 0, NCI_PARAM_LEN_POWER_LEVEL);
419
420 nfc_hal_dm_send_nci_cmd(nci_brcm_set_pwr_level_cmd,
421 NCI_MSG_HDR_SIZE + cmd_len,
422 nfc_hal_main_exit_op_done);
423 }
424
425 /*******************************************************************************
426 **
427 ** Function nfc_hal_dm_send_get_build_info_cmd
428 **
429 ** Description Send NCI_MSG_GET_BUILD_INFO CMD
430 **
431 ** Returns void
432 **
433 *******************************************************************************/
nfc_hal_dm_send_get_build_info_cmd(void)434 void nfc_hal_dm_send_get_build_info_cmd(void) {
435 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_BUILD_INFO);
436
437 /* get build information to find out HW */
438 nfc_hal_dm_send_nci_cmd(nfc_hal_dm_get_build_info_cmd, NCI_MSG_HDR_SIZE,
439 NULL);
440 }
441 /*******************************************************************************
442 **
443 ** Function: nfc_hal_dm_adjust_hw_id
444 **
445 ** Description: The hw_id of certain chips are shifted by 8 bits.
446 ** Adjust the hw_id before processing.
447 **
448 ** Returns: Nothing
449 **
450 *******************************************************************************/
nfc_hal_dm_adjust_hw_id(uint32_t hw_id)451 static uint32_t nfc_hal_dm_adjust_hw_id(uint32_t hw_id) {
452 if ((hw_id & 0xF0000000) == 0)
453 hw_id <<= 4; /* shift hw_id by 4 bits to align w the format of most chips */
454 return hw_id;
455 }
456
457 /*******************************************************************************
458 **
459 ** Function nfc_hal_dm_check_xtal
460 **
461 ** Description check if need to send xtal command.
462 ** If not, proceed to next step get_patch_version.
463 **
464 ** Returns void
465 **
466 *******************************************************************************/
nfc_hal_dm_check_xtal(void)467 static void nfc_hal_dm_check_xtal(void) {
468 uint16_t xtal_freq;
469 tNFC_HAL_XTAL_INDEX xtal_index;
470
471 /* if NFCC needs to set Xtal frequency before getting patch version */
472 xtal_index =
473 nfc_hal_dm_get_xtal_index(nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq);
474 if ((xtal_index < NFC_HAL_XTAL_INDEX_MAX) ||
475 (xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL)) {
476 {
477 /* set Xtal index before getting patch version */
478 nfc_hal_dm_set_xtal_freq_index();
479 return;
480 }
481 }
482
483 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PATCH_INFO);
484
485 nfc_hal_dm_send_nci_cmd(nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE,
486 NULL);
487 }
488
489 /*******************************************************************************
490 **
491 ** Function nfc_hal_dm_pre_set_mem_cback
492 **
493 ** Description This is pre-set mem complete callback.
494 **
495 ** Returns void
496 **
497 *******************************************************************************/
nfc_hal_dm_pre_set_mem_cback(tNFC_HAL_BTVSC_CPLT * pData)498 static void nfc_hal_dm_pre_set_mem_cback(tNFC_HAL_BTVSC_CPLT* pData) {
499 uint8_t status = pData->p_param_buf[0];
500
501 HAL_TRACE_DEBUG1("nfc_hal_dm_pre_set_mem_cback: %d", status);
502 /* if it is completed */
503 if (status == HCI_SUCCESS) {
504 if (!nfc_hal_dm_check_pre_set_mem()) {
505 return;
506 }
507 }
508 nfc_hal_dm_check_xtal();
509 }
510
511 /*******************************************************************************
512 **
513 ** Function nfc_hal_dm_check_pre_set_mem
514 **
515 ** Description Check if need to send the command.
516 **
517 ** Returns TRUE if done.
518 **
519 *******************************************************************************/
nfc_hal_dm_check_pre_set_mem(void)520 bool nfc_hal_dm_check_pre_set_mem(void) {
521 uint8_t cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH];
522 uint8_t* p;
523 uint32_t addr = 0;
524
525 if (p_nfc_hal_dm_pre_set_mem)
526 addr = p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].addr;
527 HAL_TRACE_DEBUG2("nfc_hal_dm_check_pre_set_mem: %d/0x%x",
528 nfc_hal_cb.pre_set_mem_idx, addr);
529 if (addr == 0) {
530 return true;
531 }
532 p = cmd;
533
534 /* Add the command */
535 UINT16_TO_STREAM(p, HCI_BRCM_PRE_SET_MEM);
536 UINT8_TO_STREAM(p, HCI_BRCM_PRE_SET_MEM_LENGTH);
537
538 UINT8_TO_STREAM(p, HCI_BRCM_PRE_SET_MEM_TYPE);
539 UINT32_TO_STREAM(p, addr);
540 UINT8_TO_STREAM(p, 0);
541 UINT32_TO_STREAM(p,
542 p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].data);
543 nfc_hal_cb.pre_set_mem_idx++;
544
545 nfc_hal_dm_send_bt_cmd(
546 cmd, NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH,
547 nfc_hal_dm_pre_set_mem_cback);
548 return false;
549 }
550
551 /*******************************************************************************
552 **
553 ** Function nfc_hal_dm_got_vs_rsp
554 **
555 ** Description Received VS RSP. Clean up control block to allow next NCI
556 *cmd
557 **
558 ** Returns void
559 **
560 *******************************************************************************/
nfc_hal_dm_got_vs_rsp(void)561 tNFC_HAL_NCI_CBACK* nfc_hal_dm_got_vs_rsp(void) {
562 tNFC_HAL_NCI_CBACK* p_cback = NULL;
563 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
564 p_cback = (tNFC_HAL_NCI_CBACK*)nfc_hal_cb.ncit_cb.p_vsc_cback;
565 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL;
566 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
567 return p_cback;
568 }
569
570 /*******************************************************************************
571 **
572 ** Function nfc_hal_dm_proc_msg_during_init
573 **
574 ** Description Process NCI message while initializing NFCC
575 **
576 ** Returns void
577 **
578 *******************************************************************************/
nfc_hal_dm_proc_msg_during_init(NFC_HDR * p_msg)579 void nfc_hal_dm_proc_msg_during_init(NFC_HDR* p_msg) {
580 uint8_t* p;
581 uint8_t reset_reason, reset_type;
582 uint8_t mt, pbf, gid, op_code;
583 uint8_t *p_old, old_gid, old_oid, old_mt;
584 uint8_t u8;
585 tNFC_HAL_NCI_CBACK* p_cback = NULL;
586 uint8_t chipverlen;
587 uint8_t chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
588 uint32_t hw_id = 0;
589
590 HAL_TRACE_DEBUG1("nfc_hal_dm_proc_msg_during_init(): init state:%d",
591 nfc_hal_cb.dev_cb.initializing_state);
592
593 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
594
595 NCI_MSG_PRS_HDR0(p, mt, pbf, gid);
596 NCI_MSG_PRS_HDR1(p, op_code);
597
598 /* check if waiting for this response */
599 if ((nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD) ||
600 (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC)) {
601 if (mt == NCI_MT_RSP) {
602 p_old = nfc_hal_cb.ncit_cb.last_hdr;
603 NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid);
604 old_oid = ((*p_old) & NCI_OID_MASK);
605 /* make sure this is the RSP we are waiting for before updating the
606 * command window */
607 if ((old_gid == gid) && (old_oid == op_code)) {
608 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
609 p_cback = (tNFC_HAL_NCI_CBACK*)nfc_hal_cb.ncit_cb.p_vsc_cback;
610 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL;
611 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
612 }
613 }
614 }
615
616 if (gid == NCI_GID_CORE) {
617 if (op_code == NCI_MSG_CORE_RESET) {
618 if (mt == NCI_MT_NTF) {
619 if ((nfc_hal_cb.dev_cb.initializing_state ==
620 NFC_HAL_INIT_STATE_W4_NFCC_ENABLE) ||
621 (nfc_hal_cb.dev_cb.initializing_state ==
622 NFC_HAL_INIT_STATE_POST_XTAL_SET)) {
623 /*
624 ** Core reset ntf in the following cases;
625 ** 1) after power up (raising REG_PU)
626 ** 2) after setting xtal index
627 ** Start pre-initializing NFCC
628 */
629 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.timer);
630 nfc_hal_dm_pre_init_nfcc();
631 } else {
632 /* Core reset ntf after post-patch download, Call reset notification
633 * callback */
634 p++; /* Skip over param len */
635 STREAM_TO_UINT8(reset_reason, p);
636 STREAM_TO_UINT8(reset_type, p);
637 nfc_hal_prm_spd_reset_ntf(reset_reason, reset_type);
638 }
639 }
640 } else if (p_cback) {
641 (*p_cback)((tNFC_HAL_NCI_EVT)(op_code), p_msg->len,
642 (uint8_t*)(p_msg + 1) + p_msg->offset);
643 }
644 } else if (gid == NCI_GID_PROP) /* this is for download patch */
645 {
646 if (mt == NCI_MT_NTF)
647 op_code |= NCI_NTF_BIT;
648 else
649 op_code |= NCI_RSP_BIT;
650
651 if (nfc_hal_cb.dev_cb.initializing_state ==
652 NFC_HAL_INIT_STATE_W4_XTAL_SET) {
653 if (op_code == (NCI_RSP_BIT | NCI_MSG_GET_XTAL_INDEX_FROM_DH)) {
654 /* start timer in case that NFCC doesn't send RESET NTF after loading
655 * patch from NVM */
656 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_POST_XTAL_SET);
657
658 nfc_hal_main_start_quick_timer(
659 &nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
660 ((p_nfc_hal_cfg->nfc_hal_post_xtal_timeout) *
661 QUICK_TIMER_TICKS_PER_SEC) /
662 1000);
663 }
664 } else if ((op_code == NFC_VS_GET_BUILD_INFO_EVT) &&
665 (nfc_hal_cb.dev_cb.initializing_state ==
666 NFC_HAL_INIT_STATE_W4_BUILD_INFO)) {
667 p += NCI_BUILD_INFO_OFFSET_HWID;
668
669 STREAM_TO_UINT32(hw_id, p);
670 nfc_hal_cb.dev_cb.brcm_hw_id = nfc_hal_dm_adjust_hw_id(hw_id);
671 HAL_TRACE_DEBUG2("brcm_hw_id: 0x%x -> 0x%x", hw_id,
672 nfc_hal_cb.dev_cb.brcm_hw_id);
673
674 STREAM_TO_UINT8(chipverlen, p);
675 memset(chipverstr, 0, NCI_SPD_HEADER_CHIPVER_LEN);
676
677 STREAM_TO_ARRAY(chipverstr, p, chipverlen);
678
679 /* If chip is not 20791 and 43341, set flag to send the "Disable" VSC */
680 if (((nfc_hal_cb.dev_cb.brcm_hw_id & BRCM_NFC_GEN_MASK) !=
681 BRCM_NFC_20791_GEN) &&
682 ((nfc_hal_cb.dev_cb.brcm_hw_id & BRCM_NFC_GEN_MASK) !=
683 BRCM_NFC_43341_GEN)) {
684 nfc_hal_cb.hal_flags |= NFC_HAL_FLAGS_NEED_DISABLE_VSC;
685 }
686
687 nfc_hal_hci_handle_build_info(chipverlen, chipverstr);
688 nfc_hal_cb.pre_set_mem_idx = 0;
689 if (!nfc_hal_dm_check_pre_set_mem()) {
690 /* pre-set mem started */
691 return;
692 }
693 nfc_hal_dm_check_xtal();
694 } else if ((op_code == NFC_VS_GET_PATCH_VERSION_EVT) &&
695 (nfc_hal_cb.dev_cb.initializing_state ==
696 NFC_HAL_INIT_STATE_W4_PATCH_INFO)) {
697 /* Store NVM info to control block */
698
699 /* Skip over rsp len */
700 p++;
701
702 /* Get project id */
703 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.project_id, p);
704
705 /* RFU */
706 p++;
707
708 /* Get chip version string */
709 STREAM_TO_UINT8(u8, p);
710 if (u8 > NFC_HAL_PRM_MAX_CHIP_VER_LEN) u8 = NFC_HAL_PRM_MAX_CHIP_VER_LEN;
711 memcpy(nfc_hal_cb.nvm_cb.chip_ver, p, u8);
712 p += NCI_PATCH_INFO_VERSION_LEN;
713
714 /* Get major/minor version */
715 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.ver_major, p);
716 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.ver_minor, p);
717
718 /* Skip over max_size and patch_max_size */
719 p += 4;
720
721 /* Get current lpm patch size */
722 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.lpm_size, p);
723 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.fpm_size, p);
724
725 /* clear all flags which may be set during previous initialization */
726 nfc_hal_cb.nvm_cb.flags = 0;
727
728 /* Set patch present flag */
729 if ((nfc_hal_cb.nvm_cb.fpm_size) || (nfc_hal_cb.nvm_cb.lpm_size))
730 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_PATCH_PRESENT;
731
732 /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is
733 * present in nvm) */
734 STREAM_TO_UINT8(u8, p);
735 if (u8) {
736 /* LPM patch in NVM fails CRC check */
737 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_LPM_BAD;
738 }
739
740 /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is
741 * present in nvm) */
742 STREAM_TO_UINT8(u8, p);
743 if (u8) {
744 /* FPM patch in NVM fails CRC check */
745 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_FPM_BAD;
746 }
747
748 /* Check if downloading patch to RAM only (no NVM) */
749 STREAM_TO_UINT8(nfc_hal_cb.nvm_cb.nvm_type, p);
750 if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE) {
751 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_NO_NVM;
752 }
753
754 /* let platform update baudrate or download patch */
755 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_APP_COMPLETE);
756 nfc_hal_post_reset_init(nfc_hal_cb.dev_cb.brcm_hw_id,
757 nfc_hal_cb.nvm_cb.nvm_type);
758 } else if (p_cback) {
759 (*p_cback)((tNFC_HAL_NCI_EVT)(op_code), p_msg->len,
760 (uint8_t*)(p_msg + 1) + p_msg->offset);
761 } else if (op_code == NFC_VS_SEC_PATCH_AUTH_EVT) {
762 HAL_TRACE_DEBUG0("signature!!");
763 nfc_hal_prm_nci_command_complete_cback(
764 (tNFC_HAL_NCI_EVT)(op_code), p_msg->len,
765 (uint8_t*)(p_msg + 1) + p_msg->offset);
766 }
767 }
768 }
769
770 /*******************************************************************************
771 **
772 ** Function nfc_hal_dm_proc_msg_during_exit
773 **
774 ** Description Process NCI message while shutting down NFCC
775 **
776 ** Returns void
777 **
778 *******************************************************************************/
nfc_hal_dm_proc_msg_during_exit(NFC_HDR * p_msg)779 void nfc_hal_dm_proc_msg_during_exit(NFC_HDR* p_msg) {
780 uint8_t* p;
781 uint8_t mt, pbf, gid, op_code;
782 uint8_t *p_old, old_gid, old_oid, old_mt;
783 uint8_t u8;
784 tNFC_HAL_NCI_CBACK* p_cback = NULL;
785
786 HAL_TRACE_DEBUG1("nfc_hal_dm_proc_msg_during_exit(): state:%d",
787 nfc_hal_cb.dev_cb.initializing_state);
788
789 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
790
791 NCI_MSG_PRS_HDR0(p, mt, pbf, gid);
792 NCI_MSG_PRS_HDR1(p, op_code);
793 u8 = *p;
794
795 /* check if waiting for this response */
796 if ((nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD) ||
797 (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC)) {
798 if (mt == NCI_MT_RSP) {
799 p_old = nfc_hal_cb.ncit_cb.last_hdr;
800 NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid);
801 old_oid = ((*p_old) & NCI_OID_MASK);
802 /* make sure this is the RSP we are waiting for before updating the
803 * command window */
804 if ((old_gid == gid) && (old_oid == op_code)) {
805 p_cback = nfc_hal_dm_got_vs_rsp();
806 if (p_cback) {
807 if (gid == NCI_GID_PROP) {
808 if (mt == NCI_MT_NTF)
809 op_code |= NCI_NTF_BIT;
810 else
811 op_code |= NCI_RSP_BIT;
812
813 if (op_code == NFC_VS_POWER_LEVEL_RSP) {
814 (*p_cback)((tNFC_HAL_NCI_EVT)(op_code), p_msg->len,
815 (uint8_t*)(p_msg + 1) + p_msg->offset);
816 }
817 }
818 }
819 }
820 }
821 }
822 }
823
824 /*******************************************************************************
825 **
826 ** Function nfc_hal_dm_send_nci_cmd
827 **
828 ** Description Send NCI command to NFCC while initializing BRCM NFCC
829 **
830 ** Returns void
831 **
832 *******************************************************************************/
nfc_hal_dm_send_nci_cmd(const uint8_t * p_data,uint16_t len,tNFC_HAL_NCI_CBACK * p_cback)833 void nfc_hal_dm_send_nci_cmd(const uint8_t* p_data, uint16_t len,
834 tNFC_HAL_NCI_CBACK* p_cback) {
835 NFC_HDR* p_buf;
836 uint8_t* ps;
837
838 HAL_TRACE_DEBUG1("nfc_hal_dm_send_nci_cmd (): nci_wait_rsp = 0x%x",
839 nfc_hal_cb.ncit_cb.nci_wait_rsp);
840
841 if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) {
842 HAL_TRACE_ERROR0("nfc_hal_dm_send_nci_cmd(): no command window");
843 return;
844 }
845
846 p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID);
847 if (p_buf != NULL) {
848 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_VSC;
849
850 p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
851 p_buf->event = NFC_HAL_EVT_TO_NFC_NCI;
852 p_buf->len = len;
853
854 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, len);
855
856 /* Keep a copy of the command and send to NCI transport */
857
858 /* save the message header to double check the response */
859 ps = (uint8_t*)(p_buf + 1) + p_buf->offset;
860 memcpy(nfc_hal_cb.ncit_cb.last_hdr, ps, NFC_HAL_SAVED_HDR_SIZE);
861 memcpy(nfc_hal_cb.ncit_cb.last_cmd, ps + NCI_MSG_HDR_SIZE,
862 NFC_HAL_SAVED_CMD_SIZE);
863
864 /* save the callback for NCI VSCs */
865 nfc_hal_cb.ncit_cb.p_vsc_cback = (void*)p_cback;
866
867 nfc_hal_nci_send_cmd(p_buf);
868
869 /* start NFC command-timeout timer */
870 nfc_hal_main_start_quick_timer(
871 &nfc_hal_cb.ncit_cb.nci_wait_rsp_timer,
872 (uint16_t)(NFC_HAL_TTYPE_NCI_WAIT_RSP),
873 ((uint32_t)NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
874 }
875 }
876
877 /*******************************************************************************
878 **
879 ** Function nfc_hal_dm_send_pend_cmd
880 **
881 ** Description Send a command to NFCC
882 **
883 ** Returns void
884 **
885 *******************************************************************************/
nfc_hal_dm_send_pend_cmd(void)886 void nfc_hal_dm_send_pend_cmd(void) {
887 NFC_HDR* p_buf = nfc_hal_cb.ncit_cb.p_pend_cmd;
888 uint8_t* p;
889
890 if (p_buf == NULL) return;
891
892 /* check low power mode state */
893 if (!nfc_hal_dm_power_mode_execute(NFC_HAL_LP_TX_DATA_EVT)) {
894 return;
895 }
896
897 if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP) {
898 #if (NFC_HAL_TRACE_PROTOCOL == TRUE)
899 DispHciCmd(p_buf);
900 #endif
901
902 /* save the message header to double check the response */
903 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
904 memcpy(nfc_hal_cb.ncit_cb.last_hdr, p, NFC_HAL_SAVED_HDR_SIZE);
905
906 /* add packet type for BT message */
907 p_buf->offset--;
908 p_buf->len++;
909
910 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
911 *p = HCIT_TYPE_COMMAND;
912
913 USERIAL_Write(USERIAL_NFC_PORT, p, p_buf->len);
914
915 GKI_freebuf(p_buf);
916 nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
917
918 /* start NFC command-timeout timer */
919 nfc_hal_main_start_quick_timer(
920 &nfc_hal_cb.ncit_cb.nci_wait_rsp_timer,
921 (uint16_t)(NFC_HAL_TTYPE_NCI_WAIT_RSP),
922 ((uint32_t)NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
923 }
924 }
925
926 /*******************************************************************************
927 **
928 ** Function nfc_hal_dm_send_bt_cmd
929 **
930 ** Description Send BT message to NFCC while initializing BRCM NFCC
931 **
932 ** Returns void
933 **
934 *******************************************************************************/
nfc_hal_dm_send_bt_cmd(const uint8_t * p_data,uint16_t len,tNFC_HAL_BTVSC_CPLT_CBACK * p_cback)935 void nfc_hal_dm_send_bt_cmd(const uint8_t* p_data, uint16_t len,
936 tNFC_HAL_BTVSC_CPLT_CBACK* p_cback) {
937 NFC_HDR* p_buf;
938 char buff[300];
939 char tmp[4];
940 buff[0] = 0;
941 int i;
942
943 HAL_TRACE_DEBUG1("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x",
944 nfc_hal_cb.ncit_cb.nci_wait_rsp);
945
946 for (i = 0; i < len; i++) {
947 sprintf(tmp, "%02x ", p_data[i]);
948 strcat(buff, tmp);
949 }
950 HAL_TRACE_DEBUG2("nfc_hal_dm_send_bt_cmd (): HCI Write (%d bytes): %s", len,
951 buff);
952
953 if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) {
954 HAL_TRACE_ERROR0("nfc_hal_dm_send_bt_cmd(): no command window");
955 return;
956 }
957
958 p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID);
959 if (p_buf != NULL) {
960 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP;
961
962 p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
963 p_buf->len = len;
964
965 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, len);
966
967 /* save the callback for NCI VSCs) */
968 nfc_hal_cb.ncit_cb.p_vsc_cback = (void*)p_cback;
969
970 nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf;
971 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE) {
972 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE);
973 nfc_hal_cb.p_stack_cback(HAL_NFC_REQUEST_CONTROL_EVT, HAL_NFC_STATUS_OK);
974 return;
975 }
976
977 nfc_hal_dm_send_pend_cmd();
978 }
979 }
980
981 /*******************************************************************************
982 **
983 ** Function nfc_hal_dm_set_nfc_wake
984 **
985 ** Description Set NFC_WAKE line
986 **
987 ** Returns void
988 **
989 *******************************************************************************/
nfc_hal_dm_set_nfc_wake(uint8_t cmd)990 void nfc_hal_dm_set_nfc_wake(uint8_t cmd) {
991 HAL_TRACE_DEBUG1("nfc_hal_dm_set_nfc_wake () %s",
992 (cmd == NFC_HAL_ASSERT_NFC_WAKE ? "ASSERT" : "DEASSERT"));
993
994 /*
995 ** nfc_wake_active_mode cmd result of voltage on
996 *NFC_WAKE
997 **
998 ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_ASSERT_NFC_WAKE (0) pull down
999 *NFC_WAKE (GND)
1000 ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_DEASSERT_NFC_WAKE (1) pull up
1001 *NFC_WAKE (VCC)
1002 ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_ASSERT_NFC_WAKE (0) pull up
1003 *NFC_WAKE (VCC)
1004 ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_DEASSERT_NFC_WAKE (1) pull down
1005 *NFC_WAKE (GND)
1006 */
1007
1008 if (cmd == nfc_hal_cb.dev_cb.nfc_wake_active_mode)
1009 UPIO_Set(UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO,
1010 UPIO_OFF); /* pull down NFC_WAKE */
1011 else
1012 UPIO_Set(UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO,
1013 UPIO_ON); /* pull up NFC_WAKE */
1014 }
1015
1016 /*******************************************************************************
1017 **
1018 ** Function nfc_hal_dm_power_mode_execute
1019 **
1020 ** Description If snooze mode is enabled in full power mode,
1021 ** Assert NFC_WAKE before sending data
1022 ** Deassert NFC_WAKE when idle timer expires
1023 **
1024 ** Returns TRUE if DH can send data to NFCC
1025 **
1026 *******************************************************************************/
nfc_hal_dm_power_mode_execute(tNFC_HAL_LP_EVT event)1027 bool nfc_hal_dm_power_mode_execute(tNFC_HAL_LP_EVT event) {
1028 bool send_to_nfcc = false;
1029
1030 HAL_TRACE_DEBUG1("nfc_hal_dm_power_mode_execute () event = %d", event);
1031
1032 if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) {
1033 if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) {
1034 /* if any transport activity */
1035 if ((event == NFC_HAL_LP_TX_DATA_EVT) ||
1036 (event == NFC_HAL_LP_RX_DATA_EVT)) {
1037 /* if idle timer is not running */
1038 if (nfc_hal_cb.dev_cb.lp_timer.in_use == false) {
1039 nfc_hal_dm_set_nfc_wake(NFC_HAL_ASSERT_NFC_WAKE);
1040 }
1041
1042 /* start or extend idle timer */
1043 nfc_hal_main_start_quick_timer(&nfc_hal_cb.dev_cb.lp_timer, 0x00,
1044 ((uint32_t)NFC_HAL_LP_IDLE_TIMEOUT) *
1045 QUICK_TIMER_TICKS_PER_SEC / 1000);
1046 } else if (event == NFC_HAL_LP_TIMEOUT_EVT) {
1047 /* let NFCC go to snooze mode */
1048 nfc_hal_dm_set_nfc_wake(NFC_HAL_DEASSERT_NFC_WAKE);
1049 }
1050 }
1051
1052 send_to_nfcc = true;
1053 }
1054
1055 return (send_to_nfcc);
1056 }
1057
1058 /*******************************************************************************
1059 **
1060 ** Function nci_brcm_lp_timeout_cback
1061 **
1062 ** Description callback function for low power timeout
1063 **
1064 ** Returns void
1065 **
1066 *******************************************************************************/
nci_brcm_lp_timeout_cback(void * p_tle)1067 static void nci_brcm_lp_timeout_cback(void* p_tle) {
1068 HAL_TRACE_DEBUG0("nci_brcm_lp_timeout_cback ()");
1069
1070 nfc_hal_dm_power_mode_execute(NFC_HAL_LP_TIMEOUT_EVT);
1071 }
1072
1073 /*******************************************************************************
1074 **
1075 ** Function nfc_hal_dm_pre_init_nfcc
1076 **
1077 ** Description This function initializes Broadcom specific control blocks
1078 *for
1079 ** NCI transport
1080 **
1081 ** Returns void
1082 **
1083 *******************************************************************************/
nfc_hal_dm_pre_init_nfcc(void)1084 void nfc_hal_dm_pre_init_nfcc(void) {
1085 HAL_TRACE_DEBUG0("nfc_hal_dm_pre_init_nfcc ()");
1086
1087 /* if it was waiting for core reset notification after raising REG_PU */
1088 if (nfc_hal_cb.dev_cb.initializing_state ==
1089 NFC_HAL_INIT_STATE_W4_NFCC_ENABLE) {
1090 nfc_hal_dm_send_get_build_info_cmd();
1091 }
1092 /* if it was waiting for core reset notification after setting Xtal */
1093 else if (nfc_hal_cb.dev_cb.initializing_state ==
1094 NFC_HAL_INIT_STATE_POST_XTAL_SET) {
1095 {
1096 /* Core reset ntf after xtal setting indicating NFCC loaded patch from NVM
1097 */
1098 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PATCH_INFO);
1099
1100 nfc_hal_dm_send_nci_cmd(nfc_hal_dm_get_patch_version_cmd,
1101 NCI_MSG_HDR_SIZE, NULL);
1102 }
1103 }
1104 }
1105
1106 /*******************************************************************************
1107 **
1108 ** Function nfc_hal_dm_shutting_down_nfcc
1109 **
1110 ** Description This function initializes Broadcom specific control blocks
1111 *for
1112 ** NCI transport
1113 **
1114 ** Returns void
1115 **
1116 *******************************************************************************/
nfc_hal_dm_shutting_down_nfcc(void)1117 void nfc_hal_dm_shutting_down_nfcc(void) {
1118 HAL_TRACE_DEBUG0("nfc_hal_dm_shutting_down_nfcc ()");
1119
1120 nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_CLOSING;
1121
1122 /* reset low power mode variables */
1123 if ((nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) &&
1124 (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)) {
1125 nfc_hal_dm_set_nfc_wake(NFC_HAL_ASSERT_NFC_WAKE);
1126 }
1127
1128 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
1129
1130 nfc_hal_cb.dev_cb.power_mode = NFC_HAL_POWER_MODE_FULL;
1131 nfc_hal_cb.dev_cb.snooze_mode = NFC_HAL_LP_SNOOZE_MODE_NONE;
1132
1133 /* Stop all timers */
1134 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
1135 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.dev_cb.lp_timer);
1136 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.prm.timer);
1137 #if (NFC_HAL_HCI_INCLUDED == TRUE)
1138 nfc_hal_cb.hci_cb.hcp_conn_id = 0;
1139 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.hci_cb.hci_timer);
1140 #endif
1141 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.timer);
1142 }
1143
1144 /*******************************************************************************
1145 **
1146 ** Function nfc_hal_dm_init
1147 **
1148 ** Description This function initializes Broadcom specific control blocks
1149 *for
1150 ** NCI transport
1151 **
1152 ** Returns void
1153 **
1154 *******************************************************************************/
nfc_hal_dm_init(void)1155 void nfc_hal_dm_init(void) {
1156 HAL_TRACE_DEBUG0("nfc_hal_dm_init ()");
1157
1158 nfc_hal_cb.dev_cb.lp_timer.p_cback = nci_brcm_lp_timeout_cback;
1159
1160 nfc_hal_cb.ncit_cb.nci_wait_rsp_timer.p_cback = nfc_hal_nci_cmd_timeout_cback;
1161
1162 #if (NFC_HAL_HCI_INCLUDED == TRUE)
1163 nfc_hal_cb.hci_cb.hci_timer.p_cback = nfc_hal_hci_timeout_cback;
1164 #endif
1165
1166 nfc_hal_cb.pre_discover_done = false;
1167
1168 nfc_post_reset_cb.spd_nvm_detection_cur_count = 0;
1169 nfc_post_reset_cb.spd_skip_on_power_cycle = false;
1170 }
1171
1172 /*******************************************************************************
1173 **
1174 ** Function HAL_NfcDevInitDone
1175 **
1176 ** Description Notify that pre-initialization of NFCC is complete
1177 **
1178 ** Returns void
1179 **
1180 *******************************************************************************/
HAL_NfcPreInitDone(tHAL_NFC_STATUS status)1181 void HAL_NfcPreInitDone(tHAL_NFC_STATUS status) {
1182 HAL_TRACE_DEBUG1("HAL_NfcPreInitDone () status=%d", status);
1183
1184 if (nfc_hal_cb.dev_cb.initializing_state ==
1185 NFC_HAL_INIT_STATE_W4_APP_COMPLETE) {
1186 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
1187
1188 nfc_hal_main_pre_init_done(status);
1189 }
1190 }
1191
1192 /*******************************************************************************
1193 **
1194 ** Function HAL_NfcReInit
1195 **
1196 ** Description This function is called to restart initialization after
1197 *REG_PU
1198 ** toggled because of failure to detect NVM type or download
1199 *patchram.
1200 **
1201 ** Note This function should be called only during the HAL init
1202 *process
1203 **
1204 ** Returns HAL_NFC_STATUS_OK if successfully initiated
1205 ** HAL_NFC_STATUS_FAILED otherwise
1206 **
1207 *******************************************************************************/
HAL_NfcReInit(void)1208 tHAL_NFC_STATUS HAL_NfcReInit(void) {
1209 tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
1210
1211 HAL_TRACE_DEBUG1("HAL_NfcReInit () init st=0x%x",
1212 nfc_hal_cb.dev_cb.initializing_state);
1213 if (nfc_hal_cb.dev_cb.initializing_state ==
1214 NFC_HAL_INIT_STATE_W4_APP_COMPLETE) {
1215 {
1216 /* Wait for NFCC to enable - Core reset notification */
1217 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
1218
1219 /* NFCC Enable timeout */
1220 nfc_hal_main_start_quick_timer(
1221 &nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
1222 ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout) *
1223 QUICK_TIMER_TICKS_PER_SEC) /
1224 1000);
1225 }
1226
1227 status = HAL_NFC_STATUS_OK;
1228 }
1229 return status;
1230 }
1231
1232 /*******************************************************************************
1233 **
1234 ** Function nfc_hal_dm_set_snooze_mode_cback
1235 **
1236 ** Description This is snooze update complete callback.
1237 **
1238 ** Returns void
1239 **
1240 *******************************************************************************/
nfc_hal_dm_set_snooze_mode_cback(tNFC_HAL_BTVSC_CPLT * pData)1241 static void nfc_hal_dm_set_snooze_mode_cback(tNFC_HAL_BTVSC_CPLT* pData) {
1242 uint8_t status = pData->p_param_buf[0];
1243 tHAL_NFC_STATUS hal_status;
1244 tHAL_NFC_STATUS_CBACK* p_cback;
1245
1246 /* if it is completed */
1247 if (status == HCI_SUCCESS) {
1248 /* update snooze mode */
1249 nfc_hal_cb.dev_cb.snooze_mode = nfc_hal_cb.dev_cb.new_snooze_mode;
1250
1251 nfc_hal_dm_set_nfc_wake(NFC_HAL_ASSERT_NFC_WAKE);
1252
1253 if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) {
1254 /* start idle timer */
1255 nfc_hal_main_start_quick_timer(&nfc_hal_cb.dev_cb.lp_timer, 0x00,
1256 ((uint32_t)NFC_HAL_LP_IDLE_TIMEOUT) *
1257 QUICK_TIMER_TICKS_PER_SEC / 1000);
1258 } else {
1259 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.dev_cb.lp_timer);
1260 }
1261 hal_status = HAL_NFC_STATUS_OK;
1262 } else {
1263 hal_status = HAL_NFC_STATUS_FAILED;
1264 }
1265
1266 if (nfc_hal_cb.dev_cb.p_prop_cback) {
1267 p_cback = nfc_hal_cb.dev_cb.p_prop_cback;
1268 nfc_hal_cb.dev_cb.p_prop_cback = NULL;
1269 (*p_cback)(hal_status);
1270 }
1271 }
1272
1273 /*******************************************************************************
1274 **
1275 ** Function HAL_NfcSetSnoozeMode
1276 **
1277 ** Description Set snooze mode
1278 ** snooze_mode
1279 ** NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled
1280 ** NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART
1281 ** NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C
1282 **
1283 ** idle_threshold_dh/idle_threshold_nfcc
1284 ** Idle Threshold Host in 100ms unit
1285 **
1286 ** nfc_wake_active_mode/dh_wake_active_mode
1287 ** NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting
1288 ** NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is
1289 *asserting
1290 **
1291 ** p_snooze_cback
1292 ** Notify status of operation
1293 **
1294 ** Returns tHAL_NFC_STATUS
1295 **
1296 *******************************************************************************/
HAL_NfcSetSnoozeMode(uint8_t snooze_mode,uint8_t idle_threshold_dh,uint8_t idle_threshold_nfcc,uint8_t nfc_wake_active_mode,uint8_t dh_wake_active_mode,tHAL_NFC_STATUS_CBACK * p_snooze_cback)1297 tHAL_NFC_STATUS HAL_NfcSetSnoozeMode(uint8_t snooze_mode,
1298 uint8_t idle_threshold_dh,
1299 uint8_t idle_threshold_nfcc,
1300 uint8_t nfc_wake_active_mode,
1301 uint8_t dh_wake_active_mode,
1302 tHAL_NFC_STATUS_CBACK* p_snooze_cback) {
1303 uint8_t cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH];
1304 uint8_t* p;
1305
1306 HAL_TRACE_API1("HAL_NfcSetSnoozeMode (): snooze_mode = %d", snooze_mode);
1307
1308 nfc_hal_cb.dev_cb.new_snooze_mode = snooze_mode;
1309 nfc_hal_cb.dev_cb.nfc_wake_active_mode = nfc_wake_active_mode;
1310 nfc_hal_cb.dev_cb.p_prop_cback = p_snooze_cback;
1311
1312 p = cmd;
1313
1314 /* Add the HCI command */
1315 UINT16_TO_STREAM(p, HCI_BRCM_WRITE_SLEEP_MODE);
1316 UINT8_TO_STREAM(p, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);
1317
1318 memset(p, 0x00, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);
1319
1320 UINT8_TO_STREAM(p, snooze_mode); /* Sleep Mode */
1321
1322 UINT8_TO_STREAM(p, idle_threshold_dh); /* Idle Threshold Host */
1323 UINT8_TO_STREAM(p, idle_threshold_nfcc); /* Idle Threshold HC */
1324 UINT8_TO_STREAM(p, nfc_wake_active_mode); /* BT Wake Active Mode */
1325 UINT8_TO_STREAM(p, dh_wake_active_mode); /* Host Wake Active Mode */
1326
1327 nfc_hal_dm_send_bt_cmd(
1328 cmd, NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH,
1329 nfc_hal_dm_set_snooze_mode_cback);
1330 return (NCI_STATUS_OK);
1331 }
1332