1 /***************************************************************************//**
2 * \file cy_ipc_pipe.h
3 * \version 1.130
4 *
5 *  Description:
6 *   IPC Pipe Driver - This header file contains all the function prototypes,
7 *   structure definitions, pipe constants, and pipe endpoint address definitions.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
12 * an affiliate of Cypress Semiconductor Corporation.
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 *     http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27 #ifndef CY_IPC_PIPE_H
28 #define CY_IPC_PIPE_H
29 
30 /******************************************************************************/
31 /* Include files                                                              */
32 /******************************************************************************/
33 
34 #include "cy_device.h"
35 
36 #if defined (CY_IP_M4CPUSS) || defined (CY_IP_M7CPUSS) || defined (CY_IP_MXIPC)
37 
38 #include "cy_ipc_drv.h"
39 #include "cy_syslib.h"
40 #include "cy_sysint.h"
41 
42 /**
43 * \addtogroup group_ipc_pipe IPC pipes layer (IPC_PIPE)
44 * \{
45 * The Pipe functions provide a method to transfer one or more words of data
46 * between CPUs or tasks.
47 *
48 * Include cy_ipc_pipe.h. Alternatively include cy_pdl.h
49 * to get access to all functions and declarations in the PDL.
50 *
51 * The data can be defined as a single 32-bit unsigned
52 * word, an array of data, or a user-defined structure.  The only limitation is
53 * that the first word in the array or structure must be a 32-bit unsigned word
54 * in which a client ID number is passed. The client ID dictates the callback
55 * function that will be called by the receiver of the message. After the
56 * callback function returns by the receiver, it will invoke a release callback
57 * function defined by the sender of the message.
58 *
59 * A User Pipe is provided for the user to transfer data between CPUs and
60 * tasks.
61 *
62 *     \defgroup group_ipc_pipe_macros Macros
63 *       Macro definitions are used in the driver
64 *
65 *     \defgroup group_ipc_pipe_functions Functions
66 *       Functions are used in the driver
67 *
68 *     \defgroup group_ipc_pipe_data_structures Data Structures
69 *       Data structures are used in the driver
70 *
71 *     \defgroup group_ipc_pipe_enums Enumerated Types
72 *       Enumerations are used in the driver
73 * \}
74 *
75 */
76 
77 /*
78  * This section defines the system level constants required to define
79  * callback arrays for the Cypress pipe and the user pipe.  These defines
80  * are used for both the max callback count and maximum clients.
81 */
82 
83 /** Typedef for pipe callback function pointer */
84 typedef void (* cy_ipc_pipe_callback_ptr_t)(uint32_t * msgPtr);
85 
86 /** Typedef for a pipe release callback function pointer */
87 typedef void (* cy_ipc_pipe_relcallback_ptr_t)(void);
88 
89 /** Typedef for array of callback function pointers */
90 typedef cy_ipc_pipe_callback_ptr_t *cy_ipc_pipe_callback_array_ptr_t;
91 
92 
93 /**
94 * \addtogroup group_ipc_pipe_macros
95 * \{
96 */
97 
98 /*
99  * The System pipe address is what is used to send a message to one of the
100  * endpoints of a pipe.  Currently the Cypress pipe and the User pipe
101  * are supported.  For parts with extra IPC channels users may create
102  * their own custom pipes and create their own pipe addresses.
103  *
104  * The format of the endpoint configuration
105  *    Bits[31:16] Interrupt Mask
106  *    Bits[15:8 ] IPC interrupt
107  *    Bits[ 7:0 ] IPC channel
108  */
109 #define CY_IPC_PIPE_CFG_IMASK_Pos      (16UL)           /**< Interrupts shift value for endpoint address */
110 #define CY_IPC_PIPE_CFG_IMASK_Msk      (0xFFFF0000UL)   /**< Interrupts mask for endpoint address */
111 #define CY_IPC_PIPE_CFG_INTR_Pos       (8UL)            /**< IPC Interrupt shift value for endpoint address */
112 #define CY_IPC_PIPE_CFG_INTR_Msk       (0x0000FF00UL)   /**< IPC Interrupt mask for endpoint address */
113 #define CY_IPC_PIPE_CFG_CHAN_Pos       (0UL)            /**< IPC Channel shift value for endpoint address */
114 #define CY_IPC_PIPE_CFG_CHAN_Msk       (0x000000FFUL)   /**< IPC Channel mask for endpoint address */
115 
116 
117 
118 #define CY_IPC_PIPE_MSG_CLIENT_Msk     (0x000000FFUL)   /**< Client mask for first word of Pipe message */
119 #define CY_IPC_PIPE_MSG_CLIENT_Pos     (0UL)            /**< Client shift for first word of Pipe message */
120 #define CY_IPC_PIPE_MSG_USR_Msk        (0x0000FF00UL)   /**< User data mask for first word of Pipe message */
121 #define CY_IPC_PIPE_MSG_USR_Pos        (8UL)            /**< User data shift for first word of Pipe message */
122 #define CY_IPC_PIPE_MSG_RELEASE_Msk    (0xFFFF0000UL)   /**< Mask for message release mask */
123 #define CY_IPC_PIPE_MSG_RELEASE_Pos    (16UL)           /**< Shift require to line up mask to LSB */
124 
125 /** Use to set the busy flag when waiting for a release interrupt */
126 #define CY_IPC_PIPE_ENDPOINT_BUSY      (1UL)
127 /** Denotes that a release interrupt is not pending */
128 #define CY_IPC_PIPE_ENDPOINT_NOTBUSY   (0UL)
129 
130 /** \} group_ipc_pipe_macros */
131 
132 /**
133 * \addtogroup group_ipc_pipe_data_structures
134 * \{
135 */
136 
137 /**
138 * This is the definition of a pipe endpoint.  There is one endpoint structure
139 * for each CPU in a pipe.  It contains all the information to process a message
140 * send to other CPUs in the pipe.
141 */
142 typedef struct
143 {
144     uint32_t        ipcChan;           /**< IPC channel number used for this endpoint to receive messages             */
145     uint32_t        intrChan;          /**< IPC interrupt channel number used for this endpoint to receive interrupts */
146     uint32_t        pipeIntMask;       /**< Release/Notify interrupt mask that includes all endpoints on pipe         */
147     IRQn_Type       pipeIntrSrc;       /**< Interrupt vector number that includes all endpoints on pipe               */
148 
149     IPC_STRUCT_Type *ipcPtr;           /**< Pointer to receive IPC channel ( If ipcPtr == NULL, cannot receive )      */
150     IPC_INTR_STRUCT_Type *ipcIntrPtr;  /**< Pointer to IPC interrupt, needed to clear the interrupt                   */
151     uint32_t         busy;             /**< Endpoint busy flag.  If set no messages can be sent from this endpoint   */
152     uint32_t         clientCount;      /**< Client count and size of MsgCallback array                                */
153 
154     cy_ipc_pipe_callback_array_ptr_t callbackArray; /**< Pointer to array of callback functions, one for each Client  */
155     cy_ipc_pipe_relcallback_ptr_t releaseCallbackPtr;  /**< Pointer to release callback function                      */
156     cy_ipc_pipe_relcallback_ptr_t defaultReleaseCallbackPtr; /**< Pointer to default release callback function              */
157 } cy_stc_ipc_pipe_ep_t;
158 
159 #if (CY_IPC_INSTANCES > 1U) || defined (CY_DOXYGEN)
160 /** The Pipe endpoint configuration mask structure.
161 *
162 * \note
163 * This structure is available only for the CAT1D devices.
164 *
165 */
166 typedef struct
167 {
168     uint32_t    epChannel;                    /**< IPC channel number */
169     uint32_t    epIntr;                       /**< IPC interrupt number */
170     uint32_t    epIntrmask;                   /**< IPC interrupt mask. This comprises of all channels present in all IPC IP instances . */
171 } cy_stc_ipc_pipe_ep_config_mask_t;
172 #endif /* (CY_IPC_INSTANCES > 1U) */
173 
174 /** The Pipe endpoint configuration structure. */
175 typedef struct
176 {
177     uint32_t    ipcNotifierNumber;             /**< Notifier. It comprises of total number of interrupts present in all instances of IPC IPs. */
178     uint32_t    ipcNotifierPriority;           /**< Notifier Priority */
179     uint32_t    ipcNotifierMuxNumber;          /**< CM0+ interrupt multiplexer number */
180 
181     uint32_t    epAddress;                     /**< Index in the array of endpoint structure */
182 #if (CY_IPC_INSTANCES > 1U)
183     cy_stc_ipc_pipe_ep_config_mask_t epConfig; /**< Configuration mask, contains IPC channel, IPC interrupt number,
184                                                     and the interrupt mask */
185 #else
186     uint32_t    epConfig;               /**< Configuration mask, contains IPC channel, IPC interrupt number,
187                                              and the interrupt mask */
188 #endif
189 } cy_stc_ipc_pipe_ep_config_t;
190 
191 /** The Pipe channel configuration structure. */
192 typedef struct
193 {
194     /** Specifies the notify interrupt number for the receiver endpoint.
195      *  Only for CAT1A device, it is used as first endpoint. */
196     cy_stc_ipc_pipe_ep_config_t ep0ConfigData;
197 
198     /** Specifies the notify interrupt number for the send endpoint.
199      *  Only for CAT1A device, it is used as second endpoint. */
200     cy_stc_ipc_pipe_ep_config_t ep1ConfigData;
201 
202     /** Client count and size of MsgCallback array */
203     uint32_t    endpointClientsCount;
204 
205     /** Pipes callback function array. */
206     cy_ipc_pipe_callback_array_ptr_t endpointsCallbacksArray;
207 
208     /** User IRQ handler function that is called when IPC receive data to process (interrupt was raised). */
209     cy_israddress userPipeIsrHandler;
210 } cy_stc_ipc_pipe_config_t;
211 
212 /** \} goup_ipc_pipe_data_structures */
213 
214 /**
215 * \addtogroup group_ipc_pipe_macros
216 * \{
217 */
218 /* Status and error types */
219 #define CY_IPC_PIPE_RTN        (0x0200UL)                                       /**< Software PDL driver ID for IPC pipe functions */
220 #define CY_IPC_PIPE_ID_INFO    (uint32_t)( CY_IPC_ID_INFO    | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function status codes */
221 #define CY_IPC_PIPE_ID_WARNING (uint32_t)( CY_IPC_ID_WARNING | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function warning return values */
222 #define CY_IPC_PIPE_ID_ERROR   (uint32_t)( CY_IPC_ID_ERROR   | CY_IPC_PIPE_RTN) /**< Return prefix for IPC pipe function error return values */
223 
224 /** \} group_ipc_pipe_macros */
225 
226 /**
227 * \addtogroup group_ipc_pipe_enums
228 * \{
229 */
230 
231 /** Return constants for IPC pipe functions. */
232 typedef enum
233 {
234     CY_IPC_PIPE_SUCCESS            =(uint32_t)(0x00u),                      /**<  Pipe API return for no error */
235     CY_IPC_PIPE_ERROR_NO_IPC       =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 1UL), /**<  Pipe API return for no valid IPC channel */
236     CY_IPC_PIPE_ERROR_NO_INTR      =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 2UL), /**<  Pipe API return for no valid interrupt */
237     CY_IPC_PIPE_ERROR_BAD_PRIORITY =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 3UL), /**<  Pipe API return for bad priority parameter */
238     CY_IPC_PIPE_ERROR_BAD_HANDLE   =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 4UL), /**<  Pipe API return for bad pipe handle */
239     CY_IPC_PIPE_ERROR_BAD_ID       =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 5UL), /**<  Pipe API return for bad pipe ID */
240     CY_IPC_PIPE_ERROR_DIR_ERROR    =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 6UL), /**<  Pipe API return for invalid direction (Not used at this time) */
241     CY_IPC_PIPE_ERROR_SEND_BUSY    =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 7UL), /**<  Pipe API return for pipe is currently busy */
242     CY_IPC_PIPE_ERROR_NO_MESSAGE   =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 8UL), /**<  Pipe API return for no message indicated   */
243     CY_IPC_PIPE_ERROR_BAD_CPU      =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 9UL), /**<  Pipe API return for invalid CPU value      */
244     CY_IPC_PIPE_ERROR_BAD_CLIENT   =(uint32_t)(CY_IPC_PIPE_ID_ERROR | 10UL) /**< Pipe API return for client out of range    */
245 } cy_en_ipc_pipe_status_t;
246 
247 /** \} group_ipc_pipe_enums */
248 
249 #if (CY_CPU_CORTEX_M0P)
250     #define CY_IPC_EP_CYPIPE_ADDR       CY_IPC_EP_CYPIPE_CM0_ADDR
251 #else
252     #define CY_IPC_EP_CYPIPE_ADDR       CY_IPC_EP_CYPIPE_CM4_ADDR
253 #endif  /* (CY_CPU_CORTEX_M0P) */
254 
255 /**
256 * \addtogroup group_ipc_pipe_data_structures
257 * \{
258 */
259 
260 /** \cond
261 *   NOTE: This doxygen comment must be placed before some code entity, or else
262 *         it will belong to a random entity that follows it, e.g. group_ipc_functions
263 *
264 * Client identifier for a message.
265 * For a given pipe, traffic across the pipe can be multiplexed with multiple
266 * senders on one end and multiple receivers on the other end.
267 *
268 * The first 32-bit word of the message is used to identify the client that owns
269 * the message.
270 *
271 * The upper 16-bits are the client ID.
272 *
273 * The lower 16-bits are for use by the client in any way desired.
274 *
275 * The lower 16-bits are preserved (not modified) and not interpreted in any way.
276 * \endcond
277 */
278 
279 /** \} group_ipc_pipe_data_structures */
280 
281 
282 /******************************************************************************/
283 /* Global function prototypes (definition in C source)                        */
284 /******************************************************************************/
285 
286 /**
287 * \addtogroup group_ipc_pipe_functions
288 * \{
289 */
290 
291 #ifdef __cplusplus
292 extern "C" {
293 #endif
294 
295 void Cy_IPC_Pipe_EndpointInit(uint32_t epAddr, cy_ipc_pipe_callback_array_ptr_t cbArray,
296                               uint32_t cbCnt, uint32_t epConfig, cy_stc_sysint_t const *epInterrupt);
297 #if (CY_IPC_INSTANCES > 1U) || defined (CY_DOXYGEN)
298 void Cy_IPC_Pipe_EndpointInitExt(uint32_t epAddr, cy_ipc_pipe_callback_array_ptr_t cbArray,
299                               uint32_t cbCnt, cy_stc_ipc_pipe_ep_config_mask_t *epConfig, cy_stc_sysint_t const *epInterrupt);
300 #endif /* CY_IPC_INSTANCES */
301 cy_en_ipc_pipe_status_t  Cy_IPC_Pipe_SendMessage(uint32_t toAddr, uint32_t fromAddr, void *msgPtr,
302                               cy_ipc_pipe_relcallback_ptr_t callBackPtr);
303 cy_en_ipc_pipe_status_t  Cy_IPC_Pipe_RegisterCallback(uint32_t epAddr,
304                               cy_ipc_pipe_callback_ptr_t callBackPtr,  uint32_t clientId);
305 void                     Cy_IPC_Pipe_ExecuteCallback(uint32_t epAddr);
306 void                     Cy_IPC_Pipe_RegisterCallbackRel(uint32_t epAddr, cy_ipc_pipe_relcallback_ptr_t callBackPtr);
307 void                     Cy_IPC_Pipe_Config(cy_stc_ipc_pipe_ep_t * theEpArray);
308 void                     Cy_IPC_Pipe_Init(cy_stc_ipc_pipe_config_t const *config);
309 
310 cy_en_ipc_pipe_status_t  Cy_IPC_Pipe_EndpointPause(uint32_t epAddr);
311 cy_en_ipc_pipe_status_t  Cy_IPC_Pipe_EndpointResume(uint32_t epAddr);
312 
313 /* This function is obsolete and will be removed in the next releases */
314 void                     Cy_IPC_Pipe_ExecCallback(cy_stc_ipc_pipe_ep_t * endpoint);
315 
316 #ifdef __cplusplus
317 }
318 #endif
319 
320 /** \} group_ipc_pipe_functions */
321 
322 #endif /* CY_IP_M4CPUSS  || CY_IP_M7CPUSS || (defined (CY_IP_MXIPC) && (CY_IPC_INSTANCES > 1U)) */
323 
324 #endif /* CY_IPC_PIPE_H  */
325 
326 /* [] END OF FILE */
327