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