2 * Copyright (C) 2010 NXP Semiconductors
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 * \brief Common LLC for the upper layer.
21 * Project: NFC-FRI-1.1
23 * $Date: Wed Apr 28 17:07:03 2010 $
26 * $Aliases: NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $
30 /*************************** Includes *******************************/
31 #include <phNfcTypes.h>
32 #include <phNfcStatus.h>
33 #include <phOsalNfc.h>
34 #include <phNfcInterface.h>
35 #include <phLlcNfc_DataTypes.h>
37 #include <phLlcNfc_Frame.h>
38 #include <phLlcNfc_Interface.h>
39 #include <phLlcNfc_Timer.h>
41 /*********************** End of includes ****************************/
43 /***************************** Macros *******************************/
45 /************************ End of macros *****************************/
47 /***************************** Global variables *******************************/
49 #ifdef LLC_RELEASE_FLAG
50 uint8_t g_release_flag;
51 #endif /* #ifdef LLC_RELEASE_FLAG */
53 /************************ End of global variables *****************************/
57 /*********************** Local functions ****************************/
59 * \ingroup grp_hal_nfc_llc
61 * \brief \b Init function
63 * \copydoc page_reg Initialise all variables of the LLC component (Asynchronous function).
65 * \param[in] pContext LLC context provided by the upper layer. The LLC
66 * context will be given to the upper layer through the
67 * \ref phLlcNfc_Register function
68 * \param[in] pLinkInfo Link information of the hardware
70 * \retval NFCSTATUS_PENDING If the command is yet to be processed.
71 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
72 * \retval Other errors Errors related to the lower layers
83 * \ingroup grp_hal_nfc_llc
85 * \brief \b Send function
87 * \copydoc page_reg This asynchronous function gets the information from the upper layer and creates the
88 * proper LLC packet to send the information it to the hardware. The number of
89 * bytes written is obtained from the send response callback which has been
90 * registered in \ref phLlcNfc_Register function
92 * \param[in] pContext LLC context is provided by the upper layer. The LLC
93 * context earlier was given to the upper layer through the
94 * \ref phLlcNfc_Register function
95 * \param[in] pLinkInfo Link information of the hardware.
96 * \param[in] pLlc_Buf The information given by the upper layer to send it to
98 * \param[in] llcBufLength the length of pLlc_Buf, that needs to be sent to the
99 * lower layer is given by the upper layer
101 * \retval NFCSTATUS_PENDING If the command is yet to be process.
102 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
103 * \retval Other errors Errors related to the lower layers
112 uint16_t llcBufLength
116 * \ingroup grp_hal_nfc_llc
118 * \brief \b Receive function
120 * \copydoc page_reg This asynchronous function gets the length and the required buffer from
121 * the upper layer to receive the information from the the hardware. The
122 * received data will be given through the receive response callback
123 * which has been registered in the \b phLlcNfc_Register function
125 * \param[in] pContext LLC context is provided by the upper layer. The LLC
126 * context earlier was given to the upper layer through the
127 * \b phLlcNfc_Register function
128 * \param[in] pLinkInfo Link information of the hardware
129 * \param[in] pLlc_Buf The information given by the upper layer to receive data from
131 * \param[in] llcBufLength The length of pLlc_Buf given by the upper layer
133 * \retval NFCSTATUS_PENDING If the command is yet to be process.
134 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
135 * \retval Other errors Errors related to the lower layers
144 uint16_t llcBufLength
146 /******************** End of Local functions ************************/
148 /********************** Global variables ****************************/
150 /******************** End of Global Variables ***********************/
154 phNfcIF_sReference_t *psReference,
155 phNfcIF_sCallBack_t if_callback,
159 NFCSTATUS result = NFCSTATUS_SUCCESS;
160 phLlcNfc_Context_t *ps_llc_ctxt = NULL;
161 phNfcLayer_sCfg_t *psconfig = (phNfcLayer_sCfg_t *)psIFConfig;
163 PH_LLCNFC_PRINT("Llc Register called\n");
164 if ((NULL == psReference) || (NULL == psIFConfig) ||
165 (NULL == psReference->plower_if) ||
167 (NULL == if_callback.pif_ctxt) ||
169 (NULL == if_callback.notify) ||
170 (NULL == if_callback.receive_complete) ||
171 (NULL == if_callback.send_complete))
173 result = PHNFCSTVAL(CID_NFC_LLC,
174 NFCSTATUS_INVALID_PARAMETER);
178 /* Now LLC is in RESET state */
179 ps_llc_ctxt = (phLlcNfc_Context_t*)phOsalNfc_GetMemory(
180 sizeof(phLlcNfc_Context_t));
181 if (NULL == ps_llc_ctxt)
183 /* Memory allocation failed */
184 result = PHNFCSTVAL(CID_NFC_LLC,
185 NFCSTATUS_INSUFFICIENT_RESOURCES);
189 result = NFCSTATUS_SUCCESS;
191 (void)memset(ps_llc_ctxt, 0, sizeof(phLlcNfc_Context_t));
193 /* Register the LLC functions to the upper layer */
194 psReference->plower_if->init = (pphNfcIF_Interface_t)&phLlcNfc_Init;
195 psReference->plower_if->release = (pphNfcIF_Interface_t)&phLlcNfc_Release;
196 psReference->plower_if->send = (pphNfcIF_Transact_t)&phLlcNfc_Send;
197 psReference->plower_if->receive = (pphNfcIF_Transact_t)&phLlcNfc_Receive;
198 /* Copy the LLC context to the upper layer */
199 psReference->plower_if->pcontext = ps_llc_ctxt;
201 /* Register the callback function from the upper layer */
202 ps_llc_ctxt->cb_for_if.receive_complete = if_callback.receive_complete;
203 ps_llc_ctxt->cb_for_if.send_complete = if_callback.send_complete;
204 ps_llc_ctxt->cb_for_if.notify = if_callback.notify;
205 /* Get the upper layer context */
206 ps_llc_ctxt->cb_for_if.pif_ctxt = if_callback.pif_ctxt;
208 result = phLlcNfc_Interface_Register(ps_llc_ctxt, psconfig);
210 if (NFCSTATUS_SUCCESS == result)
212 #ifdef LLC_RELEASE_FLAG
213 g_release_flag = FALSE;
214 #endif /* #ifdef LLC_RELEASE_FLAG */
218 PH_LLCNFC_DEBUG("Llc Register result : 0x%x\n", result);
229 NFCSTATUS result = NFCSTATUS_SUCCESS;
230 phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext;
231 phLlcNfc_LlcPacket_t s_packet_info;
233 PH_LLCNFC_PRINT("Llc Init called\n");
234 if ((NULL == ps_llc_ctxt) || (NULL == pLinkInfo))
236 result = PHNFCSTVAL(CID_NFC_LLC,
237 NFCSTATUS_INVALID_PARAMETER);
242 ps_llc_ctxt->phwinfo = pLinkInfo;
243 /* Call the internal frame initialise */
244 phLlcNfc_H_Frame_Init(ps_llc_ctxt);
245 /* Call the internal LLC TL interface initialise */
246 result = phLlcNfc_Interface_Init(ps_llc_ctxt);
247 if (NFCSTATUS_SUCCESS == result)
249 /* Call the internal LLC timer initialise */
250 result = phLlcNfc_TimerInit(ps_llc_ctxt);
253 if (NFCSTATUS_SUCCESS == result)
255 /* Create the static timer */
256 phLlcNfc_CreateTimers();
258 /* Create a U frame */
259 result = phLlcNfc_H_CreateUFramePayload(ps_llc_ctxt,
261 &(s_packet_info.llcbuf_len),
264 if (NFCSTATUS_SUCCESS == result)
267 result = phLlcNfc_Interface_Write(ps_llc_ctxt,
268 (uint8_t*)&(s_packet_info.s_llcbuf),
269 (uint32_t)s_packet_info.llcbuf_len);
271 if (NFCSTATUS_PENDING == result)
273 /* Start the timer */
274 result = phLlcNfc_StartTimers(PH_LLCNFC_CONNECTIONTIMER, 0);
275 if (NFCSTATUS_SUCCESS == result)
277 ps_llc_ctxt->s_frameinfo.sent_frame_type =
279 result = NFCSTATUS_PENDING;
283 if (NFCSTATUS_PENDING != result)
285 (void)phLlcNfc_Release(ps_llc_ctxt, pLinkInfo);
288 PH_LLCNFC_DEBUG("Llc Init result : 0x%x\n", result);
298 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC,
299 NFCSTATUS_INVALID_PARAMETER);
300 phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext;
302 1. Free all the memory allocated in initialise
304 PH_LLCNFC_PRINT("Llc release called\n");
306 if ((NULL != ps_llc_ctxt) && (NULL != pLinkInfo))
308 result = NFCSTATUS_SUCCESS;
309 ps_llc_ctxt->phwinfo = pLinkInfo;
310 #ifdef INCLUDE_DALINIT_DEINIT
311 if (NULL != ps_llc_ctxt->lower_if.release)
313 result = ps_llc_ctxt->lower_if.release(
314 ps_llc_ctxt->lower_if.pcontext,
318 if (NULL != ps_llc_ctxt->lower_if.transact_abort)
320 result = ps_llc_ctxt->lower_if.transact_abort(
321 ps_llc_ctxt->lower_if.pcontext,
324 if (NULL != ps_llc_ctxt->lower_if.unregister)
326 result = ps_llc_ctxt->lower_if.unregister(
327 ps_llc_ctxt->lower_if.pcontext,
331 /* Call the internal LLC timer un-initialise */
332 phLlcNfc_TimerUnInit(ps_llc_ctxt);
333 phLlcNfc_H_Frame_DeInit(&ps_llc_ctxt->s_frameinfo);
334 (void)memset(ps_llc_ctxt, 0, sizeof(phLlcNfc_Context_t));
335 phOsalNfc_FreeMemory(ps_llc_ctxt);
338 #ifdef LLC_RELEASE_FLAG
339 g_release_flag = TRUE;
340 #endif /* #ifdef LLC_RELEASE_FLAG */
343 PH_LLCNFC_DEBUG("Llc release result : 0x%04X\n", result);
353 uint16_t llcBufLength
357 1. Check the function parameters for valid values
358 2. Create the I frame llc payload using the upper layer buffer
359 3. Send the updated buffer to the below layer
360 4. Store the I frame in a list, till acknowledge is received
362 NFCSTATUS result = NFCSTATUS_SUCCESS;
363 phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext;
364 phLlcNfc_Frame_t *ps_frame_info = NULL;
365 phLlcNfc_LlcPacket_t s_packet_info;
366 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL;
371 PH_LLCNFC_PRINT ("Llc Send called\n");
372 if ((NULL == ps_llc_ctxt) || (NULL == pLinkInfo) ||
373 (NULL == pLlcBuf) || (0 == llcBufLength) ||
374 (llcBufLength > PH_LLCNFC_MAX_IFRAME_BUFLEN))
376 /* Parameter check failed */
377 result = PHNFCSTVAL(CID_NFC_LLC,
378 NFCSTATUS_INVALID_PARAMETER);
380 else if (ps_llc_ctxt->s_frameinfo.s_send_store.winsize_cnt >=
381 ps_llc_ctxt->s_frameinfo.window_size)
383 /* Window size check failed */
384 result = PHNFCSTVAL(CID_NFC_LLC,
385 NFCSTATUS_NOT_ALLOWED);
389 ps_frame_info = &(ps_llc_ctxt->s_frameinfo);
390 ps_store_frame = &(ps_frame_info->s_send_store);
392 PH_LLCNFC_DEBUG ("Buffer length : 0x%04X\n", llcBufLength);
393 PH_LLCNFC_PRINT_BUFFER (pLlcBuf, llcBufLength);
395 /* Copy the hardware information */
396 ps_llc_ctxt->phwinfo = pLinkInfo;
398 /* Create I frame with the user buffer */
399 (void)phLlcNfc_H_CreateIFramePayload (
400 &(ps_llc_ctxt->s_frameinfo),
402 pLlcBuf, (uint8_t)llcBufLength);
405 /* Store the I frame in the send list */
406 (void)phLlcNfc_H_StoreIFrame (ps_store_frame, s_packet_info);
407 result = NFCSTATUS_PENDING;
409 #ifdef CTRL_WIN_SIZE_COUNT
411 /* No check required */
412 if ((TRUE != ps_frame_info->write_pending) &&
413 (PH_LLCNFC_READPEND_REMAIN_BYTE !=
414 ps_frame_info->read_pending))
416 #else /* #ifdef CTRL_WIN_SIZE_COUNT */
418 if (1 == ps_frame_info->s_send_store.winsize_cnt)
420 #endif /* #ifdef CTRL_WIN_SIZE_COUNT */
422 /* Call write to the below layer, only if previous write
424 result = phLlcNfc_Interface_Write (ps_llc_ctxt,
425 (uint8_t *)&(s_packet_info.s_llcbuf),
426 (uint32_t)s_packet_info.llcbuf_len);
428 if ((NFCSTATUS_PENDING == result) ||
429 (NFCSTATUS_BUSY == PHNFCSTATUS (result)))
431 ps_frame_info->write_status = result;
432 if (NFCSTATUS_BUSY == PHNFCSTATUS(result))
434 result = NFCSTATUS_PENDING;
435 ps_frame_info->write_wait_call = (phLlcNfc_eSentFrameType_t)
436 ((resend_i_frame == ps_frame_info->write_wait_call) ?
437 ps_frame_info->write_wait_call : user_i_frame);
441 /* Start the timer */
442 (void)phLlcNfc_StartTimers (PH_LLCNFC_GUARDTIMER,
445 /* "sent_frame_type is updated" only if the data is
446 written to the lower layer */
447 ps_frame_info->sent_frame_type = user_i_frame;
451 /* Get the added frame array count */
452 count = (uint8_t)((((ps_store_frame->start_pos +
453 ps_store_frame->winsize_cnt) - count)) %
454 PH_LLCNFC_MOD_NS_NR);
459 ps_frame_info->write_status = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_BUSY);
460 ps_frame_info->write_wait_call = (phLlcNfc_eSentFrameType_t)
461 ((resend_i_frame == ps_frame_info->write_wait_call) ?
462 ps_frame_info->write_wait_call : user_i_frame);
467 PH_LLCNFC_DEBUG ("Llc Send result : 0x%04X\n", result);
477 uint16_t llcBufLength
480 NFCSTATUS result = NFCSTATUS_SUCCESS;
481 phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext;
482 phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL;
484 PH_LLCNFC_PRINT("Llc Receive called\n");
485 if ((NULL == ps_llc_ctxt) || (NULL == pLinkInfo) ||
486 (NULL == pLlcBuf) || (0 == llcBufLength) ||
487 (llcBufLength > PH_LLCNFC_MAX_IFRAME_BUFLEN))
489 result = PHNFCSTVAL(CID_NFC_LLC,
490 NFCSTATUS_INVALID_PARAMETER);
494 ps_llc_ctxt->phwinfo = pLinkInfo;
496 ps_recv_pkt = &(ps_llc_ctxt->s_frameinfo.s_recvpacket);
497 /* Always read the first byte to read the length, then
498 read the entire data later using the 1 byte buffer */
499 llcBufLength = PH_LLCNFC_BYTES_INIT_READ;
500 /* Call write to the below layer */
501 result = phLlcNfc_Interface_Read(ps_llc_ctxt,
502 PH_LLCNFC_READWAIT_OFF,
503 &(ps_recv_pkt->s_llcbuf.llc_length_byte),
506 ps_llc_ctxt->s_frameinfo.upper_recv_call = TRUE;
507 if (NFCSTATUS_PENDING != result)
509 ps_llc_ctxt->state = phLlcNfc_Initialised_State;
512 PH_LLCNFC_DEBUG("Llc Receive result : 0x%04X\n", result);