nfc_hal_dm.c revision b58ba0e89a3767e6174c42d3e90540d1eae10f81
1/****************************************************************************** 2 * 3 * Copyright (C) 2012 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 "nfc_hal_int.h" 25#include "nfc_hal_post_reset.h" 26#include "userial.h" 27#include "upio.h" 28 29/***************************************************************************** 30** Constants and types 31*****************************************************************************/ 32 33#define NFC_HAL_I93_RW_CFG_LEN (5) 34#define NFC_HAL_I93_RW_CFG_PARAM_LEN (3) 35#define NFC_HAL_I93_AFI (0) 36#define NFC_HAL_I93_ENABLE_SMART_POLL (1) 37 38static UINT8 nfc_hal_dm_i93_rw_cfg[NFC_HAL_I93_RW_CFG_LEN] = 39{ 40 NCI_PARAM_ID_I93_DATARATE, 41 NFC_HAL_I93_RW_CFG_PARAM_LEN, 42 NFC_HAL_I93_FLAG_DATA_RATE, /* Bit0:Sub carrier, Bit1:Data rate, 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 47static UINT8 nfc_hal_dm_set_fw_fsm_cmd[NCI_MSG_HDR_SIZE + 1] = 48{ 49 NCI_MTS_CMD|NCI_GID_PROP, 50 NCI_MSG_SET_FWFSM, 51 0x01, 52 0x00, 53}; 54#define NCI_SET_FWFSM_OFFSET_ENABLE 3 55 56const UINT8 nfc_hal_dm_core_reset_cmd[NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_RESET] = 57{ 58 NCI_MTS_CMD|NCI_GID_CORE, 59 NCI_MSG_CORE_RESET, 60 NCI_CORE_PARAM_SIZE_RESET, 61 NCI_RESET_TYPE_RESET_CFG 62}; 63 64#define NCI_PROP_PARAM_SIZE_XTAL_INDEX 3 /* length of parameters in XTAL_INDEX CMD */ 65 66const UINT8 nfc_hal_dm_get_build_info_cmd[NCI_MSG_HDR_SIZE] = 67{ 68 NCI_MTS_CMD|NCI_GID_PROP, 69 NCI_MSG_GET_BUILD_INFO, 70 0x00 71}; 72#define NCI_BUILD_INFO_OFFSET_HWID 25 /* HW ID offset in build info RSP */ 73 74const UINT8 nfc_hal_dm_get_patch_version_cmd [NCI_MSG_HDR_SIZE] = 75{ 76 NCI_MTS_CMD|NCI_GID_PROP, 77 NCI_MSG_GET_PATCH_VERSION, 78 0x00 79}; 80#define NCI_PATCH_INFO_OFFSET_NVMTYPE 35 /* NVM Type offset in patch info RSP */ 81 82/***************************************************************************** 83** Extern function prototypes 84*****************************************************************************/ 85extern UINT8 *p_nfc_hal_dm_lptd_cfg; 86extern UINT8 *p_nfc_hal_dm_pll_325_cfg; 87extern UINT8 *p_nfc_hal_dm_start_up_cfg; 88extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg; 89 90/***************************************************************************** 91** Local function prototypes 92*****************************************************************************/ 93 94/******************************************************************************* 95** 96** Function nfc_hal_dm_set_config 97** 98** Description Send NCI config items to NFCC 99** 100** Returns tHAL_NFC_STATUS 101** 102*******************************************************************************/ 103tHAL_NFC_STATUS nfc_hal_dm_set_config (UINT8 tlv_size, 104 UINT8 *p_param_tlvs, 105 tNFC_HAL_NCI_CBACK *p_cback) 106{ 107 UINT8 *p_buff, *p; 108 UINT8 num_param = 0, param_len, rem_len, *p_tlv; 109 UINT16 cmd_len = NCI_MSG_HDR_SIZE + tlv_size + 1; 110 tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED; 111 112 if ((tlv_size == 0)||(p_param_tlvs == NULL)) 113 { 114 return status; 115 } 116 117 if ((p_buff = (UINT8 *) GKI_getbuf ((UINT16)(NCI_MSG_HDR_SIZE + tlv_size))) != NULL) 118 { 119 p = p_buff; 120 121 NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_CORE); 122 NCI_MSG_BLD_HDR1 (p, NCI_MSG_CORE_SET_CONFIG); 123 UINT8_TO_STREAM (p, (UINT8) (tlv_size + 1)); 124 125 rem_len = tlv_size; 126 p_tlv = p_param_tlvs; 127 while (rem_len > 1) 128 { 129 num_param++; /* number of params */ 130 131 p_tlv ++; /* param type */ 132 param_len = *p_tlv++; /* param length */ 133 134 rem_len -= 2; /* param type and length */ 135 if (rem_len >= param_len) 136 { 137 rem_len -= param_len; 138 p_tlv += param_len; /* next param_type */ 139 140 if (rem_len == 0) 141 { 142 status = HAL_NFC_STATUS_OK; 143 break; 144 } 145 } 146 else 147 { 148 /* error found */ 149 break; 150 } 151 } 152 153 if (status == HAL_NFC_STATUS_OK) 154 { 155 UINT8_TO_STREAM (p, num_param); 156 ARRAY_TO_STREAM (p, p_param_tlvs, tlv_size); 157 158 nfc_hal_dm_send_nci_cmd (p_buff, cmd_len, p_cback); 159 } 160 else 161 { 162 NCI_TRACE_ERROR0 ("nfc_hal_dm_set_config ():Bad TLV"); 163 } 164 165 GKI_freebuf (p_buff); 166 } 167 168 return status; 169} 170 171/******************************************************************************* 172** 173** Function nfc_hal_dm_get_xtal_index 174** 175** Description Convert xtal frequency to index 176** 177** Returns xtal index 178** 179*******************************************************************************/ 180static tNFC_HAL_XTAL_INDEX nfc_hal_dm_get_xtal_index (UINT16 xtal_freq) 181{ 182 tNFC_HAL_XTAL_INDEX xtal_index; 183 184 switch (xtal_freq) 185 { 186 case 9600: xtal_index = NFC_HAL_XTAL_INDEX_9600; break; 187 case 13000: xtal_index = NFC_HAL_XTAL_INDEX_13000; break; 188 case 16200: xtal_index = NFC_HAL_XTAL_INDEX_16200; break; 189 case 19200: xtal_index = NFC_HAL_XTAL_INDEX_19200; break; 190 case 24000: xtal_index = NFC_HAL_XTAL_INDEX_24000; break; 191 case 26000: xtal_index = NFC_HAL_XTAL_INDEX_26000; break; 192 case 38400: xtal_index = NFC_HAL_XTAL_INDEX_38400; break; 193 case 52000: xtal_index = NFC_HAL_XTAL_INDEX_52000; break; 194 case 37400: xtal_index = NFC_HAL_XTAL_INDEX_37400; break; 195 default : xtal_index = NFC_HAL_XTAL_INDEX_MAX; 196 NCI_TRACE_DEBUG1 ("nfc_hal_dm_get_xtal_index ():No matched index for %d", xtal_freq); 197 break; 198 } 199 200 return xtal_index; 201} 202 203/******************************************************************************* 204** 205** Function nfc_hal_dm_set_fw_fsm 206** 207** Description Enable or disable FW FSM 208** 209** Returns void 210** 211*******************************************************************************/ 212void nfc_hal_dm_set_fw_fsm (BOOLEAN enable, tNFC_HAL_NCI_CBACK *p_cback) 213{ 214 if (enable) 215 nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x01; /* Enable, default is disabled */ 216 else 217 nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x00; /* Disable */ 218 219 nfc_hal_dm_send_nci_cmd (nfc_hal_dm_set_fw_fsm_cmd, NCI_MSG_HDR_SIZE + 1, p_cback); 220} 221 222/******************************************************************************* 223** 224** Function nfc_hal_dm_config_nfcc_cback 225** 226** Description Callback for NCI vendor specific command complete 227** 228** Returns void 229** 230*******************************************************************************/ 231void nfc_hal_dm_config_nfcc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data) 232{ 233 if (nfc_hal_cb.dev_cb.next_dm_config == NFC_HAL_DM_CONFIG_NONE) 234 { 235 nfc_hal_hci_enable (); 236 } 237 else 238 { 239 nfc_hal_dm_config_nfcc (); 240 } 241} 242 243/******************************************************************************* 244** 245** Function nfc_hal_dm_send_startup_vsc 246** 247** Description Send VS command before NFA start-up 248** 249** Returns None 250** 251*******************************************************************************/ 252void nfc_hal_dm_send_startup_vsc (void) 253{ 254 UINT8 *p, *p_end; 255 UINT16 len; 256 257 NCI_TRACE_DEBUG0 ("nfc_hal_dm_send_startup_vsc ()"); 258 259 /* VSC must have NCI header at least */ 260 if (nfc_hal_cb.dev_cb.next_startup_vsc + NCI_MSG_HDR_SIZE - 1 <= *p_nfc_hal_dm_start_up_vsc_cfg) 261 { 262 p = p_nfc_hal_dm_start_up_vsc_cfg + nfc_hal_cb.dev_cb.next_startup_vsc; 263 len = *(p + 2); 264 p_end = p + NCI_MSG_HDR_SIZE - 1 + len; 265 266 if (p_end <= p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg) 267 { 268 /* move to next VSC */ 269 nfc_hal_cb.dev_cb.next_startup_vsc += NCI_MSG_HDR_SIZE + len; 270 271 /* if this is last VSC */ 272 if (p_end == p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg) 273 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE; 274 275 nfc_hal_dm_send_nci_cmd (p, (UINT16)(NCI_MSG_HDR_SIZE + len), nfc_hal_dm_config_nfcc_cback); 276 return; 277 } 278 } 279 280 NCI_TRACE_ERROR0 ("nfc_hal_dm_send_startup_vsc (): Bad start-up VSC"); 281 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE; 282 nfc_hal_dm_config_nfcc_cback (0, 0, NULL); 283} 284 285/******************************************************************************* 286** 287** Function nfc_hal_dm_config_nfcc 288** 289** Description Send VS config before NFA start-up 290** 291** Returns void 292** 293*******************************************************************************/ 294void nfc_hal_dm_config_nfcc (void) 295{ 296 UINT8 *p; 297 UINT8 xtal_index; 298 299 NCI_TRACE_DEBUG1 ("nfc_hal_dm_config_nfcc (): next_dm_config = %d", nfc_hal_cb.dev_cb.next_dm_config); 300 301 if ((p_nfc_hal_dm_lptd_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_LPTD)) 302 { 303 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_PLL_325; 304 305 if (nfc_hal_dm_set_config (p_nfc_hal_dm_lptd_cfg[0], 306 &p_nfc_hal_dm_lptd_cfg[1], 307 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) 308 { 309 return; 310 } 311 } 312 313 if ((p_nfc_hal_dm_pll_325_cfg) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_PLL_325)) 314 { 315 xtal_index = nfc_hal_dm_get_xtal_index (nfc_post_reset_cb.dev_init_config.xtal_freq); 316 if (xtal_index < NFC_HAL_XTAL_INDEX_MAX) 317 { 318 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP; 319 p = p_nfc_hal_dm_pll_325_cfg + (xtal_index * NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN); 320 if (nfc_hal_dm_set_config (NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN, 321 p, 322 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) 323 { 324 return; 325 } 326 } 327 } 328 329 if ((p_nfc_hal_dm_start_up_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP)) 330 { 331 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_I93_DATA_RATE; 332 if (nfc_hal_dm_set_config (p_nfc_hal_dm_start_up_cfg[0], 333 &p_nfc_hal_dm_start_up_cfg[1], 334 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) 335 { 336 return; 337 } 338 } 339 340#if (NFC_HAL_I93_FLAG_DATA_RATE == NFC_HAL_I93_FLAG_DATA_RATE_HIGH) 341 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_I93_DATA_RATE) 342 { 343 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_FW_FSM; 344 if (nfc_hal_dm_set_config (NFC_HAL_I93_RW_CFG_LEN, 345 nfc_hal_dm_i93_rw_cfg, 346 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) 347 { 348 return; 349 } 350 } 351#endif 352 353 /* FW FSM is disabled as default in NFCC */ 354 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_FW_FSM) 355 { 356 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP_VSC; 357 nfc_hal_dm_set_fw_fsm (NFC_HAL_DM_MULTI_TECH_RESP, nfc_hal_dm_config_nfcc_cback); 358 return; 359 } 360 361 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP_VSC) 362 { 363 if (p_nfc_hal_dm_start_up_vsc_cfg && *p_nfc_hal_dm_start_up_vsc_cfg) 364 { 365 nfc_hal_dm_send_startup_vsc (); 366 return; 367 } 368 } 369 370 /* nothing to config */ 371 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE; 372 nfc_hal_dm_config_nfcc_cback (0, 0, NULL); 373} 374 375/******************************************************************************* 376** 377** Function nfc_hal_dm_set_xtal_freq_index 378** 379** Description Set crystal frequency index 380** 381** Returns void 382** 383*******************************************************************************/ 384void nfc_hal_dm_set_xtal_freq_index (void) 385{ 386 UINT8 nci_brcm_xtal_index_cmd[NCI_MSG_HDR_SIZE + NCI_PROP_PARAM_SIZE_XTAL_INDEX]; 387 UINT8 *p; 388 tNFC_HAL_XTAL_INDEX xtal_index; 389 390 NCI_TRACE_DEBUG1 ("nfc_hal_dm_set_xtal_freq_index (): xtal_freq = %d", nfc_post_reset_cb.dev_init_config.xtal_freq); 391 392 xtal_index = nfc_hal_dm_get_xtal_index (nfc_post_reset_cb.dev_init_config.xtal_freq); 393 394 p = nci_brcm_xtal_index_cmd; 395 UINT8_TO_STREAM (p, (NCI_MTS_CMD|NCI_GID_PROP)); 396 UINT8_TO_STREAM (p, NCI_MSG_GET_XTAL_INDEX_FROM_DH); 397 UINT8_TO_STREAM (p, NCI_PROP_PARAM_SIZE_XTAL_INDEX); 398 UINT8_TO_STREAM (p, xtal_index); 399 UINT16_TO_STREAM (p, nfc_post_reset_cb.dev_init_config.xtal_freq); 400 401 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_XTAL_SET); 402 403 nfc_hal_dm_send_nci_cmd (nci_brcm_xtal_index_cmd, NCI_MSG_HDR_SIZE + NCI_PROP_PARAM_SIZE_XTAL_INDEX, NULL); 404} 405 406/******************************************************************************* 407** 408** Function nfc_hal_dm_send_reset_cmd 409** 410** Description Send CORE RESET CMD 411** 412** Returns void 413** 414*******************************************************************************/ 415void nfc_hal_dm_send_reset_cmd (void) 416{ 417 /* Proceed with start up sequence: send CORE_RESET_CMD */ 418 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_RESET); 419 420 nfc_hal_dm_send_nci_cmd (nfc_hal_dm_core_reset_cmd, NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_RESET, NULL); 421} 422 423/******************************************************************************* 424** 425** Function nfc_hal_dm_proc_msg_during_init 426** 427** Description Process NCI message while initializing NFCC 428** 429** Returns void 430** 431*******************************************************************************/ 432void nfc_hal_dm_proc_msg_during_init (NFC_HDR *p_msg) 433{ 434 UINT8 *p; 435 UINT8 reset_reason, reset_type; 436 UINT8 mt, pbf, gid, op_code; 437 UINT8 *p_old, old_gid, old_oid, old_mt; 438 tNFC_HAL_NCI_CBACK *p_cback = NULL; 439 440 NCI_TRACE_DEBUG1 ("nfc_hal_dm_proc_msg_during_init(): init state:%d", nfc_hal_cb.dev_cb.initializing_state); 441 442 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 443 444 NCI_MSG_PRS_HDR0 (p, mt, pbf, gid); 445 NCI_MSG_PRS_HDR1 (p, op_code); 446 447 /* check if waiting for this response */ 448 if ( (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD) 449 ||(nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC) ) 450 { 451 if (mt == NCI_MT_RSP) 452 { 453 p_old = nfc_hal_cb.ncit_cb.last_hdr; 454 NCI_MSG_PRS_HDR0 (p_old, old_mt, pbf, old_gid); 455 old_oid = ((*p_old) & NCI_OID_MASK); 456 /* make sure this is the RSP we are waiting for before updating the command window */ 457 if ((old_gid == gid) && (old_oid == op_code)) 458 { 459 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 460 p_cback = (tNFC_HAL_NCI_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback; 461 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL; 462 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 463 } 464 } 465 } 466 467 if (gid == NCI_GID_CORE) 468 { 469 if (op_code == NCI_MSG_CORE_RESET) 470 { 471 if (mt == NCI_MT_RSP) 472 { 473 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_BUILD_INFO); 474 475 /* get build information to find out HW */ 476 nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_build_info_cmd, NCI_MSG_HDR_SIZE, NULL); 477 } 478 else 479 { 480 /* Call reset notification callback */ 481 p++; /* Skip over param len */ 482 STREAM_TO_UINT8 (reset_reason, p); 483 STREAM_TO_UINT8 (reset_type, p); 484 nfc_hal_prm_spd_reset_ntf (reset_reason, reset_type); 485 } 486 } 487 else if (p_cback) 488 { 489 (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code), 490 p_msg->len, 491 (UINT8 *) (p_msg + 1) + p_msg->offset); 492 } 493 } 494 else if (gid == NCI_GID_PROP) /* this is for download patch */ 495 { 496 if (mt == NCI_MT_NTF) 497 op_code |= NCI_NTF_BIT; 498 else 499 op_code |= NCI_RSP_BIT; 500 501 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_XTAL_SET) 502 { 503 if (op_code == (NCI_RSP_BIT|NCI_MSG_GET_XTAL_INDEX_FROM_DH)) 504 { 505 /* wait for crystal setting in NFCC */ 506 GKI_delay (100); 507 508 /* Crytal frequency configured. Proceed with start up sequence: send CORE_RESET_CMD */ 509 nfc_hal_dm_send_reset_cmd (); 510 } 511 } 512 else if ( (op_code == NFC_VS_GET_BUILD_INFO_EVT) 513 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO) ) 514 { 515 p += NCI_BUILD_INFO_OFFSET_HWID; 516 517 STREAM_TO_UINT32 (nfc_hal_cb.dev_cb.brcm_hw_id, p); 518 519 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_PATCH_INFO); 520 521 nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, NULL); 522 } 523 else if ( (op_code == NFC_VS_GET_PATCH_VERSION_EVT) 524 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PATCH_INFO) ) 525 { 526 p += NCI_PATCH_INFO_OFFSET_NVMTYPE; 527 528 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_APP_COMPLETE); 529 530 /* let platform update baudrate or download patch */ 531 nfc_hal_post_reset_init (nfc_hal_cb.dev_cb.brcm_hw_id, *p); 532 } 533 else if (p_cback) 534 { 535 (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code), 536 p_msg->len, 537 (UINT8 *) (p_msg + 1) + p_msg->offset); 538 } 539 else if (op_code == NFC_VS_SEC_PATCH_AUTH_EVT) 540 { 541 NCI_TRACE_DEBUG0 ("signature!!"); 542 nfc_hal_prm_nci_command_complete_cback ((tNFC_HAL_NCI_EVT) (op_code), 543 p_msg->len, 544 (UINT8 *) (p_msg + 1) + p_msg->offset); 545 } 546 } 547} 548 549/******************************************************************************* 550** 551** Function nfc_hal_dm_send_nci_cmd 552** 553** Description Send NCI command to NFCC while initializing BRCM NFCC 554** 555** Returns void 556** 557*******************************************************************************/ 558void nfc_hal_dm_send_nci_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback) 559{ 560 NFC_HDR *p_buf; 561 UINT8 *ps; 562 563 NCI_TRACE_DEBUG1 ("nfc_hal_dm_send_nci_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp); 564 565 if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) 566 { 567 NCI_TRACE_ERROR0 ("nfc_hal_dm_send_nci_cmd(): no command window"); 568 return; 569 } 570 571 if ((p_buf = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) 572 { 573 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_VSC; 574 575 p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; 576 p_buf->event = NFC_HAL_EVT_TO_NFC_NCI; 577 p_buf->len = len; 578 579 memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len); 580 581 /* Keep a copy of the command and send to NCI transport */ 582 583 /* save the message header to double check the response */ 584 ps = (UINT8 *)(p_buf + 1) + p_buf->offset; 585 memcpy(nfc_hal_cb.ncit_cb.last_hdr, ps, NFC_HAL_SAVED_HDR_SIZE); 586 memcpy(nfc_hal_cb.ncit_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_HAL_SAVED_CMD_SIZE); 587 588 /* save the callback for NCI VSCs */ 589 nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback; 590 591 nfc_hal_nci_send_cmd (p_buf); 592 593 /* start NFC command-timeout timer */ 594 nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP), 595 ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 596 } 597} 598 599/******************************************************************************* 600** 601** Function nfc_hal_dm_send_pend_cmd 602** 603** Description Send a command to NFCC 604** 605** Returns void 606** 607*******************************************************************************/ 608void nfc_hal_dm_send_pend_cmd (void) 609{ 610 NFC_HDR *p_buf = nfc_hal_cb.ncit_cb.p_pend_cmd; 611 UINT8 *p; 612 613 if (p_buf == NULL) 614 return; 615 616 if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP) 617 { 618#if (NFC_HAL_TRACE_PROTOCOL == TRUE) 619 DispHciCmd (p_buf); 620#endif 621 622 /* save the message header to double check the response */ 623 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 624 memcpy(nfc_hal_cb.ncit_cb.last_hdr, p, NFC_HAL_SAVED_HDR_SIZE); 625 626 /* add packet type for BT message */ 627 p_buf->offset--; 628 p_buf->len++; 629 630 p = (UINT8 *) (p_buf + 1) + p_buf->offset; 631 *p = HCIT_TYPE_COMMAND; 632 633 USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len); 634 635 GKI_freebuf (p_buf); 636 nfc_hal_cb.ncit_cb.p_pend_cmd = NULL; 637 638 /* start NFC command-timeout timer */ 639 nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP), 640 ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 641 642 } 643} 644 645/******************************************************************************* 646** 647** Function nfc_hal_dm_send_bt_cmd 648** 649** Description Send BT message to NFCC while initializing BRCM NFCC 650** 651** Returns void 652** 653*******************************************************************************/ 654void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback) 655{ 656 NFC_HDR *p_buf; 657 658 NCI_TRACE_DEBUG1 ("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp); 659 660 if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) 661 { 662 NCI_TRACE_ERROR0 ("nfc_hal_dm_send_bt_cmd(): no command window"); 663 return; 664 } 665 666 if ((p_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) 667 { 668 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP; 669 670 p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; 671 p_buf->len = len; 672 673 memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len); 674 675 /* save the callback for NCI VSCs) */ 676 nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback; 677 678 nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf; 679 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE) 680 { 681 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE); 682 nfc_hal_cb.p_stack_cback (HAL_NFC_REQUEST_CONTROL_EVT, NULL); 683 return; 684 } 685 686 nfc_hal_dm_send_pend_cmd(); 687 } 688} 689 690/******************************************************************************* 691** 692** Function nfc_hal_dm_set_nfc_wake 693** 694** Description Set NFC_WAKE line 695** 696** Returns void 697** 698*******************************************************************************/ 699void nfc_hal_dm_set_nfc_wake (UINT8 cmd) 700{ 701 NCI_TRACE_DEBUG1 ("nfc_hal_dm_set_nfc_wake () %s", 702 (cmd == NFC_HAL_ASSERT_NFC_WAKE ? "ASSERT" : "DEASSERT")); 703 704 /* 705 ** nfc_wake_active_mode cmd result of voltage on NFC_WAKE 706 ** 707 ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_ASSERT_NFC_WAKE (0) pull down NFC_WAKE (GND) 708 ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_DEASSERT_NFC_WAKE (1) pull up NFC_WAKE (VCC) 709 ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_ASSERT_NFC_WAKE (0) pull up NFC_WAKE (VCC) 710 ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_DEASSERT_NFC_WAKE (1) pull down NFC_WAKE (GND) 711 */ 712 713 if (cmd == nfc_hal_cb.dev_cb.nfc_wake_active_mode) 714 UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_OFF); /* pull down NFC_WAKE */ 715 else 716 UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_ON); /* pull up NFC_WAKE */ 717} 718 719/******************************************************************************* 720** 721** Function nfc_hal_dm_power_mode_execute 722** 723** Description If snooze mode is enabled in full power mode, 724** Assert NFC_WAKE before sending data 725** Deassert NFC_WAKE when idle timer expires 726** 727** Returns TRUE if DH can send data to NFCC 728** 729*******************************************************************************/ 730BOOLEAN nfc_hal_dm_power_mode_execute (tNFC_HAL_LP_EVT event) 731{ 732 BOOLEAN send_to_nfcc = FALSE; 733 734 NCI_TRACE_DEBUG1 ("nfc_hal_dm_power_mode_execute () event = %d", event); 735 736 if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) 737 { 738 if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) 739 { 740 /* if any transport activity */ 741 if ( (event == NFC_HAL_LP_TX_DATA_EVT) 742 ||(event == NFC_HAL_LP_RX_DATA_EVT) ) 743 { 744 /* if idle timer is not running */ 745 if (nfc_hal_cb.dev_cb.lp_timer.in_use == FALSE) 746 { 747 nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE); 748 } 749 750 /* start or extend idle timer */ 751 nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00, 752 ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 753 } 754 else if (event == NFC_HAL_LP_TIMEOUT_EVT) 755 { 756 /* let NFCC go to snooze mode */ 757 nfc_hal_dm_set_nfc_wake (NFC_HAL_DEASSERT_NFC_WAKE); 758 } 759 } 760 761 send_to_nfcc = TRUE; 762 } 763 764 return (send_to_nfcc); 765} 766 767/******************************************************************************* 768** 769** Function nci_brcm_lp_timeout_cback 770** 771** Description callback function for low power timeout 772** 773** Returns void 774** 775*******************************************************************************/ 776static void nci_brcm_lp_timeout_cback (void *p_tle) 777{ 778 NCI_TRACE_DEBUG0 ("nci_brcm_lp_timeout_cback ()"); 779 780 nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TIMEOUT_EVT); 781} 782 783/******************************************************************************* 784** 785** Function nfc_hal_dm_pre_init_nfcc 786** 787** Description This function initializes Broadcom specific control blocks for 788** NCI transport 789** 790** Returns void 791** 792*******************************************************************************/ 793void nfc_hal_dm_pre_init_nfcc (void) 794{ 795 NCI_TRACE_DEBUG0 ("nfc_hal_dm_pre_init_nfcc ()"); 796 797 if (nfc_post_reset_cb.dev_init_config.flags & NFC_HAL_DEV_INIT_FLAGS_SET_XTAL_FREQ) 798 { 799 nfc_hal_dm_set_xtal_freq_index (); 800 } 801 else 802 { 803 /* Send RESET CMD if application registered callback for device initialization */ 804 nfc_hal_dm_send_reset_cmd (); 805 } 806} 807 808/******************************************************************************* 809** 810** Function nfc_hal_dm_shutting_down_nfcc 811** 812** Description This function initializes Broadcom specific control blocks for 813** NCI transport 814** 815** Returns void 816** 817*******************************************************************************/ 818void nfc_hal_dm_shutting_down_nfcc (void) 819{ 820 NCI_TRACE_DEBUG0 ("nfc_hal_dm_shutting_down_nfcc ()"); 821 822 nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_CLOSING; 823 824 /* reset low power mode variables */ 825 if ( (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) 826 &&(nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) ) 827 { 828 nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE); 829 } 830 831 nfc_hal_cb.dev_cb.power_mode = NFC_HAL_POWER_MODE_FULL; 832 nfc_hal_cb.dev_cb.snooze_mode = NFC_HAL_LP_SNOOZE_MODE_NONE; 833 834 /* Stop all timers */ 835 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 836 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer); 837 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer); 838 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer); 839} 840 841/******************************************************************************* 842** 843** Function nfc_hal_dm_init 844** 845** Description This function initializes Broadcom specific control blocks for 846** NCI transport 847** 848** Returns void 849** 850*******************************************************************************/ 851void nfc_hal_dm_init (void) 852{ 853 NCI_TRACE_DEBUG0 ("nfc_hal_dm_init ()"); 854 855 nfc_hal_cb.dev_cb.lp_timer.p_cback = nci_brcm_lp_timeout_cback; 856 857 nfc_hal_cb.ncit_cb.nci_wait_rsp_timer.p_cback = nfc_hal_nci_cmd_timeout_cback; 858 859} 860 861/******************************************************************************* 862** 863** Function HAL_NfcDevInitDone 864** 865** Description Notify that pre-initialization of NFCC is complete 866** 867** Returns void 868** 869*******************************************************************************/ 870void HAL_NfcPreInitDone (tHAL_NFC_STATUS status) 871{ 872 NCI_TRACE_DEBUG1 ("HAL_NfcPreInitDone () status=%d", status); 873 874 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) 875 { 876 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 877 878 nfc_hal_main_pre_init_done (status); 879 } 880} 881 882/******************************************************************************* 883** 884** Function nfc_hal_dm_set_snooze_mode_cback 885** 886** Description This is baud rate update complete callback. 887** 888** Returns void 889** 890*******************************************************************************/ 891static void nfc_hal_dm_set_snooze_mode_cback (tNFC_HAL_BTVSC_CPLT *pData) 892{ 893 UINT8 status = pData->p_param_buf[0]; 894 tHAL_NFC_STATUS hal_status; 895 tHAL_NFC_STATUS_CBACK *p_cback; 896 897 /* if it is completed */ 898 if (status == HCI_SUCCESS) 899 { 900 nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE); 901 902 if ( nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) 903 { 904 /* start idle timer */ 905 nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00, 906 ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 907 } 908 else 909 { 910 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer); 911 } 912 hal_status = HAL_NFC_STATUS_OK; 913 } 914 else 915 { 916 hal_status = HAL_NFC_STATUS_FAILED; 917 } 918 919 if (nfc_hal_cb.dev_cb.p_prop_cback) 920 { 921 p_cback = nfc_hal_cb.dev_cb.p_prop_cback; 922 nfc_hal_cb.dev_cb.p_prop_cback = NULL; 923 (p_cback) (hal_status); 924 } 925} 926 927/******************************************************************************* 928** 929** Function HAL_NfcSetSnoozeMode 930** 931** Description Set snooze mode 932** snooze_mode 933** NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled 934** NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART 935** NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C 936** 937** idle_threshold_dh/idle_threshold_nfcc 938** Idle Threshold Host in 100ms unit 939** 940** nfc_wake_active_mode/dh_wake_active_mode 941** NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting 942** NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is asserting 943** 944** p_snooze_cback 945** Notify status of operation 946** 947** Returns tHAL_NFC_STATUS 948** 949*******************************************************************************/ 950tHAL_NFC_STATUS HAL_NfcSetSnoozeMode (UINT8 snooze_mode, 951 UINT8 idle_threshold_dh, 952 UINT8 idle_threshold_nfcc, 953 UINT8 nfc_wake_active_mode, 954 UINT8 dh_wake_active_mode, 955 tHAL_NFC_STATUS_CBACK *p_snooze_cback) 956{ 957 UINT8 cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH]; 958 UINT8 *p; 959 960 NCI_TRACE_API1 ("HAL_NfcSetSnoozeMode (): snooze_mode = %d", snooze_mode); 961 962 nfc_hal_cb.dev_cb.snooze_mode = snooze_mode; 963 nfc_hal_cb.dev_cb.nfc_wake_active_mode = nfc_wake_active_mode; 964 nfc_hal_cb.dev_cb.p_prop_cback = p_snooze_cback; 965 966 p = cmd; 967 968 /* Add the HCI command */ 969 UINT16_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE); 970 UINT8_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH); 971 972 memset (p, 0x00, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH); 973 974 UINT8_TO_STREAM (p, snooze_mode); /* Sleep Mode */ 975 976 UINT8_TO_STREAM (p, idle_threshold_dh); /* Idle Threshold Host */ 977 UINT8_TO_STREAM (p, idle_threshold_nfcc); /* Idle Threshold HC */ 978 UINT8_TO_STREAM (p, nfc_wake_active_mode); /* BT Wake Active Mode */ 979 UINT8_TO_STREAM (p, dh_wake_active_mode); /* Host Wake Active Mode */ 980 981 nfc_hal_dm_send_bt_cmd (cmd, 982 NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH, 983 nfc_hal_dm_set_snooze_mode_cback); 984 return (NCI_STATUS_OK); 985} 986 987 988 989 990 991 992 993 994