1 /***************************************************************************//**
2 * \file cy_ipc_bt.c
3 * \version 1.91
4 *
5 * \brief
6 *  This driver provides the source code for BT IPC.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
11 * an affiliate of Cypress Semiconductor Corporation.
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 *     http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26 
27 #include "cy_device.h"
28 
29 #if defined (CY_IP_MXIPC)
30 
31 #include "cy_ipc_bt.h"
32 
33 /* Should not include this. To be removed */
34 #include <string.h>
35 
36 #include <stdio.h>
37 
38 CY_MISRA_DEVIATE_BLOCK_START('ARRAY_VS_SINGLETON', 1, \
39 'Checked manually. Using pointer as an array will not corrupt or misinterpret adjacent memory locations.')
40 
41 //#define BTIPC_DBG_L0
42 //#define BTIPC_DBG_L1
43 //#define BTIPC_DBG_L2
44 //#define BTIPC_STATUS
45 
46 /** Buffer descriptor offset in the init message */
47 #ifndef BT_OLD_INIT
48 #define INIT_IPC_BUFF_DESC_OFFSET 5
49 #else
50 #define INIT_IPC_BUFF_DESC_OFFSET 1
51 #endif
52 
53 #ifdef BTIPC_DBG_L0
54 #define BTIPC_LOG_L0(...)   printf(__VA_ARGS__)
55 #else
56 #define BTIPC_LOG_L0(...)
57 #endif
58 
59 #ifdef BTIPC_DBG_L1
60 #define BTIPC_LOG_L1(...)   printf(__VA_ARGS__)
61 #else
62 #define BTIPC_LOG_L1(...)
63 #endif
64 
65 #ifdef BTIPC_DBG_L2
66 #define BTIPC_LOG_L2(...)   printf(__VA_ARGS__)
67 #else
68 #define BTIPC_LOG_L2(...)
69 #endif
70 
71 /* local functions prototype */
72 cy_en_btipcdrv_status_t Cy_bt_handle_hpclong_msg(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t * msgPtr);
73 cy_en_btipcdrv_status_t Cy_bt_handle_buf_add(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t * msgPtr);
74 static cy_en_btipc_buftype_t Cy_bt_get_buf_type(cy_en_btipc_hcipti_t pti);
75 static uint32_t Cy_bt_getPLLegnth(cy_en_btipc_hcipti_t pti, uint8_t* bufAddr);
76 static bool Cy_bt_isOffsetNeeded(cy_en_btipc_hcipti_t pti);
77 static cy_en_btipcdrv_status_t Cy_bt_GetBuffer (cy_stc_ipc_bt_context_t *btIpcContext, void **ppBuf, cy_en_btipc_buftype_t bufType, size_t length);
78 static cy_en_btipcdrv_status_t Cy_bt_PutBuffer(cy_stc_ipc_bt_context_t *btIpcContext, cy_stc_ipc_bt_buf_t *bufDecriptor);
79 static cy_en_btipcdrv_status_t Cy_BTIPC_HCI_FIFOPut(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t *pMsg);
80 cy_en_btipcdrv_status_t Cy_BTIPC_HPC_RelBuffer(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t* msgPtr);
81 
82 CY_IPC_SECTION_BEGIN
Cy_BTIPC_IRQ_Handler(cy_stc_ipc_bt_context_t * btIpcContext)83 void Cy_BTIPC_IRQ_Handler(cy_stc_ipc_bt_context_t *btIpcContext)
84 {
85     uint32_t shadowIntr;
86     IPC_STRUCT_Type *ipcPtr;
87     IPC_INTR_STRUCT_Type *ipcIntrPtr;
88     uint32_t mesg[2], backup[2];
89     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
90     uint32_t notify;
91     uint32_t release;
92     uint32_t channelHCI;
93     uint32_t channelHPC;
94     uint8_t idx;
95     cy_en_btipc_hpcpti_t msgType;
96 
97     if (NULL == contextPtr)
98     {
99         BTIPC_LOG_L0("Context ptr null\n");
100         return;
101     }
102 
103 #ifdef CY_BTIPC_STATS
104     contextPtr->ipc_int_count++;
105 #endif
106 
107     ipcIntrPtr = Cy_IPC_Drv_GetIntrBaseAddr(contextPtr->intStuctureSelf);
108     shadowIntr = Cy_IPC_Drv_GetInterruptStatusMasked(ipcIntrPtr);
109 
110     notify = Cy_IPC_Drv_ExtractAcquireMask(shadowIntr);
111 
112     /* Check to make sure the interrupt was a release interrupt */
113     release = Cy_IPC_Drv_ExtractReleaseMask(shadowIntr);
114 
115     BTIPC_LOG_L1("shadow 0x%lx, notifyMask 0x%lx, relMask 0x%lx\n", shadowIntr, notify, release);
116 
117     /* First process the release callback */
118     if (0UL != release)  /* Check for a Release interrupt */
119     {
120         BTIPC_LOG_L1("Release int\n");
121         /* Clear the release interrupt  */
122         Cy_IPC_Drv_ClearInterrupt(ipcIntrPtr, release, CY_IPC_NO_NOTIFICATION);
123 #ifdef CY_BTIPC_STATS
124         if ((release & (uint32_t)(0x1UL << contextPtr->ulChannelHPC)) != 0UL)
125         {
126             contextPtr->ipc_hpc_release_count++;
127         }
128         if ((release & (uint32_t)(0x1UL << contextPtr->ulChannelHCI)) != 0UL)
129         {
130             contextPtr->ipc_hci_release_count++;
131         }
132 #endif
133         /* release callback can be added here. */
134         if ((contextPtr->ulReleaseCallbackPtr) != NULL )
135         {
136             contextPtr->ulReleaseCallbackPtr();
137         }
138     }
139 
140     /* Check to make sure the interrupt was a notify interrupt */
141     if (0UL != notify)
142     {
143         BTIPC_LOG_L1("Notify int ");
144         /* Clear the notify interrupt.  */
145         Cy_IPC_Drv_ClearInterrupt(ipcIntrPtr, CY_IPC_NO_NOTIFICATION, notify);
146 
147         if ((notify & (uint32_t)(0x1UL << contextPtr->dlChannelHPC)) != 0UL)
148         {
149 #ifdef CY_BTIPC_STATS
150             contextPtr->ipc_hpc_notify_count++;
151             if (contextPtr->ipc_hci_fifo_full > 0UL)
152             {
153                 contextPtr->ipc_hci_notify_in_fifo_full++;
154             }
155 #endif
156             channelHPC = contextPtr->dlChannelHPC;
157 
158             BTIPC_LOG_L1("on ch %ld\n",channelHPC);
159 
160             ipcPtr = Cy_IPC_Drv_GetIpcBaseAddress(channelHPC);
161             Cy_IPC_Drv_ReadDDataValue(ipcPtr, mesg);
162             /* Keep back up of mesg needed to release the buffer */
163             backup[0] = mesg[0];
164             backup[1] = mesg[1];
165 
166             CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_btipc_hpcpti_t enum.');
167             msgType = (cy_en_btipc_hpcpti_t)((0xFFUL) & mesg[0]);
168 
169             BTIPC_LOG_L1("HPC payload type %d\n",msgType);
170 
171             if ((contextPtr->internal_hpc_notify_cb) != NULL)
172             {
173                 BTIPC_LOG_L1("Notify HPC int cb+\n");
174                 contextPtr->internal_hpc_notify_cb((void*)contextPtr, mesg);
175                 BTIPC_LOG_L1("Notify HPC int cb-\n");
176             }
177             for (idx = 0; idx < ((uint8_t)MAX_BT_IPC_HPC_CB); idx++)
178             {
179                 BTIPC_LOG_L1("idx %d, Notify HPC cb %p, msgType %d\n",idx, contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr, contextPtr->hpcNotifyCallbackParam[idx].msgType);
180                 if ((contextPtr->hpcNotifyCallbackParam[idx].msgType == msgType) &&
181                     (contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr != NULL))
182                 {
183                    BTIPC_LOG_L1("Calling Notify HPC cb %p\n",contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr);
184                     if ((msgType == CY_BT_IPC_HPC_LONG) && (*(((uint8_t*)mesg)+1) == (uint8_t)CY_BT_IPC_HPC_INIT))
185                     {
186                         /* Add Boot type to the message add pass it to the application */
187                         *(((uint8_t*)mesg)+2) = contextPtr->bootType;
188                         /* Certificate error field, so that the app can process if needed */
189                         mesg[1] = contextPtr->certError;
190                     }
191                     contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr(mesg);
192                 }
193             }
194             /* Release channel for HPC message only */
195             (void)Cy_BTIPC_HPC_RelChannel(contextPtr, backup); /* Suppress a compiler warning about unused return value */
196 #ifdef CY_BTIPC_STATS
197             contextPtr->ipc_hpc_peer_release_count++;
198 #endif
199             if (0xFFUL == (0xFFUL & mesg[0]))
200             {
201                 (void)Cy_BTIPC_HPC_RelBuffer(contextPtr, backup); /* Suppress a compiler warning about unused return value */
202             }
203         }
204 
205         if ((notify & (uint32_t)(0x1UL << contextPtr->dlChannelHCI)) != 0UL)
206         {
207 #ifdef CY_BTIPC_STATS
208             contextPtr->ipc_hci_notify_count++;
209 #endif
210             channelHCI = contextPtr->dlChannelHCI;
211 
212             BTIPC_LOG_L1("on ch %ld\n",channelHCI);
213 
214             ipcPtr = Cy_IPC_Drv_GetIpcBaseAddress(channelHCI);
215             Cy_IPC_Drv_ReadDDataValue(ipcPtr, mesg);
216             /* Push the mesg to FIFO */
217             if (((uint32_t)Cy_BTIPC_HCI_FIFOPut(contextPtr, mesg)) == 0UL)
218             {
219                 if (((uint16_t)MAX_IPC_FIFO_SIZE) > Cy_BTIPC_HCI_FIFOCount(contextPtr))
220                 {
221                     /* Release channel for HCI message only if FIFO is not full */
222                     (void)Cy_BTIPC_HCI_RelChannel(contextPtr); /* Suppress a compiler warning about unused return value */
223 #ifdef CY_BTIPC_STATS
224                     contextPtr->ipc_hci_peer_release_count++;
225 #endif
226                 }
227                 else
228                 {
229                     contextPtr->ipc_hci_fifo_full++;
230                     BTIPC_LOG_L0("\nFIFO is Full. Ch 0x%lx not released !\n",channelHCI);
231                 }
232                 BTIPC_LOG_L1("FIFO count %d\n",contextPtr->IpcFifo.bufLen);
233 
234                 /* call the callback function */
235                 if ((contextPtr->dlNotifyCallbackPtr) != NULL)
236                 {
237 
238                     BTIPC_LOG_L1("Notify HCI cb\n");
239                     contextPtr->dlNotifyCallbackPtr(mesg);
240                 }
241             }
242             else
243             {
244                 BTIPC_LOG_L0("Error: Msg received after FIFO is full !\n");
245                 contextPtr->droppedHCI++;
246                 /* Add assert here */
247                 CY_ASSERT_L1(false);
248                 return;
249             }
250         }
251     }
252 }
253 CY_IPC_SECTION_END
254 
255 CY_IPC_SECTION_BEGIN
Cy_BTIPC_HCI_RelChannel(cy_stc_ipc_bt_context_t * btIpcContext)256 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_RelChannel(cy_stc_ipc_bt_context_t *btIpcContext)
257 {
258     IPC_STRUCT_Type *ipcPtr;
259     uint32_t rel_mask;
260     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
261 
262     if (NULL == contextPtr)
263     {
264         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
265     }
266 
267     ipcPtr = Cy_IPC_Drv_GetIpcBaseAddress (contextPtr->dlChannelHCI);
268 
269     rel_mask = (uint32_t)(1UL << contextPtr->intStucturePeer);
270 
271     Cy_IPC_Drv_ReleaseNotify(ipcPtr, rel_mask);
272 
273     return CY_BT_IPC_DRV_SUCCESS;
274 }
275 CY_IPC_SECTION_END
276 
277 
Cy_BTIPC_HPC_RelChannel(cy_stc_ipc_bt_context_t * btIpcContext,void * buf)278 cy_en_btipcdrv_status_t Cy_BTIPC_HPC_RelChannel(cy_stc_ipc_bt_context_t *btIpcContext, void * buf)
279 {
280     IPC_STRUCT_Type *ipcPtr;
281     uint32_t rel_mask;
282     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
283     (void)buf;
284     // Fix if this is causing issue
285 #if 1
286     if ((NULL == contextPtr) || (NULL == buf))
287     {
288         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
289     }
290 #endif
291 
292     ipcPtr = Cy_IPC_Drv_GetIpcBaseAddress (contextPtr->dlChannelHPC);
293 
294     rel_mask = (uint32_t)(1UL << contextPtr->intStucturePeer);
295     BTIPC_LOG_L1("Release %p, mask 0x%lx\n", ipcPtr, rel_mask);
296     Cy_IPC_Drv_ReleaseNotify(ipcPtr, rel_mask);
297     BTIPC_LOG_L1("Release register 0x%lx\n", ipcPtr->RELEASE);
298     return CY_BT_IPC_DRV_SUCCESS;
299 }
300 
301 
Cy_BTIPC_HCI_RelBuffer(cy_stc_ipc_bt_context_t * btIpcContext,uint32_t * msgPtr)302 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_RelBuffer(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t* msgPtr)
303 {
304     cy_stc_ipc_msg_alloc_t ipcMsgAlloc;
305     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
306     uint8_t idx;
307     uint8_t found;
308     uint32_t interruptState;
309     uint32_t *pMsg;
310 
311     if ((NULL == contextPtr) || (NULL == msgPtr))
312     {
313         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
314     }
315 
316     if (((cy_stc_ipc_msg_buff_t*)((void*)msgPtr))->pti != ((uint8_t)CY_BT_IPC_HCI_LONG))
317     {
318         /* Remove the FIFO entry */
319         (void)Cy_BTIPC_HCI_FIFOGet(contextPtr, &pMsg, 1);
320         return CY_BT_IPC_DRV_SUCCESS;
321     }
322 
323     found = 0;
324 
325     interruptState = Cy_SysLib_EnterCriticalSection();
326 
327     /* If the channel is busy then do not proceed further, return CH BUSY error */
328     if (Cy_IPC_Drv_IsLockAcquired (Cy_IPC_Drv_GetIpcBaseAddress(contextPtr->ulChannelHPC)))
329     {
330         Cy_SysLib_ExitCriticalSection(interruptState);
331         return CY_BT_IPC_DRV_ERROR_CH_BUSY;
332     }
333 
334     for (idx = 0U; idx < ((uint8_t)MAX_TO_FREE_BUF_COUNT); idx++)
335     {
336         if (contextPtr->toFreeBuf[idx].bufPtr == (uint8_t*)msgPtr[1])
337         {
338             ipcMsgAlloc.pti = (uint8_t)CY_BT_IPC_HPC_BUFRELEASE;
339             ipcMsgAlloc.bufType = ((uint8_t)contextPtr->toFreeBuf[idx].bufType);
340             ipcMsgAlloc.bufSize = contextPtr->toFreeBuf[idx].bufLen;
341             ipcMsgAlloc.bufAddr = contextPtr->toFreeBuf[idx].bufPtr;
342             found = 1;
343             contextPtr->toFreeBuf[idx].bufType = CY_BT_IPC_HCI_INVALID_BUF;
344             contextPtr->toFreeBuf[idx].bufLen = 0;
345             contextPtr->toFreeBuf[idx].bufPtr = NULL;
346             break;
347         }
348     }
349 
350     Cy_SysLib_ExitCriticalSection(interruptState);
351 
352     /* Remove the FIFO entry */
353     (void)Cy_BTIPC_HCI_FIFOGet(contextPtr, &pMsg, 1);
354 
355     if (found != 0UL)
356     {
357 #ifdef CY_BTIPC_STATS
358         contextPtr->ipc_hci_peer_outbuf_count++;
359 #endif
360         return (Cy_BTIPC_HPC_Write(contextPtr, &ipcMsgAlloc, (size_t) 2));
361     }
362     else
363     {
364         return CY_BT_IPC_DRV_ERROR_BUF_GET;
365     }
366 }
367 
368 
Cy_BTIPC_HPC_RelBuffer(cy_stc_ipc_bt_context_t * btIpcContext,uint32_t * msgPtr)369 cy_en_btipcdrv_status_t Cy_BTIPC_HPC_RelBuffer(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t* msgPtr)
370 {
371     cy_stc_ipc_msg_alloc_t ipcMsgAlloc;
372     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
373 
374     if ((NULL == contextPtr) || (NULL == msgPtr))
375     {
376         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
377     }
378 
379     BTIPC_LOG_L1("Releasing HPC buffer 0x%lx\n", msgPtr[1]);
380 #ifdef CY_BTIPC_STATS
381     contextPtr->ipc_hpc_peer_outbuf_count++;
382 #endif
383     ipcMsgAlloc.pti = (uint8_t)CY_BT_IPC_HPC_BUFRELEASE;
384     ipcMsgAlloc.bufType = 0;
385     ipcMsgAlloc.bufSize = 0;
386     ipcMsgAlloc.bufAddr = (uint8_t*)msgPtr[1];
387 
388     return (Cy_BTIPC_HPC_Write(contextPtr, &ipcMsgAlloc, (size_t) 2));
389 }
390 
391 
Cy_BTIPC_HPC_Notify(void * btIpcContext,uint32_t * msgPtr)392 void Cy_BTIPC_HPC_Notify(void *btIpcContext, uint32_t * msgPtr)
393 {
394     cy_en_btipc_hpcpti_t pti;
395     cy_stc_ipc_bt_context_t *contextPtr = (cy_stc_ipc_bt_context_t*) btIpcContext;
396     if ((NULL == contextPtr) || (NULL == msgPtr))
397     {
398         return;
399     }
400 
401     BTIPC_LOG_L1("Internal cb for HPC\n");
402 
403     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_btipc_hpcpti_t enum.');
404     pti = (cy_en_btipc_hpcpti_t)((0xFFUL) & msgPtr[0]);
405 
406     switch (pti)
407     {
408         case CY_BT_IPC_HPC_LONG:
409             (void)Cy_bt_handle_hpclong_msg(contextPtr, msgPtr);
410             break;
411         case CY_BT_IPC_HPC_BUFPROVIDE:
412             (void)Cy_bt_handle_buf_add(contextPtr, msgPtr);
413             break;
414         default:
415             /* default invalid pti */
416             break;
417     }
418 }
419 
420 
Cy_BTIPC_Init(cy_stc_ipc_bt_context_t * btIpcContext,cy_stc_ipc_bt_config_t * btIpcConfig)421 cy_en_btipcdrv_status_t Cy_BTIPC_Init(cy_stc_ipc_bt_context_t *btIpcContext, cy_stc_ipc_bt_config_t *btIpcConfig)
422 {
423     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
424     cy_en_btipcdrv_status_t status;
425     uint8_t idx;
426 
427     if ((NULL == contextPtr) || (NULL == btIpcConfig))
428     {
429         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
430     }
431 
432     contextPtr->dlChannelHCI = btIpcConfig->dlChannelHCI;
433     contextPtr->ulChannelHCI = btIpcConfig->ulChannelHCI;
434 
435     contextPtr->dlChannelHPC = btIpcConfig->dlChannelHPC;
436     contextPtr->ulChannelHPC = btIpcConfig->ulChannelHPC;
437 
438     contextPtr->intStuctureSelf = btIpcConfig->intStuctureSelf;
439     contextPtr->intStucturePeer = btIpcConfig->intStucturePeer;
440     contextPtr->intPeerMask = (uint32_t) (0x1UL << btIpcConfig->intStucturePeer);
441 
442     contextPtr->dlNotifyCallbackPtr = NULL;
443     contextPtr->ulReleaseCallbackPtr = btIpcConfig->ulReleaseCallbackPtr;
444     contextPtr->bufCallbackPtr = btIpcConfig->bufCallbackPtr;
445 
446     contextPtr->irqHandlerPtr = btIpcConfig->irqHandlerPtr;
447     contextPtr->ipcIntConfig.intrSrc = btIpcConfig->ipcIntConfig.intrSrc;
448     contextPtr->ipcIntConfig.intrPriority = btIpcConfig->ipcIntConfig.intrPriority;
449 
450     contextPtr->internal_hpc_notify_cb = btIpcConfig->internal_hpc_notify_cb;
451 
452     contextPtr->dlNotifyMask = (uint32_t)((uint32_t)(0x1UL << btIpcConfig->dlChannelHCI) | (uint32_t)(0x1UL << btIpcConfig->dlChannelHPC));
453     contextPtr->ulReleaseMask = (uint32_t)((uint32_t)(0x1UL << btIpcConfig->ulChannelHCI) | (uint32_t)(0x1UL << btIpcConfig->ulChannelHPC));
454 
455     contextPtr->droppedHCI = 0;
456 
457     contextPtr->bootType = 0xFF;
458 
459     for (idx = 0U; idx <((uint8_t)MAX_BT_IPC_HPC_CB); idx++)
460     {
461         contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr = NULL;
462         contextPtr->hpcNotifyCallbackParam[idx].msgType = CY_BT_IPC_HPC_RESERVED;
463     }
464 
465     for (idx = 0U; idx < ((uint8_t)MAX_BUF_COUNT); idx++)
466     {
467         contextPtr->buffPool[idx].bufPtr = NULL;
468         contextPtr->buffPool[idx].bufType = CY_BT_IPC_HCI_INVALID_BUF;
469     }
470 
471     for (idx = 0U; idx < ((uint8_t)MAX_IPC_FIFO_SIZE); idx++)
472     {
473         contextPtr->IpcFifo.fifo[idx].msg[0] = 0;
474         contextPtr->IpcFifo.fifo[idx].msg[1] = 0;
475     }
476     contextPtr->IpcFifo.rdIdx = 0;
477     contextPtr->IpcFifo.wrIdx = 0;
478     contextPtr->IpcFifo.bufLen = 0;
479 
480     for (idx = 0U; idx < ((uint8_t)MAX_TO_FREE_BUF_COUNT); idx++)
481     {
482         contextPtr->toFreeBuf[idx].bufPtr = NULL;
483         contextPtr->toFreeBuf[idx].bufType = CY_BT_IPC_HCI_INVALID_BUF;
484         contextPtr->toFreeBuf[idx].bufLen = 0;
485     }
486 
487     status = Cy_BTIPC_WarmInit(contextPtr, btIpcConfig);
488 
489 #ifdef CY_BTIPC_STATS
490     contextPtr->ipc_int_count = 0;
491 
492     contextPtr->ipc_hci_cmd_count = 0;
493     contextPtr->ipc_hpc_cmd_count = 0;
494 
495     contextPtr->ipc_hci_release_count = 0;
496     contextPtr->ipc_hpc_release_count = 0;
497 
498     contextPtr->ipc_hci_notify_count = 0;
499     contextPtr->ipc_hpc_notify_count = 0;
500 
501     contextPtr->ipc_hci_peer_release_count = 0;
502     contextPtr->ipc_hpc_peer_release_count = 0;
503 
504     contextPtr->ipc_hci_peer_inbuf_count = 0;
505     contextPtr->ipc_hci_peer_outbuf_count = 0;
506 
507     contextPtr->ipc_hpc_peer_inbuf_count = 0;
508     contextPtr->ipc_hpc_peer_outbuf_count = 0;
509 
510     contextPtr->ipc_hci_cmd_self_outbuf_count = 0;
511     contextPtr->ipc_hci_cmd_self_inbuf_count = 0;
512     contextPtr->ipc_hci_cmd_self_outbuf_success = 0;
513 
514     contextPtr->ipc_hci_fifo_full = 0;
515     contextPtr->ipc_hci_notify_in_fifo_full = 0;
516 #endif
517     return status;
518  }
519 
520 
Cy_BTIPC_WarmInit(cy_stc_ipc_bt_context_t * btIpcContext,cy_stc_ipc_bt_config_t * btIpcConfig)521 cy_en_btipcdrv_status_t Cy_BTIPC_WarmInit(cy_stc_ipc_bt_context_t *btIpcContext, cy_stc_ipc_bt_config_t *btIpcConfig)
522 {
523     cy_en_sysint_status_t intrStatus;
524     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
525 
526     if ((NULL == contextPtr) || (NULL == btIpcConfig))
527     {
528         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
529     }
530 
531     intrStatus = Cy_SysInt_Init(&contextPtr->ipcIntConfig, contextPtr->irqHandlerPtr);
532     if (((uint32_t)intrStatus) != 0UL)
533     {
534         return CY_BT_IPC_DRV_ERROR;
535     }
536 
537     /* enable interrupt */
538     NVIC_EnableIRQ(contextPtr->ipcIntConfig.intrSrc);
539 
540     /* Set IPC Interrupt mask */
541     /* Allow only notify on DL channel  and release on UL channel interrupts */
542     Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(contextPtr->intStuctureSelf), contextPtr->ulReleaseMask, contextPtr->dlNotifyMask);
543     return CY_BT_IPC_DRV_SUCCESS;
544  }
545 
546 
Cy_BTIPC_Deinit(cy_stc_ipc_bt_context_t * btIpcContext)547 cy_en_btipcdrv_status_t Cy_BTIPC_Deinit(cy_stc_ipc_bt_context_t *btIpcContext)
548 {
549     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
550     uint8_t idx;
551 
552     if (NULL == contextPtr)
553     {
554         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
555     }
556 
557     /* enable interrupt */
558     NVIC_DisableIRQ(contextPtr->ipcIntConfig.intrSrc);
559 
560     contextPtr->irqHandlerPtr = NULL;
561     contextPtr->internal_hpc_notify_cb = NULL;
562 
563     for (idx = 0; idx < ((uint8_t)MAX_BT_IPC_HPC_CB); idx++)
564     {
565         contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr = NULL;
566         contextPtr->hpcNotifyCallbackParam[idx].msgType = CY_BT_IPC_HPC_RESERVED;
567     }
568 
569     for (idx = 0U; idx < ((uint8_t)MAX_BUF_COUNT); idx++)
570     {
571         contextPtr->buffPool[idx].bufPtr = NULL;
572         contextPtr->buffPool[idx].bufType = CY_BT_IPC_HCI_INVALID_BUF;
573     }
574 
575     return CY_BT_IPC_DRV_SUCCESS;
576 }
577 
578 
579 CY_IPC_SECTION_BEGIN
Cy_BTIPC_HCI_getPTI(cy_en_btipc_hcipti_t * pti,uint32_t * p_length,uint32_t * msgPtr)580 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_getPTI (cy_en_btipc_hcipti_t *pti, uint32_t *p_length, uint32_t *msgPtr)
581 {
582     cy_stc_ipc_msg_buff_t *ipcMsgBuf;
583     uint8_t *bufAddr;
584     cy_en_btipc_hcipti_t mesgPti;
585 
586     if ((NULL == pti) || (NULL == msgPtr) || (NULL == p_length))
587     {
588         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
589     }
590 
591     /* Incase of long messages the PTI needs to be read from DATA0[bit 8-15] */
592     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_btipc_hcipti_t enum');
593     mesgPti = (cy_en_btipc_hcipti_t)((0xFFUL) & msgPtr[0]);
594     if (mesgPti == CY_BT_IPC_HCI_LONG)
595     {
596         ipcMsgBuf = (cy_stc_ipc_msg_buff_t*)((void*)msgPtr);
597         *pti = (cy_en_btipc_hcipti_t)ipcMsgBuf->actualPti;
598         bufAddr = ipcMsgBuf->bufAddr;
599         /* Mapping of BT address space to MCU address space */
600 #if defined(BT_IPC_SIM) || !defined (BTSS)
601         bufAddr = (uint8_t*)bufAddr;
602 #else
603         bufAddr = (uint8_t*)((uint32_t)(bufAddr) + ((uint32_t)BTSS_DATA_RAM_IPC - 0x28000000UL));
604 #endif
605 
606         if (Cy_bt_isOffsetNeeded(*pti))
607         {
608             bufAddr++;
609         }
610     }
611     else
612     {
613         *pti = mesgPti;
614         bufAddr = (uint8_t*)msgPtr;
615         /* Skip the PTI byte read from the DATA0 register */
616         bufAddr++;
617     }
618     *p_length = Cy_bt_getPLLegnth(*pti, bufAddr);
619     return CY_BT_IPC_DRV_SUCCESS;
620 }
621 CY_IPC_SECTION_END
622 
623 CY_IPC_SECTION_BEGIN
Cy_BTIPC_HCI_GetReadBufPtr(cy_stc_ipc_bt_context_t * btIpcContext,void ** ppData,size_t * pLength)624 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_GetReadBufPtr (cy_stc_ipc_bt_context_t *btIpcContext, void **ppData, size_t* pLength)
625 {
626     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
627     cy_stc_ipc_msg_buff_t *ipcMsgBuf;
628     cy_stc_ipc_msg_short_t *shortMesg;
629     cy_en_btipc_hcipti_t actualPti;
630     cy_en_btipc_hcipti_t mesgPti;
631     cy_en_btipcdrv_status_t status;
632     uint32_t *pMsg;
633     uint8_t *srcPtr;
634     uint8_t idx;
635     uint8_t done;
636     uint32_t interruptState;
637 
638     if ((NULL == contextPtr) || (NULL == ppData))
639     {
640         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
641     }
642 
643     status = Cy_BTIPC_HCI_FIFOGet(contextPtr, &pMsg, 0);
644 
645     if (((uint32_t)status) != 0UL)
646     {
647         return status;
648     }
649 
650     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_btipc_hcipti_t enum.');
651     mesgPti = (cy_en_btipc_hcipti_t)((0xFFUL) & pMsg[0]);
652 
653     if (mesgPti == CY_BT_IPC_HCI_LONG)
654     {
655         ipcMsgBuf = (cy_stc_ipc_msg_buff_t*)((void*)pMsg);
656         actualPti = (cy_en_btipc_hcipti_t)ipcMsgBuf->actualPti;
657         srcPtr = ipcMsgBuf->bufAddr;
658         /* Mapping of BT address space to MCU address space */
659 #if defined(BT_IPC_SIM) || !defined (BTSS)
660         srcPtr = (uint8_t*)(srcPtr);
661 #else
662         srcPtr = (uint8_t*)((uint32_t)(srcPtr) + ((uint32_t)BTSS_DATA_RAM_IPC - 0x28000000UL));
663 #endif
664 #ifdef CY_BTIPC_STATS
665         contextPtr->ipc_hci_peer_inbuf_count++;
666 #endif
667         if (Cy_bt_isOffsetNeeded(actualPti))
668         {
669             srcPtr++;
670         }
671         *pLength = Cy_bt_getPLLegnth(actualPti, srcPtr);
672 
673         interruptState = Cy_SysLib_EnterCriticalSection();
674 
675         done = 0;
676         for (idx = 0U; idx < ((uint8_t)MAX_TO_FREE_BUF_COUNT); idx++)
677         {
678             if (contextPtr->toFreeBuf[idx].bufPtr == NULL)
679             {
680                 contextPtr->toFreeBuf[idx].bufType = Cy_bt_get_buf_type(actualPti);
681                 contextPtr->toFreeBuf[idx].bufLen = (uint16_t)(*pLength);
682                 contextPtr->toFreeBuf[idx].bufPtr = ipcMsgBuf->bufAddr;
683                 done = 1;
684                 break;
685             }
686         }
687 
688         Cy_SysLib_ExitCriticalSection(interruptState);
689 
690         if (done == 0U)
691         {
692             return CY_BT_IPC_DRV_ERROR_BUF_FULL;
693         }
694 
695     }
696     else
697     {
698         shortMesg = (cy_stc_ipc_msg_short_t*)((void*)pMsg);
699         srcPtr = &(shortMesg->db0);
700         *pLength = Cy_bt_getPLLegnth(mesgPti, srcPtr);
701     }
702 
703     *ppData = srcPtr;
704     return CY_BT_IPC_DRV_SUCCESS;
705 }
706 CY_IPC_SECTION_END
707 
708 CY_IPC_SECTION_BEGIN
Cy_BTIPC_HCI_GetWriteBufPtr(cy_stc_ipc_bt_context_t * btIpcContext,cy_en_btipc_hcipti_t pti,void ** ppData,size_t length)709 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_GetWriteBufPtr(cy_stc_ipc_bt_context_t *btIpcContext, cy_en_btipc_hcipti_t pti, void **ppData, size_t length)
710 {
711     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
712     cy_en_btipcdrv_status_t status;
713     uint8_t *destBuf;
714     cy_en_btipc_buftype_t bufType;
715     uint8_t *bPtr;
716     uint32_t interruptState;
717 
718     if ((NULL == contextPtr) || (NULL == ppData))
719     {
720         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
721     }
722 
723     interruptState = Cy_SysLib_EnterCriticalSection();
724     /* If the HCI channel is busy then do not proceed further, return CH BUSY error */
725     if (Cy_IPC_Drv_IsLockAcquired (Cy_IPC_Drv_GetIpcBaseAddress(contextPtr->ulChannelHCI)))
726     {
727         Cy_SysLib_ExitCriticalSection(interruptState);
728         return CY_BT_IPC_DRV_ERROR_CH_BUSY;
729     }
730     Cy_SysLib_ExitCriticalSection(interruptState);
731 
732     *ppData = NULL;
733 
734     /* Get the buffer type based on the payload type indicator */
735     bufType = Cy_bt_get_buf_type(pti);
736     /* Pick a free buffer from the pool of buffers */
737     status = Cy_bt_GetBuffer (contextPtr, (void **)&destBuf, bufType, length);
738     if (((uint32_t)status) != 0UL)
739     {
740         return status;
741     }
742 
743     bPtr = destBuf;
744     /* Skip pad byte if needed */
745     if (Cy_bt_isOffsetNeeded(pti))
746     {
747         bPtr++;
748     }
749     *ppData = bPtr;
750     return CY_BT_IPC_DRV_SUCCESS;
751 }
752 CY_IPC_SECTION_END
753 
754 CY_IPC_SECTION_BEGIN
Cy_BTIPC_HCI_Write(cy_stc_ipc_bt_context_t * btIpcContext,cy_en_btipc_hcipti_t pti,void * data,size_t length)755 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_Write(cy_stc_ipc_bt_context_t *btIpcContext, cy_en_btipc_hcipti_t pti, void *data, size_t length)
756 {
757     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
758     cy_stc_ipc_msg_buff_t ipcPacket;
759     cy_stc_ipc_msg_short_t ipcShort;
760     uint32_t *msgPtr;
761     uint8_t *bPtr, *bDptr;
762     uint8_t i;
763 
764     if ((NULL == contextPtr) || (NULL == data))
765     {
766         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
767     }
768 
769     /* Check if it is long message or ACL or ISO packet.
770      * As per BT FW team's request, this deviation is taken to use buffers for
771      * ACL and ISO short packets. Ref JIRA DRIVERS-6513 for more details */
772     if ((length > ((uint8_t)MAX_SHORT_MESG_LENGTH)) || (pti == CY_BT_IPC_HCI_ACL)
773         || (pti == CY_BT_IPC_HCI_ISO))
774     {
775         /* Add pad byte if needed */
776         bPtr = (uint8_t*)data;
777         if (Cy_bt_isOffsetNeeded(pti))
778         {
779             bPtr--;
780         }
781 
782         ipcPacket.pti = (uint8_t) CY_BT_IPC_HCI_LONG;
783         ipcPacket.actualPti = (uint8_t)pti;
784         ipcPacket.bufSize = 0;
785         // Remap the address to BT memory map
786 #if defined(BT_IPC_SIM) || !defined (BTSS)
787         ipcPacket.bufAddr = bPtr;
788 #else
789         ipcPacket.bufAddr = (uint8_t*)((uint32_t)bPtr - ((uint32_t)BTSS_DATA_RAM_IPC - 0x28000000UL));
790 #endif
791         /* end of buffer preparation */
792         msgPtr = (uint32_t*)((void*)&ipcPacket);
793     }
794     else /* Short Message */
795     {
796         msgPtr = (uint32_t*)((void*)&ipcShort);
797         msgPtr[0] = 0;
798         msgPtr[1] = 0;
799         ipcShort.pti = (uint8_t)pti;
800         bPtr = &(ipcShort.db0);
801         bDptr = (uint8_t*)data;
802 
803         for (i = 0; i < length; i++)
804         {
805             CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 18.1','Checked manually, these pointer will not exceed register range.');
806             *bPtr++ = *bDptr++;
807         }
808     }
809 
810     if (Cy_IPC_Drv_SendMsgDWord(Cy_IPC_Drv_GetIpcBaseAddress(contextPtr->ulChannelHCI),
811                                 contextPtr->intPeerMask, msgPtr) == CY_IPC_DRV_SUCCESS)
812     {
813 #ifdef CY_BTIPC_STATS
814         contextPtr->ipc_hci_cmd_count++;
815 #endif
816         return CY_BT_IPC_DRV_SUCCESS;
817     }
818     else
819     {
820         (void)ipcShort.pti; /* Suppress a compiler warning about unused variables */
821         return CY_BT_IPC_DRV_ERROR_LOCK_ACQUIRE;
822     }
823 }
824 CY_IPC_SECTION_END
825 
Cy_BTIPC_HPC_GetWriteBufPtr(cy_stc_ipc_bt_context_t * btIpcContext,void ** ppData,size_t length)826 cy_en_btipcdrv_status_t Cy_BTIPC_HPC_GetWriteBufPtr(cy_stc_ipc_bt_context_t *btIpcContext, void **ppData, size_t length)
827 {
828     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
829     cy_en_btipcdrv_status_t status;
830     uint8_t *destBuf;
831     (void)length;
832     uint32_t interruptState;
833 
834     if ((NULL == contextPtr) || (NULL == ppData))
835     {
836         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
837     }
838 
839     interruptState = Cy_SysLib_EnterCriticalSection();
840     /* If the HPC channel is busy then do not proceed further, return CH BUSY error */
841     if (Cy_IPC_Drv_IsLockAcquired (Cy_IPC_Drv_GetIpcBaseAddress(contextPtr->ulChannelHPC)))
842     {
843         Cy_SysLib_ExitCriticalSection(interruptState);
844         return CY_BT_IPC_DRV_ERROR_CH_BUSY;
845     }
846     Cy_SysLib_ExitCriticalSection(interruptState);
847 
848     *ppData = NULL;
849     /* Pick a free control buffer from the pool of buffers */
850     status = Cy_bt_GetBuffer (contextPtr, (void **)&destBuf, CY_BT_IPC_CTRL_BUF, length);
851     if (((uint32_t)status) == 0UL)
852     {
853         *ppData = destBuf;
854     }
855     (void) length; /* Suppress a compiler warning about unused variables */
856     return status;
857 }
858 
859 
Cy_BTIPC_HPC_Write(cy_stc_ipc_bt_context_t * btIpcContext,void * data,size_t length)860 cy_en_btipcdrv_status_t Cy_BTIPC_HPC_Write(cy_stc_ipc_bt_context_t *btIpcContext, void *data, size_t length)
861 {
862     uint32_t *dataPtr = (uint32_t*) data;
863     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
864 
865     (void) length;
866 
867     if ((NULL == contextPtr) || (NULL == data))
868     {
869         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
870     }
871 
872     if (!((bool)(Cy_IPC_Drv_SendMsgDWord(Cy_IPC_Drv_GetIpcBaseAddress(contextPtr->ulChannelHPC),
873                                 contextPtr->intPeerMask, (uint32_t*) dataPtr))))
874     {
875 #ifdef CY_BTIPC_STATS
876         contextPtr->ipc_hpc_cmd_count++;
877 #endif
878         return CY_BT_IPC_DRV_SUCCESS;
879     }
880     else
881     {
882         return CY_BT_IPC_DRV_ERROR_LOCK_ACQUIRE;
883     }
884 }
885 
886 
Cy_BTIPC_HCI_RegisterCb(cy_stc_ipc_bt_context_t * btIpcContext,cy_ipc_bt_callback_ptr_t hciNotifyCallbackPtr)887 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_RegisterCb(cy_stc_ipc_bt_context_t *btIpcContext, cy_ipc_bt_callback_ptr_t hciNotifyCallbackPtr)
888 {
889     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
890 
891     if ((NULL == contextPtr) || (NULL == hciNotifyCallbackPtr))
892     {
893         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
894     }
895 
896     contextPtr->dlNotifyCallbackPtr = hciNotifyCallbackPtr;
897     return CY_BT_IPC_DRV_SUCCESS;
898 }
899 
900 
Cy_BTIPC_HCI_UnregisterCb(cy_stc_ipc_bt_context_t * btIpcContext)901 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_UnregisterCb(cy_stc_ipc_bt_context_t *btIpcContext)
902 {
903     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
904 
905     if (NULL == contextPtr)
906     {
907         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
908     }
909 
910     contextPtr->dlNotifyCallbackPtr = NULL;
911 
912     return CY_BT_IPC_DRV_SUCCESS;
913 }
914 
915 
Cy_BTIPC_HPC_RegisterCb(cy_stc_ipc_bt_context_t * btIpcContext,cy_stc_ipc_hcp_cb_t * pHpcNotifyCallbackParam)916 cy_en_btipcdrv_status_t Cy_BTIPC_HPC_RegisterCb(cy_stc_ipc_bt_context_t *btIpcContext, cy_stc_ipc_hcp_cb_t *pHpcNotifyCallbackParam)
917 {
918     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
919     uint8_t idx;
920     uint8_t placed;
921 
922     if ((NULL == contextPtr) || (NULL == pHpcNotifyCallbackParam))
923     {
924         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
925     }
926 
927     placed = 0U;
928     for (idx = 0U; idx < ((uint8_t)MAX_BT_IPC_HPC_CB); idx++)
929     {
930         if ((contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr == NULL) &&
931             (contextPtr->hpcNotifyCallbackParam[idx].msgType == CY_BT_IPC_HPC_RESERVED))
932         {
933             contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr = pHpcNotifyCallbackParam->hpcNotifyCallbackPtr;
934             contextPtr->hpcNotifyCallbackParam[idx].msgType = pHpcNotifyCallbackParam->msgType;
935             placed = 1;
936             break;
937         }
938     }
939 
940     if (placed != 0U)
941     {
942         return CY_BT_IPC_DRV_SUCCESS;
943     }
944     else
945     {
946         return CY_BT_IPC_DRV_ERROR;
947     }
948 }
949 
950 
Cy_BTIPC_HPC_UnregisterCb(cy_stc_ipc_bt_context_t * btIpcContext,cy_stc_ipc_hcp_cb_t * pHpcNotifyCallbackParam)951 cy_en_btipcdrv_status_t Cy_BTIPC_HPC_UnregisterCb(cy_stc_ipc_bt_context_t *btIpcContext, cy_stc_ipc_hcp_cb_t *pHpcNotifyCallbackParam)
952 {
953     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
954     uint8_t idx;
955     uint8_t found;
956 
957     if ((NULL == contextPtr) || (NULL == pHpcNotifyCallbackParam))
958     {
959         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
960     }
961 
962     found = 0;
963     for (idx = 0U; idx < ((uint8_t)MAX_BT_IPC_HPC_CB); idx++)
964     {
965         if ((contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr == pHpcNotifyCallbackParam->hpcNotifyCallbackPtr) &&
966             (contextPtr->hpcNotifyCallbackParam[idx].msgType == pHpcNotifyCallbackParam->msgType))
967         {
968             contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr = NULL;
969             contextPtr->hpcNotifyCallbackParam[idx].msgType = CY_BT_IPC_HPC_RESERVED;
970             found = 1;
971             break;
972         }
973     }
974 
975     if (found != 0UL)
976     {
977         return CY_BT_IPC_DRV_SUCCESS;
978     }
979     else
980     {
981         return CY_BT_IPC_DRV_ERROR;
982     }
983 }
984 
985 
Cy_BTIPC_Buffer_RegisterCb(cy_stc_ipc_bt_context_t * btIpcContext,cy_ipc_bt_bufcallback_ptr_t bufCallbackPtr)986 cy_en_btipcdrv_status_t Cy_BTIPC_Buffer_RegisterCb(cy_stc_ipc_bt_context_t *btIpcContext, cy_ipc_bt_bufcallback_ptr_t bufCallbackPtr)
987 {
988     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
989     uint32_t interruptState;
990 
991     if ((NULL == contextPtr) || (NULL == bufCallbackPtr))
992     {
993         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
994     }
995 
996     interruptState = Cy_SysLib_EnterCriticalSection();
997     contextPtr->bufCallbackPtr = bufCallbackPtr;
998     Cy_SysLib_ExitCriticalSection(interruptState);
999 
1000     return CY_BT_IPC_DRV_SUCCESS;
1001 }
1002 
1003 
1004 CY_IPC_SECTION_BEGIN
Cy_bt_GetBuffer(cy_stc_ipc_bt_context_t * btIpcContext,void ** ppBuf,cy_en_btipc_buftype_t bufType,size_t length)1005 static cy_en_btipcdrv_status_t Cy_bt_GetBuffer (cy_stc_ipc_bt_context_t *btIpcContext, void **ppBuf, cy_en_btipc_buftype_t bufType, size_t length)
1006 {
1007     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1008     uint8_t idx;
1009     uint8_t found;
1010     uint8_t size_error;
1011     uint32_t interruptState;
1012 
1013     if ((NULL == contextPtr) || (NULL == ppBuf))
1014     {
1015         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
1016     }
1017 
1018     interruptState = Cy_SysLib_EnterCriticalSection();
1019 
1020     found = 0;
1021     size_error = 0;
1022 
1023     BTIPC_LOG_L2("Buf req: Type 0x%x, Size %d\n",bufType,length);
1024     BTIPC_LOG_L2("Buf Pool content\n");
1025 
1026 #ifdef CY_BTIPC_STATS
1027     if (bufType == CY_BT_IPC_HCI_CMD_BUF)
1028     {
1029         contextPtr->ipc_hci_cmd_self_outbuf_count++;
1030     }
1031 #endif
1032     for (idx = 0U; idx < ((uint8_t)MAX_BUF_COUNT); idx++)
1033     {
1034         BTIPC_LOG_L2("idx %d, bufType 0x%x, bufLen %d, bufPtr %p\n",idx, contextPtr->buffPool[idx].bufType,contextPtr->buffPool[idx].bufLen, contextPtr->buffPool[idx].bufPtr);
1035 
1036         if ((contextPtr->buffPool[idx].bufType == bufType) && (contextPtr->buffPool[idx].bufPtr != NULL))
1037         {
1038             if (length <= contextPtr->buffPool[idx].bufLen)
1039             {
1040                 *ppBuf = (void*)contextPtr->buffPool[idx].bufPtr;
1041                 // Mapping of address
1042 #if defined(BT_IPC_SIM) || !defined (BTSS)
1043                 *ppBuf = (void*)(*ppBuf);
1044 #else
1045                 *ppBuf = (void*)((uint32_t)(*ppBuf) + ((uint32_t)BTSS_DATA_RAM_IPC - 0x28000000UL));
1046 #endif
1047                 contextPtr->buffPool[idx].bufPtr = NULL;
1048                 contextPtr->buffPool[idx].bufType = CY_BT_IPC_HCI_INVALID_BUF;
1049                 found = 1;
1050 #ifdef CY_BTIPC_STATS
1051                 if (bufType == CY_BT_IPC_HCI_CMD_BUF)
1052                 {
1053                    contextPtr->ipc_hci_cmd_self_outbuf_success++;
1054                 }
1055 #endif
1056                 break;
1057             }
1058             else
1059             {
1060                 size_error = 1;
1061             }
1062         }
1063     }
1064 
1065     Cy_SysLib_ExitCriticalSection(interruptState);
1066 
1067     if (found != 0UL)
1068     {
1069         return CY_BT_IPC_DRV_SUCCESS;
1070     }
1071     else if (size_error == 1UL)
1072     {
1073         return CY_BT_IPC_DRV_ERROR_BUF_SIZE;
1074     }
1075     else
1076     {
1077         *ppBuf = NULL;
1078         return CY_BT_IPC_DRV_ERROR_BUF_GET;
1079     }
1080 
1081 }
1082 CY_IPC_SECTION_END
1083 
Cy_bt_PutBuffer(cy_stc_ipc_bt_context_t * btIpcContext,cy_stc_ipc_bt_buf_t * bufDecriptor)1084 static cy_en_btipcdrv_status_t Cy_bt_PutBuffer(cy_stc_ipc_bt_context_t *btIpcContext, cy_stc_ipc_bt_buf_t *bufDecriptor)
1085 {
1086     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1087     uint8_t idx;
1088     uint32_t interruptState;
1089     cy_en_btipcdrv_status_t status = CY_BT_IPC_DRV_ERROR_BUF_FULL;
1090 
1091     BTIPC_LOG_L2("Put buffer+\n");
1092 
1093     if ((NULL == contextPtr) || (NULL == bufDecriptor) || (bufDecriptor->bufPtr == NULL))
1094     {
1095         BTIPC_LOG_L2("Put buffer-\n");
1096         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
1097     }
1098 
1099     interruptState = Cy_SysLib_EnterCriticalSection();
1100 
1101     for (idx = 0U; idx < ((uint8_t)MAX_BUF_COUNT); idx++)
1102     {
1103         if ((contextPtr->buffPool[idx].bufType == bufDecriptor->bufType) &&
1104             (contextPtr->buffPool[idx].bufPtr == bufDecriptor->bufPtr))
1105         {
1106             BTIPC_LOG_L2("Buffer already present in the pool at %d\n",idx);
1107             status = CY_BT_IPC_DRV_ERROR_BUF_PRESENT;
1108             break;
1109         }
1110         else if (contextPtr->buffPool[idx].bufType == CY_BT_IPC_HCI_INVALID_BUF)
1111         {
1112             contextPtr->buffPool[idx] = *bufDecriptor;
1113             status = CY_BT_IPC_DRV_SUCCESS;
1114             BTIPC_LOG_L2("Added buffer at index %d\n",idx);
1115             break;
1116         }
1117         else
1118         {
1119             /* This is just to keep coverity happy */
1120         }
1121     }
1122 
1123     Cy_SysLib_ExitCriticalSection(interruptState);
1124 
1125     /* Call handler for buffer */
1126     if ((status == CY_BT_IPC_DRV_SUCCESS) && (NULL != contextPtr->bufCallbackPtr))
1127     {
1128         contextPtr->bufCallbackPtr(bufDecriptor->bufType);
1129     }
1130 
1131     BTIPC_LOG_L2("Put buffer-\n");
1132     return status;
1133 }
1134 
1135 
1136 /* Local function implementation */
Cy_bt_handle_hpclong_msg(cy_stc_ipc_bt_context_t * btIpcContext,uint32_t * msgPtr)1137 cy_en_btipcdrv_status_t Cy_bt_handle_hpclong_msg(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t * msgPtr)
1138 {
1139     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1140     cy_stc_ipc_msg_init_t *ptr;
1141     cy_stc_ipc_bt_buf_t bufDescriptor;
1142     cy_en_btipcdrv_status_t status;
1143     uint8_t i;
1144     uint8_t bufCount;
1145     uint8_t *bPtr;
1146     uint8_t *bDptr;
1147     cy_en_btipc_hpcmsgid_t longMsgType;
1148     uint8_t idx;
1149 
1150     if ((NULL == contextPtr) || (NULL == msgPtr))
1151     {
1152         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
1153     }
1154 
1155     bPtr = (uint8_t*)msgPtr;
1156     longMsgType = (cy_en_btipc_hpcmsgid_t)(*(bPtr+1));
1157 
1158     BTIPC_LOG_L1("longMsgType %d\n", longMsgType);
1159 
1160     status = CY_BT_IPC_DRV_SUCCESS;
1161 #ifdef CY_BTIPC_STATS
1162     contextPtr->ipc_hpc_peer_inbuf_count++;
1163 #endif
1164     switch (longMsgType)
1165     {
1166         case CY_BT_IPC_HPC_INIT:
1167             ptr = (cy_stc_ipc_msg_init_t*)(* (msgPtr+1));
1168             if (NULL == ptr)
1169             {
1170                 status = CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
1171                 break;
1172             }
1173             /* mapping of memory */
1174 #if defined(BT_IPC_SIM) || !defined (BTSS)
1175             ptr = (cy_stc_ipc_msg_init_t*)(ptr);
1176 #else
1177             ptr = (cy_stc_ipc_msg_init_t*)((uint32)ptr + ((uint32_t)BTSS_DATA_RAM_IPC - 0x28000000UL));
1178 #endif
1179             /* The payloadLen includes bootype (1 byte) and error code (4 bytes).
1180             Hence, subtract INIT_IPC_BUFF_DESC_OFFSET (5 Bytes) from it */
1181             bufCount = (ptr->payLoadLen - (uint8_t)INIT_IPC_BUFF_DESC_OFFSET)/((uint8_t)BUFFER_DESCRIPTION_LEN);
1182 
1183             /* Add code to extract boot type from init structure */
1184             contextPtr->bootType = ptr->bootType;
1185 #ifndef BT_OLD_INIT
1186             bPtr = (uint8_t*)(&ptr->bootType);
1187             CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 18.1','Checked manually, the byte pointer will not corrupt memory.');
1188             bPtr++;
1189             bDptr = (uint8_t*)(&contextPtr->certError);
1190             CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 18.1','Checked manually, the byte pointer will not corrupt memory.');
1191             *bDptr++ = *bPtr++;
1192             *bDptr++ = *bPtr++;
1193             *bDptr++ = *bPtr++;
1194             *bDptr++ = *bPtr++;
1195 #endif
1196 
1197 #ifdef BT_OLD_INIT
1198             BTIPC_LOG_L0("handling Init mesg from %p, boottype %d, payload len 0x%x, bufCount %d\n",
1199                 ptr, ptr->bootType, ptr->payLoadLen, bufCount);
1200 #else
1201             BTIPC_LOG_L0("handling Init mesg from %p, boottype %d, payload len 0x%x, certError 0x%lx bufCount %d\n",
1202                 ptr, ptr->bootType, ptr->payLoadLen, contextPtr->certError , bufCount);
1203 #endif
1204 
1205 
1206             if ((ptr->bootType == (uint8_t)CY_BT_IPC_BOOT_CONFIG_WAIT) ||
1207                 (ptr->bootType == (uint8_t)CY_BT_IPC_BOOT_FULLY_UP))
1208             {
1209 
1210                 /* Clear all buffers in the pool */
1211                 for (idx = 0U; idx < ((uint8_t)MAX_BUF_COUNT); idx++)
1212                 {
1213                     contextPtr->buffPool[idx].bufPtr = NULL;
1214                     contextPtr->buffPool[idx].bufType = CY_BT_IPC_HCI_INVALID_BUF;
1215                 }
1216 
1217                 //msgId
1218                 //bootType
1219                 /* point to the start of buffer pool */
1220                 bPtr = (uint8_t*)ptr + sizeof(cy_stc_ipc_msg_init_t);
1221 
1222                 BTIPC_LOG_L0("\nExtract buffers from %p\n",bPtr);
1223 
1224                 for (i = 0; i < bufCount; i++)
1225                 {
1226                     bufDescriptor.bufType = (cy_en_btipc_buftype_t) (*bPtr++);
1227 
1228                     bDptr = (uint8_t*)(&bufDescriptor.bufLen);
1229                     *bDptr++ = *bPtr++;
1230                     *bDptr++ = *bPtr++;
1231 
1232                     bDptr = (uint8_t*)(&bufDescriptor.bufPtr);
1233                     *bDptr++ = *bPtr++;
1234                     *bDptr++ = *bPtr++;
1235                     *bDptr++ = *bPtr++;
1236                     *bDptr++ = *bPtr++;
1237 
1238                     BTIPC_LOG_L0("bufType %x, bufLen %d, bufPtr %p\n",bufDescriptor.bufType, bufDescriptor.bufLen, bufDescriptor.bufPtr);
1239 
1240                     status = Cy_bt_PutBuffer(contextPtr, &bufDescriptor);
1241                     if (((uint32_t)status) != 0UL)
1242                     {
1243                         /* Need to check if some cleaning needed for error condition */
1244                         BTIPC_LOG_L0("Error in putting the buffer to pool\n");
1245                     }
1246                     else
1247                     {
1248                         BTIPC_LOG_L0("Added buf %d\n",i);
1249                     }
1250                 }
1251                 BTIPC_LOG_L0("Bufs add done\n\n");
1252             }
1253             else
1254             {
1255                 BTIPC_LOG_L0("\nInvalid Boot type\n");
1256             }
1257             break;
1258 
1259         case CY_BT_IPC_HPC_HADM:
1260             BTIPC_LOG_L1("HADM Data\n");
1261             /* Add code to handle HADM data */
1262             break;
1263 
1264         default:
1265             /* Invalid long message type */
1266             status = CY_BT_IPC_DRV_ERROR_PARAM;
1267             break;
1268     }
1269     return status;
1270 }
1271 
1272 
Cy_bt_handle_buf_add(cy_stc_ipc_bt_context_t * btIpcContext,uint32_t * msgPtr)1273 cy_en_btipcdrv_status_t Cy_bt_handle_buf_add(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t * msgPtr)
1274 {
1275     cy_stc_ipc_bt_buf_t bufDescriptor;
1276     cy_stc_ipc_msg_alloc_t allocBuf;
1277     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1278     cy_en_btipcdrv_status_t status;
1279 
1280     BTIPC_LOG_L2("Adding buf\n");
1281 
1282     if ((NULL == contextPtr) || (NULL == msgPtr))
1283     {
1284         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
1285     }
1286 
1287     allocBuf = *(cy_stc_ipc_msg_alloc_t*)((void*)msgPtr);
1288     bufDescriptor.bufType = (cy_en_btipc_buftype_t) allocBuf.bufType;
1289     bufDescriptor.bufLen = allocBuf.bufSize;
1290     bufDescriptor.bufPtr = (uint8_t*) allocBuf.bufAddr;
1291 
1292     BTIPC_LOG_L2("bufType 0x%x, bufLen 0x%x, bufPtr %p\n",bufDescriptor.bufType, bufDescriptor.bufLen, bufDescriptor.bufPtr);
1293 #ifdef CY_BTIPC_STATS
1294     if (bufDescriptor.bufType == CY_BT_IPC_HCI_CMD_BUF)
1295     {
1296         contextPtr->ipc_hci_cmd_self_inbuf_count++;
1297     }
1298 #endif
1299     status = Cy_bt_PutBuffer(contextPtr, &bufDescriptor);
1300     if (((uint32_t)status) != 0UL)
1301     {
1302         /* Need to check if some cleaning needed for error condition */
1303         BTIPC_LOG_L0("Error: 0x%x in putting the buffer to pool\n",status);
1304     }
1305     return status;
1306 }
1307 
1308 
1309 CY_IPC_SECTION_BEGIN
Cy_bt_get_buf_type(cy_en_btipc_hcipti_t pti)1310 static cy_en_btipc_buftype_t Cy_bt_get_buf_type(cy_en_btipc_hcipti_t pti)
1311 {
1312     cy_en_btipc_buftype_t bufType;
1313 
1314     /* To be done: Currently returning Control buffer for all PTIs. Need to change it once we have clarity on it */
1315     switch (pti)
1316     {
1317         case CY_BT_IPC_HCI_CMD:
1318             bufType = CY_BT_IPC_HCI_CMD_BUF;
1319             break;
1320         case CY_BT_IPC_HCI_ACL:
1321         /* CY_BT_IPC_HCI_BREDR_BUF if classic BT, or CY_BT_IPC_HCI_BLE_BUF for BLE. 20829 only supports BLE*/
1322             bufType = CY_BT_IPC_HCI_BLE_BUF;
1323             break;
1324         case CY_BT_IPC_HCI_ISO:
1325             bufType = CY_BT_IPC_HCI_ISOC_BUF;
1326             break;
1327         case CY_BT_IPC_HCI_EVT:
1328         /* This will not be sent from MCU. But simulation code needs it */
1329             bufType = CY_BT_IPC_HCI_CMD_BUF;
1330             break;
1331         case CY_BT_IPC_HCI_DIAG:
1332             bufType = CY_BT_IPC_HCI_CMD_BUF;
1333         break;
1334         case CY_BT_IPC_HCI_SCO:
1335         /* SCO is not supported in CYW20829 */
1336         /* Do not have info. Needs to be revisited later */
1337         case CY_BT_IPC_HCI_MPAF:
1338         /* Not Supported */
1339         case CY_BT_IPC_HCI_SLIPH5:
1340         /* Not Supported */
1341         default:
1342             bufType = CY_BT_IPC_HCI_INVALID_BUF;
1343             break;
1344     }
1345     return bufType;
1346 }
1347 CY_IPC_SECTION_END
1348 
1349 CY_IPC_SECTION_BEGIN
Cy_bt_getPLLegnth(cy_en_btipc_hcipti_t pti,uint8_t * bufAddr)1350 static uint32_t Cy_bt_getPLLegnth(cy_en_btipc_hcipti_t pti, uint8_t* bufAddr)
1351 {
1352     uint32_t length;
1353     switch (pti)
1354     {
1355         case CY_BT_IPC_HCI_CMD:
1356             length = (uint32_t)(((BTHCI_CMD_HDR_t*)((void*)bufAddr))->params_len);
1357             length += sizeof(BTHCI_CMD_HDR_t);
1358             break;
1359         case CY_BT_IPC_HCI_ACL:
1360             length = (uint32_t)(((BTHCI_ACL_HDR_t*)((void*)bufAddr))->data_len);
1361             length += sizeof(BTHCI_ACL_HDR_t);
1362             break;
1363         case CY_BT_IPC_HCI_SCO:
1364             length = (uint32_t)(((BTHCI_SCO_HDR_t*)((void*)bufAddr))->data_len);
1365             length += sizeof(BTHCI_SCO_HDR_t);
1366             break;
1367         case CY_BT_IPC_HCI_EVT:
1368             length = (uint32_t)(((BTHCI_EVENT_HDR_t*)((void*)bufAddr))->params_len);
1369             length += sizeof(BTHCI_EVENT_HDR_t);
1370             break;
1371         case CY_BT_IPC_HCI_ISO:
1372             length = (uint32_t)(((BTHCI_ISO_HDR_t*)((void*)bufAddr))->data_len);
1373             length += sizeof(BTHCI_ISO_HDR_t);
1374             break;
1375         case CY_BT_IPC_HCI_DIAG:
1376             length = *bufAddr; /* The first byte of the payload holds the payload length */
1377             break;
1378         /* To be done: Header length for the remaining PTI needs to be updated */
1379         case CY_BT_IPC_HCI_MPAF:
1380             length = 0;
1381             break;
1382         case CY_BT_IPC_HCI_SLIPH5:
1383             length = 0;
1384             break;
1385         default:
1386             length = 0;
1387             break;
1388     }
1389     return length;
1390 }
1391 CY_IPC_SECTION_END
1392 
1393 CY_IPC_SECTION_BEGIN
Cy_bt_isOffsetNeeded(cy_en_btipc_hcipti_t pti)1394 static bool Cy_bt_isOffsetNeeded(cy_en_btipc_hcipti_t pti)
1395 {
1396     bool ret;
1397 
1398     switch (pti)
1399     {
1400         case CY_BT_IPC_HCI_CMD:
1401         case CY_BT_IPC_HCI_SCO:
1402             ret = true;
1403             break;
1404         case CY_BT_IPC_HCI_ACL:
1405         case CY_BT_IPC_HCI_EVT:
1406         case CY_BT_IPC_HCI_ISO:
1407         case CY_BT_IPC_HCI_DIAG:
1408         case CY_BT_IPC_HCI_MPAF:
1409         case CY_BT_IPC_HCI_SLIPH5:
1410         default:
1411             ret = false;
1412             break;
1413     }
1414 
1415     return ret;
1416 }
1417 CY_IPC_SECTION_END
1418 
Cy_BTIPC_HCI_FIFOPut(cy_stc_ipc_bt_context_t * btIpcContext,uint32_t * pMsg)1419 static cy_en_btipcdrv_status_t Cy_BTIPC_HCI_FIFOPut(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t *pMsg)
1420 {
1421     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1422     uint32_t interruptState;
1423 
1424     /* Check if buffer is full */
1425     if (contextPtr->IpcFifo.bufLen == ((uint8_t)MAX_IPC_FIFO_SIZE))
1426     {
1427         return CY_BT_IPC_DRV_ERROR_BUF_FULL;
1428     }
1429 
1430     interruptState = Cy_SysLib_EnterCriticalSection();
1431 
1432     contextPtr->IpcFifo.fifo[contextPtr->IpcFifo.wrIdx].msg[0] = pMsg[0];
1433     contextPtr->IpcFifo.fifo[contextPtr->IpcFifo.wrIdx].msg[1] = pMsg[1];
1434 
1435     contextPtr->IpcFifo.bufLen++;
1436     contextPtr->IpcFifo.wrIdx++;
1437 
1438     /* If at last index in buffer, set writeIndex back to 0 */
1439     if (contextPtr->IpcFifo.wrIdx == ((uint8_t)MAX_IPC_FIFO_SIZE))
1440     {
1441         contextPtr->IpcFifo.wrIdx = 0;
1442     }
1443 
1444     Cy_SysLib_ExitCriticalSection(interruptState);
1445     return CY_BT_IPC_DRV_SUCCESS;
1446 }
1447 
1448 CY_IPC_SECTION_BEGIN
Cy_BTIPC_HCI_FIFOGet(cy_stc_ipc_bt_context_t * btIpcContext,uint32_t ** ppMsg,uint8_t delete)1449 cy_en_btipcdrv_status_t Cy_BTIPC_HCI_FIFOGet(cy_stc_ipc_bt_context_t *btIpcContext, uint32_t **ppMsg, uint8_t delete)
1450 {
1451     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1452     uint32_t interruptState;
1453 
1454     /* Check if buffer is empty */
1455     if (contextPtr->IpcFifo.bufLen == 0U)
1456     {
1457         return CY_BT_IPC_DRV_ERROR_BUF_EMPTY;
1458     }
1459 
1460     interruptState = Cy_SysLib_EnterCriticalSection();
1461     *ppMsg = contextPtr->IpcFifo.fifo[contextPtr->IpcFifo.rdIdx].msg;
1462 
1463     if (delete != 0U)
1464     {
1465         contextPtr->IpcFifo.bufLen--;
1466         contextPtr->IpcFifo.rdIdx++;
1467 
1468         /* If at last index in buffer, set readIndex back to 0 */
1469         if (contextPtr->IpcFifo.rdIdx == ((uint8_t)MAX_IPC_FIFO_SIZE))
1470         {
1471             contextPtr->IpcFifo.rdIdx = 0;
1472         }
1473     }
1474     Cy_SysLib_ExitCriticalSection(interruptState);
1475 
1476     if ((delete != 0UL) && (((uint8_t)MAX_IPC_FIFO_SIZE - 1U) == contextPtr->IpcFifo.bufLen))
1477     {
1478         /* Release the channel as FIFO gets a free location */
1479         (void)Cy_BTIPC_HCI_RelChannel(contextPtr); /* Suppress a compiler warning about unused return value */
1480 #ifdef CY_BTIPC_STATS
1481         contextPtr->ipc_hci_peer_release_count++;
1482 #endif
1483         BTIPC_LOG_L0("Releasing the channel\n");
1484     }
1485     return CY_BT_IPC_DRV_SUCCESS;
1486 }
1487 CY_IPC_SECTION_END
1488 
1489 CY_IPC_SECTION_BEGIN
Cy_BTIPC_HCI_FIFOCount(cy_stc_ipc_bt_context_t * btIpcContext)1490 uint16_t Cy_BTIPC_HCI_FIFOCount(cy_stc_ipc_bt_context_t *btIpcContext)
1491 {
1492     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1493     uint32_t interruptState;
1494     uint16_t count;
1495 
1496     interruptState = Cy_SysLib_EnterCriticalSection();
1497     count = contextPtr->IpcFifo.bufLen;
1498     Cy_SysLib_ExitCriticalSection(interruptState);
1499     return count;
1500 }
1501 CY_IPC_SECTION_END
1502 
Cy_BTIPC_RetrieveContext(cy_stc_ipc_bt_context_t * btIpcContext,cy_stc_ipc_bt_save_ctxt_t * pContextRet)1503 cy_en_btipcdrv_status_t Cy_BTIPC_RetrieveContext(cy_stc_ipc_bt_context_t *btIpcContext, cy_stc_ipc_bt_save_ctxt_t *pContextRet)
1504 {
1505     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1506     uint32_t i;
1507 
1508     if ((NULL == contextPtr) || (NULL == pContextRet))
1509     {
1510         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
1511     }
1512 
1513     for (i = 0U; i < ((uint8_t)MAX_BUF_COUNT); i++)
1514     {
1515         pContextRet->buffPool[i].bufType = (uint16_t) contextPtr->buffPool[i].bufType;
1516         pContextRet->buffPool[i].bufLen = contextPtr->buffPool[i].bufLen;
1517         pContextRet->buffPool[i].bufPtr = contextPtr->buffPool[i].bufPtr;
1518     }
1519     return CY_BT_IPC_DRV_SUCCESS;
1520 }
1521 
Cy_BTIPC_RestoreContext(cy_stc_ipc_bt_context_t * btIpcContext,cy_stc_ipc_bt_save_ctxt_t * pContextRet)1522 cy_en_btipcdrv_status_t Cy_BTIPC_RestoreContext(cy_stc_ipc_bt_context_t *btIpcContext, cy_stc_ipc_bt_save_ctxt_t *pContextRet)
1523 {
1524     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1525     uint32_t i;
1526     if ((NULL == contextPtr) || (NULL == pContextRet))
1527     {
1528         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
1529     }
1530 
1531     for (i = 0U; i < ((uint8_t)MAX_BUF_COUNT); i++)
1532     {
1533         contextPtr->buffPool[i].bufType = (cy_en_btipc_buftype_t) pContextRet->buffPool[i].bufType;
1534         contextPtr->buffPool[i].bufLen = pContextRet->buffPool[i].bufLen;
1535         contextPtr->buffPool[i].bufPtr = pContextRet->buffPool[i].bufPtr;
1536     }
1537     return CY_BT_IPC_DRV_SUCCESS;
1538 }
1539 
1540 #ifdef BTIPC_STATUS
Cy_bt_PrintStatus(cy_stc_ipc_bt_context_t * btIpcContext)1541 cy_en_btipcdrv_status_t Cy_bt_PrintStatus (cy_stc_ipc_bt_context_t *btIpcContext)
1542 {
1543     cy_stc_ipc_bt_context_t *contextPtr = btIpcContext;
1544     uint8_t idx;
1545     uint32_t interruptState;
1546 
1547     if (NULL == contextPtr)
1548     {
1549         return CY_BT_IPC_DRV_ERROR_BAD_HANDLE;
1550     }
1551 
1552     interruptState = Cy_SysLib_EnterCriticalSection();
1553 
1554     printf("\n\nBuf Pool content\n");
1555     for (idx = 0U; idx < ((uint8_t)MAX_BUF_COUNT); idx++)
1556     {
1557 #if defined (__ARMCC_VERSION)
1558         printf("idx %d, bufType 0x%x, bufLen %d, bufPtr 0x%x\n",idx, contextPtr->buffPool[idx].bufType,contextPtr->buffPool[idx].bufLen, (uint32_t)(contextPtr->buffPool[idx].bufPtr));
1559 #else
1560     printf("idx %d, bufType 0x%x, bufLen %d, bufPtr %p\n",idx, contextPtr->buffPool[idx].bufType,contextPtr->buffPool[idx].bufLen, contextPtr->buffPool[idx].bufPtr);
1561 #endif
1562     }
1563 
1564     printf("\nFIFO content\n");
1565     for (idx = 0; idx < MAX_IPC_FIFO_SIZE; idx++)
1566     {
1567 #if defined (__ARMCC_VERSION)
1568         printf("idx %d, msg[0] 0x%x, msg[1] 0x%x\n",idx, contextPtr->IpcFifo.fifo[idx].msg[0], contextPtr->IpcFifo.fifo[idx].msg[1]);
1569 #else
1570         printf("idx %d, msg[0] 0x%lx, msg[1] 0x%lx\n",idx, contextPtr->IpcFifo.fifo[idx].msg[0], contextPtr->IpcFifo.fifo[idx].msg[1]);
1571 #endif
1572     }
1573     printf("rdIdx %d, wrIdx %d, bufLen %d\n",contextPtr->IpcFifo.rdIdx, contextPtr->IpcFifo.wrIdx, contextPtr->IpcFifo.bufLen);
1574 
1575     printf("\nCallbacks registered\n");
1576     for (idx = 0; idx < MAX_BT_IPC_HPC_CB; idx++)
1577     {
1578 #if defined (__ARMCC_VERSION)
1579         printf("idx %d, hpcNotifyCallbackPtr 0x%x, msgType %d\n", idx,
1580                 (uint32_t)(contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr),
1581                 contextPtr->hpcNotifyCallbackParam[idx].msgType);
1582 #else
1583     printf("idx %d, hpcNotifyCallbackPtr %p, msgType %d\n", idx,
1584             contextPtr->hpcNotifyCallbackParam[idx].hpcNotifyCallbackPtr,
1585             contextPtr->hpcNotifyCallbackParam[idx].msgType);
1586 #endif
1587     }
1588 
1589     Cy_SysLib_ExitCriticalSection(interruptState);
1590     return CY_BT_IPC_DRV_SUCCESS;
1591 }
1592 #endif
1593 CY_MISRA_BLOCK_END('ARRAY_VS_SINGLETON')
1594 #endif
1595