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