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