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 36 uint32_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 *******************************************************************************/ 49 void 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 *******************************************************************************/ 82 void 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 *******************************************************************************/ 96 void 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 *******************************************************************************/ 121 void 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 *******************************************************************************/ 144 void 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 *******************************************************************************/ 179 void 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 *******************************************************************************/ 221 bool 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 *******************************************************************************/ 261 void 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 *******************************************************************************/ 284 void 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 *******************************************************************************/ 303 uint8_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