1/****************************************************************************** 2 * 3 * Copyright (C) 2012-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/****************************************************************************** 20 * 21 * NFC Hardware Abstraction Layer API: Implementation for Broadcom NFC 22 * controllers 23 * 24 ******************************************************************************/ 25#include "nfc_hal_api.h" 26#include <string.h> 27#include "gki.h" 28#include "nfc_hal_int.h" 29#include "nfc_hal_target.h" 30 31/******************************************************************************* 32** NFC_HAL_TASK declarations 33*******************************************************************************/ 34#define NFC_HAL_TASK_STR ((int8_t*)"NFC_HAL_TASK") 35#define NFC_HAL_TASK_STACK_SIZE 0x400 36uint32_t nfc_hal_task_stack[(NFC_HAL_TASK_STACK_SIZE + 3) / 4]; 37 38/******************************************************************************* 39** 40** Function HAL_NfcInitialize 41** 42** Description Called when HAL library is loaded. 43** 44** Initialize GKI and start the HCIT task 45** 46** Returns void 47** 48*******************************************************************************/ 49void HAL_NfcInitialize(void) { 50 /* Initialize HAL control block */ 51 nfc_hal_main_init(); 52 53 HAL_TRACE_API1("HAL_NfcInitialize (): NFC_HAL_TASK id=%i", NFC_HAL_TASK); 54 55#ifndef NFC_HAL_SHARED_GKI 56 /* Initialize GKI (not needed if using shared NFC/HAL GKI resources) */ 57 GKI_init(); 58 GKI_enable(); 59#endif 60 61 /* Create the NCI transport task */ 62 GKI_create_task( 63 (TASKPTR)nfc_hal_main_task, NFC_HAL_TASK, NFC_HAL_TASK_STR, 64 (uint16_t*)((uint8_t*)nfc_hal_task_stack + NFC_HAL_TASK_STACK_SIZE), 65 sizeof(nfc_hal_task_stack), NULL, NULL); 66 67#ifndef NFC_HAL_SHARED_GKI 68 /* Start GKI scheduler (not needed if using shared NFC/HAL GKI resources) */ 69 GKI_run(0); 70#endif 71} 72 73/******************************************************************************* 74** 75** Function HAL_NfcTerminate 76** 77** Description Called to terminate NFC HAL 78** 79** Returns void 80** 81*******************************************************************************/ 82void HAL_NfcTerminate(void) { HAL_TRACE_API0("HAL_NfcTerminate ()"); } 83 84/******************************************************************************* 85** 86** Function HAL_NfcOpen 87** 88** Description Open transport and intialize the NFCC, and 89** Register callback for HAL event notifications, 90** 91** HAL_OPEN_CPLT_EVT will notify when operation is complete. 92** 93** Returns void 94** 95*******************************************************************************/ 96void HAL_NfcOpen(tHAL_NFC_CBACK* p_hal_cback, 97 tHAL_NFC_DATA_CBACK* p_data_cback) { 98 HAL_TRACE_API0("HAL_NfcOpen ()"); 99 100 /* Only handle if HAL is not opened (stack cback is NULL) */ 101 if (p_hal_cback) { 102 nfc_hal_dm_init(); 103 nfc_hal_cb.p_stack_cback = p_hal_cback; 104 nfc_hal_cb.p_data_cback = p_data_cback; 105 106 /* Send startup event to NFC_HAL_TASK */ 107 GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_INITIALIZE); 108 } 109} 110 111/******************************************************************************* 112** 113** Function HAL_NfcClose 114** 115** Description Prepare for shutdown. A HAL_CLOSE_DONE_EVENT will be 116** reported when complete. 117** 118** Returns void 119** 120*******************************************************************************/ 121void HAL_NfcClose(void) { 122 HAL_TRACE_API0("HAL_NfcClose ()"); 123 124 /* Only handle if HAL is opened (stack cback is not-NULL) */ 125 if (nfc_hal_cb.p_stack_cback) { 126 /* Send shutdown event to NFC_HAL_TASK */ 127 GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE); 128 } 129} 130 131/******************************************************************************* 132** 133** Function HAL_NfcCoreInitialized 134** 135** Description Called after the CORE_INIT_RSP is received from the NFCC. 136** At this time, the HAL can do any chip-specific 137*configuration, 138** and when finished signal the libnfc-nci with event 139** HAL_POST_INIT_DONE. 140** 141** Returns void 142** 143*******************************************************************************/ 144void HAL_NfcCoreInitialized(uint16_t data_len, 145 uint8_t* p_core_init_rsp_params) { 146 NFC_HDR* p_msg; 147 uint16_t size; 148 149 HAL_TRACE_API0("HAL_NfcCoreInitialized ()"); 150 151 /* NCI payload len + NCI header size */ 152 size = p_core_init_rsp_params[2] + NCI_MSG_HDR_SIZE; 153 154 /* Send message to NFC_HAL_TASK */ 155 p_msg = (NFC_HDR*)GKI_getbuf((uint16_t)(size + NFC_HDR_SIZE)); 156 if (p_msg != NULL) { 157 p_msg->event = NFC_HAL_EVT_POST_CORE_RESET; 158 p_msg->offset = 0; 159 p_msg->len = size; 160 p_msg->layer_specific = 0; 161 memcpy((uint8_t*)(p_msg + 1) + p_msg->offset, p_core_init_rsp_params, size); 162 163 GKI_send_msg(NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg); 164 } 165} 166 167/******************************************************************************* 168** 169** Function HAL_NfcWrite 170** 171** Description Send an NCI control message or data packet to the 172** transport. If an NCI command message exceeds the transport 173** size, HAL is responsible for fragmenting it, Data packets 174** must be of the correct size. 175** 176** Returns void 177** 178*******************************************************************************/ 179void HAL_NfcWrite(uint16_t data_len, uint8_t* p_data) { 180 NFC_HDR* p_msg; 181 uint8_t mt; 182 183 HAL_TRACE_API0("HAL_NfcWrite ()"); 184 185 if (data_len > (NCI_MAX_CTRL_SIZE + NCI_MSG_HDR_SIZE)) { 186 HAL_TRACE_ERROR1("HAL_NfcWrite (): too many bytes (%d)", data_len); 187 return; 188 } 189 190 /* Send message to NFC_HAL_TASK */ 191 p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID); 192 if (p_msg != NULL) { 193 p_msg->event = NFC_HAL_EVT_TO_NFC_NCI; 194 p_msg->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; 195 p_msg->len = data_len; 196 memcpy((uint8_t*)(p_msg + 1) + p_msg->offset, p_data, data_len); 197 198 /* Check if message is a command or data */ 199 mt = (*(p_data)&NCI_MT_MASK) >> NCI_MT_SHIFT; 200 p_msg->layer_specific = (mt == NCI_MT_CMD) ? NFC_HAL_WAIT_RSP_CMD : 0; 201 202 GKI_send_msg(NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg); 203 } 204} 205 206/******************************************************************************* 207** 208** Function HAL_NfcPreDiscover 209** 210** Description Perform any vendor-specific pre-discovery actions (if 211*needed) 212** If any actions were performed TRUE will be returned, and 213** HAL_PRE_DISCOVER_DONE_EVENT will notify when actions are 214** completed. 215** 216** Returns TRUE if vendor-specific pre-discovery actions initialized 217** FALSE if no vendor-specific pre-discovery actions are 218*needed. 219** 220*******************************************************************************/ 221bool HAL_NfcPreDiscover(void) { 222 bool status = false; 223 224 NFC_HDR* p_msg; 225 226 HAL_TRACE_API0("HAL_NfcPreDiscover ()"); 227 if (nfc_hal_cb.pre_discover_done == false) { 228 nfc_hal_cb.pre_discover_done = true; 229 if (p_nfc_hal_pre_discover_cfg && *p_nfc_hal_pre_discover_cfg) { 230 status = true; 231 /* Send message to NFC_HAL_TASK */ 232 p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID); 233 if (p_msg != NULL) { 234 p_msg->event = NFC_HAL_EVT_PRE_DISCOVER; 235 GKI_send_msg(NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg); 236 } 237 } 238 } 239 240 HAL_TRACE_API1("HAL_NfcPreDiscover status:%d", status); 241 return status; 242} 243 244/******************************************************************************* 245** 246** Function HAL_NfcControlGranted 247** 248** Description Grant control to HAL control for sending NCI commands. 249** 250** Call in response to HAL_REQUEST_CONTROL_EVENT. 251** 252** Must only be called when there are no NCI commands pending. 253** 254** HAL_RELEASE_CONTROL_EVENT will notify when HAL no longer 255** needs control of NCI. 256** 257** 258** Returns void 259** 260*******************************************************************************/ 261void HAL_NfcControlGranted(void) { 262 NFC_HDR* p_msg; 263 HAL_TRACE_API0("HAL_NfcControlGranted ()"); 264 265 /* Send message to NFC_HAL_TASK */ 266 p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID); 267 if (p_msg != NULL) { 268 p_msg->event = NFC_HAL_EVT_CONTROL_GRANTED; 269 GKI_send_msg(NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg); 270 } 271} 272 273/******************************************************************************* 274** 275** Function HAL_NfcPowerCycle 276** 277** Description Restart NFCC by power cyle 278** 279** HAL_OPEN_CPLT_EVT will notify when operation is complete. 280** 281** Returns void 282** 283*******************************************************************************/ 284void HAL_NfcPowerCycle(void) { 285 HAL_TRACE_API0("HAL_NfcPowerCycle ()"); 286 287 /* Only handle if HAL is opened (stack cback is not-NULL) */ 288 if (nfc_hal_cb.p_stack_cback) { 289 /* Send power cycle event to NFC_HAL_TASK */ 290 GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_POWER_CYCLE); 291 } 292} 293 294/******************************************************************************* 295** 296** Function HAL_NfcGetMaxNfcee 297** 298** Description Retrieve the maximum number of NFCEEs supported by NFCC 299** 300** Returns the maximum number of NFCEEs supported by NFCC 301** 302*******************************************************************************/ 303uint8_t HAL_NfcGetMaxNfcee(void) { 304 HAL_TRACE_API1("HAL_NfcGetMaxNfcee: %d", nfc_hal_cb.max_ee); 305 return nfc_hal_cb.max_ee; 306} 307