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