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 *******************************************************************************/
HAL_NfcInitialize(void)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 *******************************************************************************/
HAL_NfcTerminate(void)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 *******************************************************************************/
HAL_NfcOpen(tHAL_NFC_CBACK * p_hal_cback,tHAL_NFC_DATA_CBACK * p_data_cback)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 *******************************************************************************/
HAL_NfcClose(void)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 *******************************************************************************/
HAL_NfcCoreInitialized(uint16_t data_len,uint8_t * p_core_init_rsp_params)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 *******************************************************************************/
HAL_NfcWrite(uint16_t data_len,uint8_t * p_data)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 *******************************************************************************/
HAL_NfcPreDiscover(void)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 *******************************************************************************/
HAL_NfcControlGranted(void)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 *******************************************************************************/
HAL_NfcPowerCycle(void)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 *******************************************************************************/
HAL_NfcGetMaxNfcee(void)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