Home | History | Annotate | Download | only in hal
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-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  *  Functions for handling NFC HAL NCI Transport events
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "nfc_hal_int.h"
     26 #include "userial.h"
     27 #include "upio.h"
     28 
     29 /****************************************************************************
     30 ** Definitions
     31 ****************************************************************************/
     32 
     33 /* Default NFC HAL NCI port configuration  */
     34 NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg =
     35 {
     36     NFC_HAL_SHARED_TRANSPORT_ENABLED,   /* bSharedTransport */
     37     USERIAL_BAUD_115200,                /* Baud rate */
     38     USERIAL_FC_HW                       /* Flow control */
     39 };
     40 
     41 /* Control block for NFC HAL NCI transport */
     42 #if NFC_DYNAMIC_MEMORY == FALSE
     43 tNFC_HAL_CB nfc_hal_cb;
     44 #endif
     45 
     46 /****************************************************************************
     47 ** Internal function prototypes
     48 ****************************************************************************/
     49 static void nfc_hal_main_userial_cback (tUSERIAL_PORT port, tUSERIAL_EVT evt, tUSERIAL_EVT_DATA *p_data);
     50 static void nfc_hal_main_handle_terminate (void);
     51 
     52 
     53 #if (NFC_HAL_DEBUG == TRUE)
     54 const char * const nfc_hal_init_state_str[] =
     55 {
     56     "IDLE",             /* Initialization is done                */
     57     "W4_XTAL_SET",      /* Waiting for crystal setting rsp       */
     58     "W4_RESET",         /* Waiting for reset rsp                 */
     59     "W4_BUILD_INFO",    /* Waiting for build info rsp            */
     60     "W4_PATCH_INFO",    /* Waiting for patch info rsp            */
     61     "W4_APP_COMPL",     /* Waiting for complete from application */
     62     "W4_POST_INIT",     /* Waiting for complete of post init     */
     63     "W4_CONTROL",       /* Waiting for control release           */
     64     "W4_PREDISC",       /* Waiting for complete of prediscover   */
     65     "W4_RE_INIT",       /* Waiting for reset rsp on ReInit       */
     66     "CLOSING"           /* Shutting down                         */
     67 };
     68 #endif
     69 
     70 /*******************************************************************************
     71 **
     72 ** Function         nfc_hal_main_init
     73 **
     74 ** Description      This function initializes control block for NFC HAL
     75 **
     76 ** Returns          nothing
     77 **
     78 *******************************************************************************/
     79 void nfc_hal_main_init (void)
     80 {
     81     /* Clear control block */
     82     memset (&nfc_hal_cb, 0, sizeof (tNFC_HAL_CB));
     83 
     84     nfc_hal_cb.ncit_cb.nci_ctrl_size   = NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE;
     85     nfc_hal_cb.trace_level             = NFC_HAL_INITIAL_TRACE_LEVEL;
     86 }
     87 
     88 /*******************************************************************************
     89 **
     90 ** Function         nfc_hal_main_open_transport
     91 **
     92 ** Description      Open transport and prepare for new incoming message;
     93 **
     94 ** Returns          nothing
     95 **
     96 *******************************************************************************/
     97 static void nfc_hal_main_open_transport (void)
     98 {
     99     tUSERIAL_OPEN_CFG open_cfg;
    100 
    101     /* Initialize control block */
    102     nfc_hal_cb.ncit_cb.rcv_state = NFC_HAL_RCV_IDLE_ST; /* to process packet type */
    103 
    104     if (nfc_hal_cb.ncit_cb.p_rcv_msg)
    105     {
    106         GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
    107         nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
    108     }
    109 
    110     /* open transport */
    111     open_cfg.fmt    = (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1);
    112     open_cfg.baud   = nfc_hal_trans_cfg.userial_baud;
    113     open_cfg.fc     = nfc_hal_trans_cfg.userial_fc;
    114     open_cfg.buf    = USERIAL_BUF_BYTE;
    115 
    116     USERIAL_Open (USERIAL_NFC_PORT, &open_cfg, nfc_hal_main_userial_cback);
    117 
    118     /* notify transport openned */
    119     nfc_hal_dm_pre_init_nfcc ();
    120 }
    121 
    122 /*******************************************************************************
    123 **
    124 ** Function         nfc_hal_main_send_error
    125 **
    126 ** Description      send an Error event to NFC stack
    127 **
    128 ** Returns          nothing
    129 **
    130 *******************************************************************************/
    131 void nfc_hal_main_send_error (tHAL_NFC_STATUS status)
    132 {
    133     /* Notify stack */
    134     nfc_hal_cb.p_stack_cback(HAL_NFC_ERROR_EVT, status);
    135 }
    136 
    137 /*******************************************************************************
    138 **
    139 ** Function         nfc_hal_main_userial_cback
    140 **
    141 ** Description      USERIAL callback for NCI transport
    142 **
    143 ** Returns          nothing
    144 **
    145 *******************************************************************************/
    146 static void nfc_hal_main_userial_cback (tUSERIAL_PORT port, tUSERIAL_EVT evt, tUSERIAL_EVT_DATA *p_data)
    147 {
    148     if (evt == USERIAL_RX_READY_EVT)
    149     {
    150         /* Notify transport task of serial port event */
    151         GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_DATA_RDY);
    152     }
    153     else if (evt == USERIAL_TX_DONE_EVT)
    154     {
    155         /* Serial driver has finshed sending data from USERIAL_Write */
    156         /* Currently, no action is needed for this event */
    157     }
    158     else if (evt == USERIAL_ERR_EVT)
    159     {
    160         NCI_TRACE_ERROR0 ("nfc_hal_main_userial_cback: USERIAL_ERR_EVT. Notifying NFC_TASK of transport error");
    161         if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
    162         {
    163             nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
    164             nfc_hal_nci_cmd_timeout_cback ((void *)&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
    165         }
    166         else
    167         {
    168             nfc_hal_main_send_error (HAL_NFC_STATUS_ERR_TRANSPORT);
    169         }
    170     }
    171     else if (evt == USERIAL_WAKEUP_EVT)
    172     {
    173         NCI_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: USERIAL_WAKEUP_EVT: %d", p_data->sigs);
    174     }
    175     else
    176     {
    177         NCI_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: unhandled userial evt: %i", evt);
    178     }
    179 }
    180 
    181 /*******************************************************************************
    182 **
    183 ** Function         nfc_hal_main_pre_init_done
    184 **
    185 ** Description      notify complete of pre-initialization
    186 **
    187 ** Returns          nothing
    188 **
    189 *******************************************************************************/
    190 void nfc_hal_main_pre_init_done (tHAL_NFC_STATUS status)
    191 {
    192     NCI_TRACE_DEBUG1 ("nfc_hal_main_pre_init_done () status = %d", status);
    193 
    194     if (status != HAL_NFC_STATUS_OK)
    195     {
    196         nfc_hal_main_handle_terminate ();
    197 
    198         /* Close uart */
    199         USERIAL_Close (USERIAL_NFC_PORT);
    200     }
    201 
    202     /* Notify NFC Task the status of initialization */
    203     nfc_hal_cb.p_stack_cback (HAL_NFC_OPEN_CPLT_EVT, status);
    204 }
    205 
    206 /*******************************************************************************
    207 **
    208 ** Function         nfc_hal_main_timeout_cback
    209 **
    210 ** Description      callback function for timeout
    211 **
    212 ** Returns          void
    213 **
    214 *******************************************************************************/
    215 static void nfc_hal_main_timeout_cback (void *p_tle)
    216 {
    217     TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *) p_tle;
    218 
    219     NCI_TRACE_DEBUG0 ("nfc_hal_main_timeout_cback ()");
    220 
    221     switch (p_tlent->event)
    222     {
    223     case NFC_HAL_TTYPE_POWER_CYCLE:
    224         nfc_hal_main_open_transport ();
    225         break;
    226 
    227     default:
    228         NCI_TRACE_DEBUG1 ("nfc_hal_main_timeout_cback: unhandled timer event (0x%04x)", p_tlent->event);
    229         break;
    230     }
    231 }
    232 
    233 /*******************************************************************************
    234 **
    235 ** Function         nfc_hal_main_handle_terminate
    236 **
    237 ** Description      Handle NFI transport shutdown
    238 **
    239 ** Returns          nothing
    240 **
    241 *******************************************************************************/
    242 static void nfc_hal_main_handle_terminate (void)
    243 {
    244     NFC_HDR *p_msg;
    245 
    246     /* dequeue and free buffer */
    247     if (nfc_hal_cb.ncit_cb.p_pend_cmd != NULL)
    248     {
    249         GKI_freebuf (nfc_hal_cb.ncit_cb.p_pend_cmd);
    250         nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
    251     }
    252 
    253     /* Free unsent nfc rx buffer */
    254     if (nfc_hal_cb.ncit_cb.p_rcv_msg)
    255     {
    256         GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
    257         nfc_hal_cb.ncit_cb.p_rcv_msg  = NULL;
    258     }
    259 
    260     /* Free buffer for pending fragmented response/notification */
    261     if (nfc_hal_cb.ncit_cb.p_frag_msg)
    262     {
    263         GKI_freebuf (nfc_hal_cb.ncit_cb.p_frag_msg);
    264         nfc_hal_cb.ncit_cb.p_frag_msg = NULL;
    265     }
    266 
    267     /* Free buffers in the tx mbox */
    268     while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
    269     {
    270         GKI_freebuf (p_msg);
    271     }
    272 
    273     /* notify closing transport */
    274     nfc_hal_dm_shutting_down_nfcc ();
    275 }
    276 
    277 /*******************************************************************************
    278 **
    279 ** Function         nfc_hal_main_start_quick_timer
    280 **
    281 ** Description      Start a timer for the specified amount of time.
    282 **                  NOTE: The timeout resolution depends on including modules.
    283 **                  QUICK_TIMER_TICKS_PER_SEC should be used to convert from
    284 **                  time to ticks.
    285 **
    286 **
    287 ** Returns          void
    288 **
    289 *******************************************************************************/
    290 void nfc_hal_main_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
    291 {
    292     NFC_HDR *p_msg;
    293 
    294     /* if timer list is currently empty, start periodic GKI timer */
    295     if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
    296     {
    297         /* if timer starts on other than NCIT task (script wrapper) */
    298         if(GKI_get_taskid () != NFC_HAL_TASK)
    299         {
    300             /* post event to start timer in NCIT task */
    301             if ((p_msg = (NFC_HDR *) GKI_getbuf (NFC_HDR_SIZE)) != NULL)
    302             {
    303                 p_msg->event = NFC_HAL_EVT_TO_START_QUICK_TIMER;
    304                 GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
    305             }
    306         }
    307         else
    308         {
    309             GKI_start_timer (NFC_HAL_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
    310         }
    311     }
    312 
    313     GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
    314 
    315     p_tle->event = type;
    316     p_tle->ticks = timeout; /* Save the number of ticks for the timer */
    317 
    318     GKI_add_to_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
    319 }
    320 
    321 /*******************************************************************************
    322 **
    323 ** Function         nfc_hal_main_stop_quick_timer
    324 **
    325 ** Description      Stop a timer.
    326 **
    327 ** Returns          void
    328 **
    329 *******************************************************************************/
    330 void nfc_hal_main_stop_quick_timer (TIMER_LIST_ENT *p_tle)
    331 {
    332     GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
    333 
    334     /* if timer list is empty stop periodic GKI timer */
    335     if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
    336     {
    337         GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID);
    338     }
    339 }
    340 
    341 /*******************************************************************************
    342 **
    343 ** Function         nfc_hal_main_process_quick_timer_evt
    344 **
    345 ** Description      Process quick timer event
    346 **
    347 ** Returns          void
    348 **
    349 *******************************************************************************/
    350 static void nfc_hal_main_process_quick_timer_evt (void)
    351 {
    352     TIMER_LIST_ENT  *p_tle;
    353 
    354     GKI_update_timer_list (&nfc_hal_cb.quick_timer_queue, 1);
    355 
    356     while ((nfc_hal_cb.quick_timer_queue.p_first) && (!nfc_hal_cb.quick_timer_queue.p_first->ticks))
    357     {
    358         p_tle = nfc_hal_cb.quick_timer_queue.p_first;
    359         GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
    360 
    361         if (p_tle->p_cback)
    362         {
    363             (*p_tle->p_cback) (p_tle);
    364         }
    365     }
    366 
    367     /* if timer list is empty stop periodic GKI timer */
    368     if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
    369     {
    370         GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID);
    371     }
    372 }
    373 
    374 /*******************************************************************************
    375 **
    376 ** Function         nfc_hal_main_send_message
    377 **
    378 ** Description      This function is calledto send an NCI message.
    379 **
    380 ** Returns          void
    381 **
    382 *******************************************************************************/
    383 static void nfc_hal_main_send_message (NFC_HDR *p_msg)
    384 {
    385     UINT8   *ps;
    386     UINT16  len = p_msg->len;
    387 #ifdef DISP_NCI
    388     UINT8   delta;
    389 #endif
    390 
    391     NCI_TRACE_DEBUG1 ("nfc_hal_main_send_message() ls:0x%x", p_msg->layer_specific);
    392     if (  (p_msg->layer_specific == NFC_HAL_WAIT_RSP_CMD)
    393         ||(p_msg->layer_specific == NFC_HAL_WAIT_RSP_VSC)  )
    394     {
    395         nfc_hal_nci_send_cmd (p_msg);
    396     }
    397     else
    398     {
    399         /* NFC task has fragmented the data packet to the appropriate size
    400          * and data credit is available; just send it */
    401 
    402         /* add NCI packet type in front of message */
    403         nfc_hal_nci_add_nfc_pkt_type (p_msg);
    404 
    405         /* send this packet to transport */
    406         ps = (UINT8 *) (p_msg + 1) + p_msg->offset;
    407 #ifdef DISP_NCI
    408         delta = p_msg->len - len;
    409         DISP_NCI (ps + delta, (UINT16) (p_msg->len - delta), FALSE);
    410 #endif
    411         USERIAL_Write (USERIAL_NFC_PORT, ps, p_msg->len);
    412         GKI_freebuf (p_msg);
    413     }
    414 }
    415 
    416 /*******************************************************************************
    417 **
    418 ** Function         nfc_hal_main_task
    419 **
    420 ** Description      NFC HAL NCI transport event processing task
    421 **
    422 ** Returns          0
    423 **
    424 *******************************************************************************/
    425 UINT32 nfc_hal_main_task (UINT32 param)
    426 {
    427     UINT16   event;
    428     UINT8    byte;
    429     UINT8    num_interfaces;
    430     UINT8    *p;
    431     NFC_HDR  *p_msg;
    432     BOOLEAN  free_msg;
    433 
    434     NCI_TRACE_DEBUG0 ("NFC_HAL_TASK started");
    435 
    436     /* Main loop */
    437     while (TRUE)
    438     {
    439         event = GKI_wait (0xFFFF, 0);
    440 
    441         /* Handle NFC_HAL_TASK_EVT_INITIALIZE (for initializing NCI transport) */
    442         if (event & NFC_HAL_TASK_EVT_INITIALIZE)
    443         {
    444             NCI_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_INITIALIZE signal. Opening NFC transport...");
    445 
    446             nfc_hal_main_open_transport ();
    447         }
    448 
    449         /* Check for terminate event */
    450         if (event & NFC_HAL_TASK_EVT_TERMINATE)
    451         {
    452             NCI_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_TERMINATE");
    453             nfc_hal_main_handle_terminate ();
    454 
    455             /* Close uart */
    456             USERIAL_Close (USERIAL_NFC_PORT);
    457 
    458             nfc_hal_cb.p_stack_cback (HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
    459             nfc_hal_cb.p_stack_cback = NULL;
    460             continue;
    461         }
    462 
    463         /* Check for power cycle event */
    464         if (event & NFC_HAL_TASK_EVT_POWER_CYCLE)
    465         {
    466             NCI_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_POWER_CYCLE");
    467             nfc_hal_main_handle_terminate ();
    468 
    469             /* Close uart */
    470             USERIAL_Close (USERIAL_NFC_PORT);
    471 
    472             /* power cycle timeout */
    473             nfc_hal_cb.timer.p_cback = nfc_hal_main_timeout_cback;
    474             nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_POWER_CYCLE,
    475                                             (NFC_HAL_POWER_CYCLE_DELAY*QUICK_TIMER_TICKS_PER_SEC)/1000);
    476             continue;
    477         }
    478 
    479         /* NCI message ready to be sent to NFCC */
    480         if (event & NFC_HAL_TASK_EVT_MBOX)
    481         {
    482             while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
    483             {
    484                 free_msg = TRUE;
    485                 switch (p_msg->event & NFC_EVT_MASK)
    486                 {
    487                 case NFC_HAL_EVT_TO_NFC_NCI:
    488                     nfc_hal_main_send_message (p_msg);
    489                     /* do not free buffer. NCI VS code may keep it for processing later */
    490                     free_msg = FALSE;
    491                     break;
    492 
    493                 case NFC_HAL_EVT_POST_CORE_RESET:
    494                     NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_POST_INIT_DONE);
    495 
    496                     /* set NCI Control packet size from CORE_INIT_RSP */
    497                     p = (UINT8 *) (p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
    498                     p += 5;
    499                     STREAM_TO_UINT8 (num_interfaces, p);
    500                     p += (num_interfaces + 3);
    501                     nfc_hal_cb.ncit_cb.nci_ctrl_size = *p;
    502 
    503                     /* start post initialization */
    504                     nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_LPTD;
    505                     nfc_hal_cb.dev_cb.next_startup_vsc = 1;
    506 
    507                     nfc_hal_dm_config_nfcc ();
    508                     break;
    509 
    510                 case NFC_HAL_EVT_TO_START_QUICK_TIMER:
    511                     GKI_start_timer (NFC_HAL_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
    512                     break;
    513 
    514                 case NFC_HAL_EVT_HCI:
    515                     nfc_hal_hci_evt_hdlr ((tNFC_HAL_HCI_EVENT_DATA *) p_msg);
    516                     break;
    517 
    518 
    519                 case NFC_HAL_EVT_CONTROL_GRANTED:
    520                     nfc_hal_dm_send_pend_cmd ();
    521                     break;
    522 
    523                 default:
    524                     break;
    525                 }
    526 
    527                 if (free_msg)
    528                     GKI_freebuf (p_msg);
    529             }
    530         }
    531 
    532         /* Data waiting to be read from serial port */
    533         if (event & NFC_HAL_TASK_EVT_DATA_RDY)
    534         {
    535             while (TRUE)
    536             {
    537                 /* Read one byte to see if there is anything waiting to be read */
    538                 if (USERIAL_Read (USERIAL_NFC_PORT, &byte, 1) == 0)
    539                 {
    540                     break;
    541                 }
    542 
    543                 if (nfc_hal_nci_receive_msg (byte))
    544                 {
    545                     /* complete of receiving NCI message */
    546                     nfc_hal_nci_assemble_nci_msg ();
    547                     if (nfc_hal_cb.ncit_cb.p_rcv_msg)
    548                     {
    549                         if (nfc_hal_nci_preproc_rx_nci_msg (nfc_hal_cb.ncit_cb.p_rcv_msg))
    550                         {
    551                             /* Send NCI message to the stack */
    552                             nfc_hal_cb.p_data_cback(nfc_hal_cb.ncit_cb.p_rcv_msg->len, (UINT8 *)((nfc_hal_cb.ncit_cb.p_rcv_msg + 1)
    553                                                              + nfc_hal_cb.ncit_cb.p_rcv_msg->offset));
    554 
    555                         }
    556                     }
    557 
    558                     if (nfc_hal_cb.ncit_cb.p_rcv_msg)
    559                     {
    560                         GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
    561                         nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
    562                     }
    563                 }
    564             } /* while (TRUE) */
    565         }
    566 
    567         /* Process quick timer tick */
    568         if (event & NFC_HAL_QUICK_TIMER_EVT_MASK)
    569         {
    570             nfc_hal_main_process_quick_timer_evt ();
    571         }
    572     }
    573 
    574     NCI_TRACE_DEBUG0 ("nfc_hal_main_task terminated");
    575 
    576     GKI_exit_task (GKI_get_taskid ());
    577     return 0;
    578 }
    579 
    580 /*******************************************************************************
    581 **
    582 ** Function         HAL_NfcSetTraceLevel
    583 **
    584 ** Description      This function sets the trace level for HAL.  If called with
    585 **                  a value of 0xFF, it simply returns the current trace level.
    586 **
    587 ** Returns          The new or current trace level
    588 **
    589 *******************************************************************************/
    590 UINT8 HAL_NfcSetTraceLevel (UINT8 new_level)
    591 {
    592     if (new_level != 0xFF)
    593         nfc_hal_cb.trace_level = new_level;
    594 
    595     return (nfc_hal_cb.trace_level);
    596 }
    597