1 /***************************************************************************//**
2 * \file cy_ipc_pipe.c
3 * \version 1.60
4 *
5 *  Description:
6 *   IPC Pipe Driver - This source file includes code for the Pipe layer on top
7 *   of the IPC driver.
8 *
9 ********************************************************************************
10 * Copyright 2016-2020 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *     http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 #include "cy_device.h"
27 
28 #if defined (CY_IP_M4CPUSS)
29 
30 #include "cy_ipc_pipe.h"
31 
32 /* Define a pointer to array of endPoints. */
33 static cy_stc_ipc_pipe_ep_t * cy_ipc_pipe_epArray = NULL;
34 
35 
36 /*******************************************************************************
37 * Function Name: Cy_IPC_Pipe_Config
38 ****************************************************************************//**
39 *
40 * This function stores a copy of a pointer to the array of endpoints.  All
41 * access to endpoints will be via the index of the endpoint in this array.
42 *
43 * \note In general case, this function is called in the default startup code,
44 * so user doesn't need to call it anywhere.
45 * However, it may be useful in case of some pipe customizations.
46 *
47 * \param theEpArray
48 * This is the pointer to an array of endpoint structures that the designer
49 * created and will be used to reference all endpoints.
50 *
51 * \funcusage
52 * \snippet ipc/snippet/main.c snippet_myIpcPipeEpArray
53 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_Config
54 *
55 *******************************************************************************/
Cy_IPC_Pipe_Config(cy_stc_ipc_pipe_ep_t * theEpArray)56 void Cy_IPC_Pipe_Config(cy_stc_ipc_pipe_ep_t * theEpArray)
57 {
58     /* Keep copy of this endpoint */
59     if (cy_ipc_pipe_epArray == NULL)
60     {
61         cy_ipc_pipe_epArray = theEpArray;
62     }
63 }
64 
65 
66 /*******************************************************************************
67 * Function Name: Cy_IPC_Pipe_Init
68 ****************************************************************************//**
69 *
70 * Initializes the system pipes. The system pipes are used by BLE.
71 * \note The function should be called on all CPUs.
72 *
73 * \note In general case, this function is called in the default startup code,
74 * so user doesn't need to call it anywhere.
75 * However, it may be useful in case of some pipe customizations.
76 *
77 * \param config
78 * This is the pointer to the pipe configuration structure
79 *
80 * \funcusage
81 * \snippet ipc/snippet/main.c snippet_myIpcPipeCbArray
82 * \snippet ipc/snippet/main.c snippet_myIpcPipeEpConfig
83 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_Init
84 *
85 *******************************************************************************/
Cy_IPC_Pipe_Init(cy_stc_ipc_pipe_config_t const * config)86 void Cy_IPC_Pipe_Init(cy_stc_ipc_pipe_config_t const *config)
87 {
88     /* Create the interrupt structures and arrays needed */
89 
90     cy_stc_sysint_t                 ipc_intr_cypipeConfig;
91 
92     cy_stc_ipc_pipe_ep_config_t        epConfigDataA;
93     cy_stc_ipc_pipe_ep_config_t        epConfigDataB;
94 
95     /* Parameters checking begin */
96     CY_ASSERT_L1(NULL != config);
97     #if (CY_CPU_CORTEX_M0P)
98     CY_ASSERT_L2((uint32_t)(1UL << __NVIC_PRIO_BITS) > config->ep0ConfigData.ipcNotifierPriority);
99     #else
100     CY_ASSERT_L2((uint32_t)(1UL << __NVIC_PRIO_BITS) > config->ep1ConfigData.ipcNotifierPriority);
101     #endif
102     CY_ASSERT_L1(NULL != config->endpointsCallbacksArray);
103     CY_ASSERT_L1(NULL != config->userPipeIsrHandler);
104     /* Parameters checking end */
105 
106 #if (CY_CPU_CORTEX_M0P)
107 
108     /* Receiver endpoint = EP0, Sender endpoint = EP1 */
109     epConfigDataA = config->ep0ConfigData;
110     epConfigDataB = config->ep1ConfigData;
111 
112     /* Configure CM0 interrupts */
113     ipc_intr_cypipeConfig.intrSrc          = (IRQn_Type)epConfigDataA.ipcNotifierMuxNumber;
114     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to IRQn_Type enum');
115     ipc_intr_cypipeConfig.cm0pSrc          = (cy_en_intr_t)((int32_t)cy_device->cpussIpc0Irq + (int32_t)epConfigDataA.ipcNotifierNumber);
116     ipc_intr_cypipeConfig.intrPriority     = epConfigDataA.ipcNotifierPriority;
117 
118 #else
119 
120     /* Receiver endpoint = EP1, Sender endpoint = EP0 */
121     epConfigDataA = config->ep1ConfigData;
122     epConfigDataB = config->ep0ConfigData;
123 
124     /* Configure interrupts */
125     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to IRQn_Type enum');
126     ipc_intr_cypipeConfig.intrSrc          = (IRQn_Type)((int32_t)cy_device->cpussIpc0Irq + (int32_t)epConfigDataA.ipcNotifierNumber);
127     ipc_intr_cypipeConfig.intrPriority     = epConfigDataA.ipcNotifierPriority;
128 
129 #endif
130 
131     /* Initialize the pipe endpoints */
132     Cy_IPC_Pipe_EndpointInit(epConfigDataA.epAddress,
133                              config->endpointsCallbacksArray,
134                              config->endpointClientsCount,
135                              epConfigDataA.epConfig,
136                              &ipc_intr_cypipeConfig);
137 
138     /* Create the endpoints for the CM4 just for reference */
139     Cy_IPC_Pipe_EndpointInit(epConfigDataB.epAddress, NULL, 0UL, epConfigDataB.epConfig, NULL);
140 
141     (void)Cy_SysInt_Init(&ipc_intr_cypipeConfig, config->userPipeIsrHandler);
142 
143     /* Enable the interrupts */
144     NVIC_EnableIRQ(ipc_intr_cypipeConfig.intrSrc);
145 }
146 
147 
148 /*******************************************************************************
149 * Function Name: Cy_IPC_Pipe_EndpointInit
150 ****************************************************************************//**
151 *
152 * This function initializes the endpoint of a pipe for the current CPU.  The
153 * current CPU is the CPU that is executing the code. An endpoint of a pipe
154 * is for the IPC channel that receives a message for the current CPU.
155 *
156 * After this function is called, the callbackArray needs to be populated
157 * with the callback functions for that endpoint using the
158 * Cy_IPC_Pipe_RegisterCallback() function.
159 *
160 * \note In general case, this function is called within \ref Cy_IPC_Pipe_Init,
161 * so user doesn't need to call it anywhere.
162 * However, it may be useful in case of some pipe/endpoint customizations.
163 *
164 * \param epAddr
165 * This parameter is the address (or index in the array of endpoint structures)
166 * that designates the endpoint you want to initialize.
167 *
168 * \param cbArray
169 * This is a pointer to the callback function array.  Based on the client ID, one
170 * of the functions in this array is called to process the message.
171 *
172 * \param cbCnt
173 * This is the size of the callback array, or the number of defined clients.
174 *
175 * \param epConfig
176 * This value defines the IPC channel, IPC interrupt number, and the interrupt
177 * mask for the entire pipe.
178 * The format of the endpoint configuration
179 *    Bits[31:16] Interrupt Mask
180 *    Bits[15:8 ] IPC interrupt
181 *    Bits[ 7:0 ] IPC channel
182 *
183 * \param epInterrupt
184 * This is a pointer to the endpoint interrupt description structure.
185 *
186 * \funcusage
187 * \snippet ipc/snippet/main.c snippet_myIpcPipeCbArray
188 * \snippet ipc/snippet/main.c snippet_myIpcPipeEpConfig
189 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_EndpointInit
190 *
191 *******************************************************************************/
Cy_IPC_Pipe_EndpointInit(uint32_t epAddr,cy_ipc_pipe_callback_array_ptr_t cbArray,uint32_t cbCnt,uint32_t epConfig,cy_stc_sysint_t const * epInterrupt)192 void Cy_IPC_Pipe_EndpointInit(uint32_t epAddr, cy_ipc_pipe_callback_array_ptr_t cbArray,
193                               uint32_t cbCnt, uint32_t epConfig, cy_stc_sysint_t const *epInterrupt)
194 {
195     cy_stc_ipc_pipe_ep_t * endpoint;
196 
197     CY_ASSERT_L1(NULL != cy_ipc_pipe_epArray);
198 
199     endpoint = &cy_ipc_pipe_epArray[epAddr];
200 
201     /* Extract the channel, interrupt and interrupt mask */
202     endpoint->ipcChan         = _FLD2VAL(CY_IPC_PIPE_CFG_CHAN,  epConfig);
203     endpoint->intrChan        = _FLD2VAL(CY_IPC_PIPE_CFG_INTR,  epConfig);
204     endpoint->pipeIntMask     = _FLD2VAL(CY_IPC_PIPE_CFG_IMASK, epConfig);
205 
206     /* Assign IPC channel to this endpoint */
207     endpoint->ipcPtr   = Cy_IPC_Drv_GetIpcBaseAddress (endpoint->ipcChan);
208 
209     /* Assign interrupt structure to endpoint and Initialize the interrupt mask for this endpoint */
210     endpoint->ipcIntrPtr = Cy_IPC_Drv_GetIntrBaseAddr(endpoint->intrChan);
211 
212     /* Only allow notify and release interrupts from endpoints in this pipe. */
213     Cy_IPC_Drv_SetInterruptMask(endpoint->ipcIntrPtr, endpoint->pipeIntMask, endpoint->pipeIntMask);
214 
215     /* Save the Client count and the callback array pointer */
216     endpoint->clientCount   = cbCnt;
217     endpoint->callbackArray = cbArray;
218     endpoint->busy = CY_IPC_PIPE_ENDPOINT_NOTBUSY;
219 
220     if (NULL != epInterrupt)
221     {
222         endpoint->pipeIntrSrc     = epInterrupt->intrSrc;
223     }
224 }
225 
226 
227 /*******************************************************************************
228 * Function Name: Cy_IPC_Pipe_SendMessage
229 ****************************************************************************//**
230 *
231 * This function is used to send a message from one endpoint to another.  It
232 * generates an interrupt on the endpoint that receives the message and a
233 * release interrupt to the sender to acknowledge the message has been processed.
234 *
235 * \param toAddr
236 * This parameter is the address (or index in the array of endpoint structures)
237 * of the endpoint to which you are sending the message.
238 *
239 * \param fromAddr
240 * This parameter is the address (or index in the array of endpoint structures)
241 * of the endpoint from which the message is being sent.
242 *
243 * \param msgPtr
244 * Pointer to the message structure to be sent.
245 *
246 * \param callBackPtr
247 * Pointer to the Release callback function.
248 *
249 * \return
250 *    CY_IPC_PIPE_SUCCESS:          Message was sent to the other end of the pipe
251 *    CY_IPC_PIPE_ERROR_BAD_HANDLE: The handle provided for the pipe was not valid
252 *    CY_IPC_PIPE_ERROR_SEND_BUSY:  The pipe is already busy sending a message
253 *
254 * \funcusage
255 * \snippet ipc/snippet/main.c snippet_myReleaseCallback
256 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_SendMessage
257 *
258 *******************************************************************************/
Cy_IPC_Pipe_SendMessage(uint32_t toAddr,uint32_t fromAddr,void * msgPtr,cy_ipc_pipe_relcallback_ptr_t callBackPtr)259 cy_en_ipc_pipe_status_t Cy_IPC_Pipe_SendMessage(uint32_t toAddr, uint32_t fromAddr,
260                                                 void * msgPtr, cy_ipc_pipe_relcallback_ptr_t callBackPtr)
261 {
262     cy_en_ipc_pipe_status_t  returnStatus;
263     uint32_t releaseMask;
264     uint32_t notifyMask;
265 
266     cy_stc_ipc_pipe_ep_t * fromEp;
267     cy_stc_ipc_pipe_ep_t * toEp;
268 
269     CY_ASSERT_L1(NULL != msgPtr);
270     CY_ASSERT_L1(NULL != cy_ipc_pipe_epArray);
271 
272     toEp   = &(cy_ipc_pipe_epArray[toAddr]);
273     fromEp = &cy_ipc_pipe_epArray[fromAddr];
274 
275     /* Create the release mask for the "fromAddr" channel's interrupt channel */
276     releaseMask =  (uint32_t)(1UL << (fromEp->intrChan));
277 
278     /* Shift into position */
279     releaseMask = _VAL2FLD(CY_IPC_PIPE_MSG_RELEASE, releaseMask);
280 
281     /* Create the notify mask for the "toAddr" channel's interrupt channel */
282     notifyMask  =  (uint32_t)(1UL << (toEp->intrChan));
283 
284     /* Check if IPC channel valid */
285     if( toEp->ipcPtr != NULL)
286     {
287         if(fromEp->busy == CY_IPC_PIPE_ENDPOINT_NOTBUSY)
288         {
289             /* Attempt to acquire the channel */
290             if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(toEp->ipcPtr) )
291             {
292                 /* Mask out the release mask area */
293                 * (uint32_t *) msgPtr &= ~(CY_IPC_PIPE_MSG_RELEASE_Msk);
294 
295                 * (uint32_t *) msgPtr |= releaseMask;
296 
297                 /* If the channel was acquired, write the message.   */
298                 Cy_IPC_Drv_WriteDataValue(toEp->ipcPtr, (uint32_t) msgPtr);
299 
300                 /* Set the busy flag.  The ISR clears this after the release */
301                 fromEp->busy = CY_IPC_PIPE_ENDPOINT_BUSY;
302 
303                 /* Setup release callback function */
304                 fromEp->releaseCallbackPtr = callBackPtr;
305 
306                 /* Cause notify event/interrupt */
307                 Cy_IPC_Drv_AcquireNotify(toEp->ipcPtr, notifyMask);
308 
309                 returnStatus = CY_IPC_PIPE_SUCCESS;
310             }
311             else
312             {
313                 /* Channel was already acquired, return Error */
314                 returnStatus = CY_IPC_PIPE_ERROR_SEND_BUSY;
315             }
316         }
317         else
318         {
319             /* Channel may not be acquired, but the release interrupt has not executed yet */
320             returnStatus = CY_IPC_PIPE_ERROR_SEND_BUSY;
321         }
322     }
323     else
324     {
325         /* Null pipe handle. */
326         returnStatus = CY_IPC_PIPE_ERROR_BAD_HANDLE;
327     }
328     return (returnStatus);
329 }
330 
331 
332 /*******************************************************************************
333 * Function Name: Cy_IPC_Pipe_RegisterCallback
334 ****************************************************************************//**
335 *
336 * This function registers a callback that is called when a message is received
337 * on a pipe.
338 * The client_ID is the same as the index of the callback function array.
339 * The callback may be a real function pointer or NULL if no callback is required.
340 *
341 * \param epAddr
342 * This parameter is the address (or index in the array of endpoint structures)
343 * that designates the endpoint to which you want to add callback functions.
344 *
345 * \param callBackPtr
346 * Pointer to the callback function called when the endpoint has received a message.
347 * If this parameters is NULL current callback will be unregistered.
348 *
349 * \param clientId
350 * The index in the callback array (Client ID) where the function pointer is saved.
351 *
352 * \return
353 *    CY_IPC_PIPE_SUCCESS:           Callback registered successfully
354 *    CY_IPC_PIPE_ERROR_BAD_CLIENT:  Client ID out of range, callback not registered.
355 *
356 * \funcusage
357 * \snippet ipc/snippet/main.c snippet_myAcquireCallback
358 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_RegisterCallback
359 *
360 *******************************************************************************/
Cy_IPC_Pipe_RegisterCallback(uint32_t epAddr,cy_ipc_pipe_callback_ptr_t callBackPtr,uint32_t clientId)361 cy_en_ipc_pipe_status_t Cy_IPC_Pipe_RegisterCallback(uint32_t epAddr, cy_ipc_pipe_callback_ptr_t callBackPtr,  uint32_t clientId)
362 {
363     cy_en_ipc_pipe_status_t returnStatus;
364     cy_stc_ipc_pipe_ep_t * thisEp;
365 
366     CY_ASSERT_L1(NULL != cy_ipc_pipe_epArray);
367 
368     thisEp = &cy_ipc_pipe_epArray[epAddr];
369 
370     CY_ASSERT_L1(NULL != thisEp->callbackArray);
371 
372     /* Check if clientId is between 0 and less than client count */
373     if (clientId < thisEp->clientCount)
374     {
375         /* Copy callback function into callback function pointer array */
376         thisEp->callbackArray[clientId] = callBackPtr;
377 
378         returnStatus = CY_IPC_PIPE_SUCCESS;
379     }
380     else
381     {
382         returnStatus = CY_IPC_PIPE_ERROR_BAD_CLIENT;
383     }
384     return (returnStatus);
385 }
386 
387 
388 /*******************************************************************************
389 * Function Name: Cy_IPC_Pipe_RegisterCallbackRel
390 ****************************************************************************//**
391 *
392 * This function registers a default callback if a release interrupt
393 * is generated but the current release callback function is null.
394 *
395 *
396 * \param epAddr
397 * This parameter is the address (or index in the array of endpoint structures)
398 * that designates the endpoint to which you want to add a release callback function.
399 *
400 * \param callBackPtr
401 * Pointer to the callback executed when the endpoint has received a message.
402 * If this parameters is NULL current callback will be unregistered.
403 *
404 * \return
405 *    None
406 *
407 * \funcusage
408 * \snippet ipc/snippet/main.c snippet_myDefaultReleaseCallback
409 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_RegisterCallbackRel
410 *
411 *******************************************************************************/
Cy_IPC_Pipe_RegisterCallbackRel(uint32_t epAddr,cy_ipc_pipe_relcallback_ptr_t callBackPtr)412 void Cy_IPC_Pipe_RegisterCallbackRel(uint32_t epAddr, cy_ipc_pipe_relcallback_ptr_t callBackPtr)
413 {
414     cy_stc_ipc_pipe_ep_t * endpoint;
415 
416     CY_ASSERT_L1(NULL != cy_ipc_pipe_epArray);
417 
418     endpoint = &cy_ipc_pipe_epArray[epAddr];
419 
420     /* Copy callback function into callback function pointer array */
421     endpoint->defaultReleaseCallbackPtr = callBackPtr;
422 }
423 
424 
425 /*******************************************************************************
426 * Function Name: Cy_IPC_Pipe_ExecuteCallback
427 ****************************************************************************//**
428 *
429 * This function is called by the ISR for a given pipe endpoint to dispatch
430 * the appropriate callback function based on the client ID for that endpoint.
431 *
432 * \param epAddr
433 * This parameter is the address (or index in the array of endpoint structures)
434 * that designates the endpoint to process.
435 *
436 * \note This function should be used instead of obsolete
437 *       Cy_IPC_Pipe_ExecCallback() function because it will be removed in the
438 *       next releases.
439 *
440 * \funcusage
441 * \snippet ipc/snippet/main.c snippet_myIpcPipeEpArray
442 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_ExecuteCallback
443 *
444 *******************************************************************************/
Cy_IPC_Pipe_ExecuteCallback(uint32_t epAddr)445 void Cy_IPC_Pipe_ExecuteCallback(uint32_t epAddr)
446 {
447     cy_stc_ipc_pipe_ep_t * endpoint;
448 
449     CY_ASSERT_L1(NULL != cy_ipc_pipe_epArray);
450 
451     endpoint = &cy_ipc_pipe_epArray[epAddr];
452 
453     Cy_IPC_Pipe_ExecCallback(endpoint);
454 }
455 
456 
457 /*******************************************************************************
458 * Function Name: Cy_IPC_Pipe_ExecCallback
459 ****************************************************************************//**
460 *
461 * This function is called by the ISR for a given pipe endpoint to dispatch
462 * the appropriate callback function based on the client ID for that endpoint.
463 *
464 * \param endpoint
465 * Pointer to endpoint structure.
466 *
467 * \note This function is obsolete and will be removed in the next releases.
468 *       Please use Cy_IPC_Pipe_ExecuteCallback() instead.
469 *
470 *******************************************************************************/
Cy_IPC_Pipe_ExecCallback(cy_stc_ipc_pipe_ep_t * endpoint)471 void Cy_IPC_Pipe_ExecCallback(cy_stc_ipc_pipe_ep_t * endpoint)
472 {
473     uint32_t *msgPtr = NULL;
474     uint32_t clientID;
475     uint32_t shadowIntr;
476     uint32_t releaseMask = (uint32_t)0;
477 
478     cy_ipc_pipe_callback_ptr_t callbackPtr;
479 
480     /* Parameters checking begin */
481     CY_ASSERT_L1(NULL != endpoint);
482     CY_ASSERT_L1(NULL != endpoint->ipcPtr);
483     CY_ASSERT_L1(NULL != endpoint->ipcIntrPtr);
484     CY_ASSERT_L1(NULL != endpoint->callbackArray);
485     /* Parameters checking end */
486 
487     shadowIntr = Cy_IPC_Drv_GetInterruptStatusMasked(endpoint->ipcIntrPtr);
488 
489     /* Check to make sure the interrupt was a notify interrupt */
490     if (0UL != Cy_IPC_Drv_ExtractAcquireMask(shadowIntr))
491     {
492         /* Clear the notify interrupt.  */
493         Cy_IPC_Drv_ClearInterrupt(endpoint->ipcIntrPtr, CY_IPC_NO_NOTIFICATION, Cy_IPC_Drv_ExtractAcquireMask(shadowIntr));
494 
495         if ( Cy_IPC_Drv_IsLockAcquired (endpoint->ipcPtr) )
496         {
497             /* Extract Client ID  */
498             if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_ReadMsgPtr (endpoint->ipcPtr, (void **)&msgPtr))
499             {
500                 /* Get release mask */
501                 releaseMask = _FLD2VAL(CY_IPC_PIPE_MSG_RELEASE, *msgPtr);
502                 clientID    = _FLD2VAL(CY_IPC_PIPE_MSG_CLIENT,  *msgPtr);
503 
504                 /* Make sure client ID is within valid range */
505                 if (endpoint->clientCount > clientID)
506                 {
507                     callbackPtr = endpoint->callbackArray[clientID];  /* Get the callback function */
508 
509                     if (callbackPtr != NULL)
510                     {
511                         callbackPtr(msgPtr);   /* Call the function pointer for "clientID" */
512                     }
513                 }
514             }
515 
516             /* Must always release the IPC channel */
517             (void)Cy_IPC_Drv_LockRelease (endpoint->ipcPtr, releaseMask);
518         }
519     }
520 
521     /* Check to make sure the interrupt was a release interrupt */
522     if (0UL != Cy_IPC_Drv_ExtractReleaseMask(shadowIntr))  /* Check for a Release interrupt */
523     {
524         /* Clear the release interrupt  */
525         Cy_IPC_Drv_ClearInterrupt(endpoint->ipcIntrPtr, Cy_IPC_Drv_ExtractReleaseMask(shadowIntr), CY_IPC_NO_NOTIFICATION);
526 
527         if (endpoint->releaseCallbackPtr != NULL)
528         {
529             endpoint->releaseCallbackPtr();
530 
531             /* Clear the pointer after it was called */
532             endpoint->releaseCallbackPtr = NULL;
533         }
534         else
535         {
536             if (endpoint->defaultReleaseCallbackPtr != NULL)
537             {
538                 endpoint->defaultReleaseCallbackPtr();
539             }
540         }
541 
542         /* Clear the busy flag when release is detected */
543         endpoint->busy = CY_IPC_PIPE_ENDPOINT_NOTBUSY;
544     }
545 
546     (void)Cy_IPC_Drv_GetInterruptStatus(endpoint->ipcIntrPtr);
547 }
548 
549 
550 /*******************************************************************************
551 * Function Name: Cy_IPC_Pipe_EndpointPause
552 ****************************************************************************//**
553 *
554 * This function sets the receiver endpoint to paused state.
555 *
556 * \param epAddr
557 * This parameter is the address (or index in the array of endpoint structures)
558 * that designates the endpoint to pause.
559 *
560 * \return
561 *    CY_IPC_PIPE_SUCCESS:           Callback registered successfully
562 *
563 * \funcusage
564 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_EndpointPauseResume
565 *
566 *******************************************************************************/
Cy_IPC_Pipe_EndpointPause(uint32_t epAddr)567 cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointPause(uint32_t epAddr)
568 {
569     cy_stc_ipc_pipe_ep_t * endpoint;
570 
571     CY_ASSERT_L1(NULL != cy_ipc_pipe_epArray);
572 
573     endpoint = &cy_ipc_pipe_epArray[epAddr];
574 
575     /* Disable the interrupts */
576     NVIC_DisableIRQ(endpoint->pipeIntrSrc);
577 
578     return (CY_IPC_PIPE_SUCCESS);
579 }
580 
581 
582 /*******************************************************************************
583 * Function Name: Cy_IPC_Pipe_EndpointResume
584 ****************************************************************************//**
585 *
586 * This function sets the receiver endpoint to active state.
587 *
588 * \param epAddr
589 * This parameter is the address (or index in the array of endpoint structures)
590 * that designates the endpoint to resume.
591 *
592 * \return
593 *    CY_IPC_PIPE_SUCCESS:           Callback registered successfully
594 *
595 * \funcusage
596 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Pipe_EndpointPauseResume
597 *
598 *******************************************************************************/
Cy_IPC_Pipe_EndpointResume(uint32_t epAddr)599 cy_en_ipc_pipe_status_t Cy_IPC_Pipe_EndpointResume(uint32_t epAddr)
600 {
601     cy_stc_ipc_pipe_ep_t * endpoint;
602 
603     CY_ASSERT_L1(NULL != cy_ipc_pipe_epArray);
604 
605     endpoint = &cy_ipc_pipe_epArray[epAddr];
606 
607     /* Enable the interrupts */
608     NVIC_EnableIRQ(endpoint->pipeIntrSrc);
609 
610     return (CY_IPC_PIPE_SUCCESS);
611 }
612 
613 #endif
614 /* [] END OF FILE */
615