1 /***************************************************************************//**
2 * \file cy_ipc_drv.h
3 * \version 1.91
4 * Provides an API declaration of the IPC driver.
5 *
6 ********************************************************************************
7 * \copyright
8 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
9 * an affiliate of Cypress Semiconductor Corporation.
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 *     http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24 
25 #ifndef CY_IPC_DRV_H
26 #define CY_IPC_DRV_H
27 
28 
29 /**
30 * \addtogroup group_ipc
31 * \{
32 * The inter-processor communication (IPC) driver provides a safe and reliable
33 * method to transfer data between CPUs. Hardware locking ensures that only one
34 * device can acquire and transfer data at a time so no data is lost or
35 * overwritten by asynchronous processes or CPUs.
36 *
37 * Include either cy_ipc_pipe.h, cy_ipc_sema.h or cy_ipc_bt.h. Alternatively include cy_pdl.h
38 * to get access to all functions and declarations in the PDL.
39 *
40 * There are four parts to the API:
41 *     - Driver-level (DRV) API - used internally by Semaphore, Pipe and Bluetooth levels. These APIs are supported in all CAT1 devices.
42 *     - Pipe-level (PIPE) API - establishes a communication channel between
43 *       processors. These APIs are supported in all CAT1 devices.
44 *     - Semaphore-level (SEMA) API - enables users to set and clear flags to
45 *       synchronize operations. These APIs are supported in all CAT1 devices.
46 *     - Bluetooth Subsystem (BTSS) API - establishes communication channel
47 *       between MCU and the BTSS. These APIs are supported in CAT1B devices.
48 *
49 * Firmware does not need to use the DRV API. It can implement IPC functionality
50 * entirely with the PIPE, SEMA and BTSS APIs.
51 *
52 * \section group_ipc_background Background
53 *
54 * IPC is implemented in hardware as a collection of individual communication
55 * channels, each with a set of 32-bit registers. The IPC design implements a set
56 * of interrupts that enable each processor to notify the other that data is
57 * available, or has been processed. There is also a locking mechanism that
58 * allows only one CPU to gain access at a time.
59 *
60 * In case of devices having multiple IPC IP instances, IPC channels and IPC
61 * interrupts are associated with each other within particular IP instance. It is not
62 * possible to create an IPC mechanism where IPC channels of one IPC instance interacts
63 * with interrupts of another IPC instance. Following table describes channels and
64 * interrupts present in different devices:
65 * <table class="doxtable">
66 *   <tr><th>Device category</th><th>IPC IP instances</th><th>Channel numbers</th><th>Interrupt numbers</th></tr>
67 *   <tr>
68 *     <td>CAT1A</td>
69 *     <td>IPC0 ( Single instance )</td>
70 *     <td>0-15</td>
71 *     <td>0-15</td>
72 *   </tr>
73 *   <tr>
74 *     <td>CAT1B</td>
75 *     <td>IPC0 ( Single instance )</td>
76 *     <td>0-3</td>
77 *     <td>0-1</td>
78 *   </tr>
79 *   <tr>
80 *     <td>CAT1C</td>
81 *     <td>IPC0 ( Single instance )</td>
82 *     <td>0-7</td>
83 *     <td>0-7</td>
84 *   </tr>
85 *   <tr>
86 *     <td rowspan="2">CAT1D</td>
87 *     <td>IPC0 ( First instance )</td>
88 *     <td>0-15</td>
89 *     <td>0-7</td>
90 *   </tr>
91 *   <tr>
92 *     <td>IPC1 ( Second instance )</td>
93 *     <td>16-31</td>
94 *     <td>8-15</td>
95 *   </tr>
96 * </table>
97 *
98 * The Driver-level API manages each channel's registers to implement IPC
99 * functionality. For information on the IPC registers, see the IPC chapter of
100 * the Technical Reference Manual (TRM).
101 *
102 * At the hardware level, communication is a five-step process.
103 *     -#  The sending processor acquires a channel
104 *     -#  It puts data into the channel
105 *     -#  The sender generates a notify event (interrupt)
106 *     -#  The receiving processor identifies the sender and retrieves the data
107 *     -#  The receiving processor generates a release event (interrupt)
108 *
109 * \image html ipc_driver.png
110 *
111 * These transactions are handled transparently by the DRV-level API. Use the
112 * PIPE, SEMA and BTSS layers of the API to implement communication in your application.
113 * The data transferred is limited to a single 32-bit value in case of PIPE and SEMA and two
114 * 32-bit value incase of BTIPC. As implemented by
115 * the PIPE API, that value is a pointer to a data structure of arbitrary size
116 * and complexity.
117 * BTSS uses both 32-bit registers for communication of short messages. If the payload
118 * is greater than 7 bytes, then it copies the data to the shared memory between MCU
119 * and the BT SS.
120 *
121 * \section group_ipc_overview Overview
122 *
123 * The Pipe is the key element in the PDL design. A pipe is typically a
124 * full-duplex communication channel between CPU cores. A pipe allows a single
125 * conduit to transfer messages or data to and from multiple processes or CPUs.
126 *
127 * A pipe has two endpoints, one on each core. Each endpoint contains a dedicated
128 * IPC channel and an interrupt. IPC channels 0-7(8 for the CYB064XX devices)
129 * and IPC interrupts 0-7 are reserved for system use.
130 *
131 * The pipe also contains the number of clients it supports, and for each client
132 * a callback function. So, the pipe can service a number of clients, each with a
133 * separate callback function, on either endpoint. The number of clients a pipe
134 * supports is the sum of each endpoint's clients.
135 *
136 * This design enables any number of processes on the sending core to put
137 * arbitrary data into a single pipe. The first element of that data is the
138 * client ID of the client that should handle the data.
139 *
140 * An interrupt notifies the receiving core that data is available. The receiving
141 * core parses the data to identify the client, and then dispatches the event to
142 * the appropriate client via the client callback function. An interrupt notifies
143 * the sending core that the receiver is finished. In this way a single pipe can
144 * manage arbitrary data transfers between cores with data flowing in either
145 * direction.
146 *
147 * \image html ipc_ints.png
148 *
149 * The application can use semaphores to control access to shared resources, as
150 * required by the application's logic.
151 *
152 * The PDL provides specific files that set up default IPC functionality.
153 * They are system_psoc6.h, system_psoc6_cm0plus.c and system_psoc6_cm4.c. You
154 * can modify these files based on the requirements of your design.
155 * If you use PSoC Creator as a development environment, it will not overwrite
156 * your changes when you generate the application or build your code.
157 *
158 * BTSS provides dedicated communication channels for communication between
159 * MCU and the BT SS. APIs provided handle exchange of Host Controller Interface (HCI)
160 * and High Priority Controller (HPC) packets
161 * using 4 dedicated IPC channels. Two dedicated Up Link (UL) channels, one for HCI
162 * and another for HPC from MCU to BT SS and two dedicated Down Link (DL) channels,
163 * one for HCI and another for HPC from BT SS to MCU are used.
164 *
165 * \section group_ipc_pipe_layer PIPE layer
166 *
167 * A pipe is a communication channel between two endpoints. PSoC 6 devices support
168 * 16 IPC channels, and 16 IPC interrupts, each numbered 0-15. IPC Channels 0-7
169 * and IPC interrupts 0-7 are reserved for system use. Channels 8-15 and
170 * interrupts 8-15 are available for application use.
171 *
172 * A full duplex pipe uses two IPC channels, one per endpoint. Each endpoint
173 * specifies all the information required to process a message (either sent or
174 * received). Each endpoint is configured to use an IPC channel, and an IPC
175 * interrupt. Common practice is to use the interrupt with the same number as
176 * the IPC channel. However, IPC Interrupts are not directly associated with the
177 * IPC channels, so any channel can use any interrupt.  Any IPC channel can
178 * trigger 0, 1 or all the IPC interrupts at once, depending on the Notify or
179 * Release masks used.
180 *
181 * It is also possible to set up a one-directional pipe, using a single IPC
182 * channel. In this design one processor is always the sender, and the other is
183 * always the receiver. However, there are still two endpoints.
184 *
185 * A pipe supports an arbitrary number of clients with an array of callback
186 * functions, one per client. The client ID is the index number into the array
187 * for the client. After a pipe is configured and initialized, the application
188 * calls Cy_IPC_Pipe_RegisterCallback() once per client to register each client's
189 * callback function. Multiple clients can use the same callback function. The
190 * endpoints in a pipe share the callback array.
191 *
192 * Use Cy_IPC_Pipe_SendMessage() to send data. You specify both the "to" and
193 * "from" endpoints, and a callback function to be used when the data transfer is
194 * complete. The data is a 32-bit void pointer. The data pointed to is arbitrary,
195 * and can be an array, a structure, or a location in memory. The only limitation
196 * is that the first element of the data must be a 32-bit unsigned word containing
197 * a client ID number. The ID number is the index into the callback array.
198 *
199 * When a message is sent, the receiving endpoint's interrupt handler is called.
200 * The ISR can perform any task required by the design. However, as part of its
201 * function it calls \ref Cy_IPC_Pipe_ExecCallback. This function retrieves the
202 * client ID from the data and calls the associated callback function.
203 * The user-supplied callback function handles the data in whatever way is
204 * appropriate based on the application logic.
205 *
206 * After the callback function is returned by the receiver, it invokes the release
207 * callback function defined by the sender of the message.
208 *
209 * \section group_ipc_sema_layer SEMA Layer
210 *
211 * A semaphore is a flag the application uses to control access to a shared
212 * resource. The SEMA-level API uses an IPC channel to implement
213 * semaphores. Startup code sets up a default semaphore system. The
214 * default system creates an array of 128 semaphores (four 32-bit values).
215 * Semaphores 0-15 are reserved for system use. See
216 * Configuration Considerations - SEMA.
217 *
218 * Functions are available to initialize the semaphore system, to set or
219 * clear a semaphore, or to get the semaphore's current status. Application
220 * logic uses SEMA functions to relate a particular semaphore to a particular
221 * shared resource, and set, clear, or check the flag when accessing the
222 * shared resource.
223 *
224 * \section group_ipc_bt_layer BTSS layer
225 *
226 * A Bluetooth Sub-system (BTSS) layer is a communication channel between the MCU and the BT
227 * Sub-system. It uses 4 IPC channels and 2 interrupts. 2 UL channels (one for HCI and HPC each)
228 * and 2 DL channels (one for HCI and HPC each). IPC interrupt 0 is used to interrupt the
229 * BT SS and IPC interrupt 1 is used to interrupt the MCU.
230 * IPC channels 0 is used for HCI UL, channel 1 is used from HCI DL,
231 * IPC channels 2 is used for HPC UL, and channel 3 is used from HPC DL.
232 * The IPC interrupt gets triggered for both Notify and Release channel.
233 * Bluetooth stack interface layer registers a callback function for notification
234 * when BT SS sends an HCI packet. It also provides APIs to read the
235 * HCI packets from the BT SS. On the UL path, it supports APIs to send HCI packet
236 * from MCU to BT SS.
237 *
238 * The communication is made more efficient by eliminating the need for buffers
239 * by packing them into the DATA0 and DATA1 IPC channel registers when payload
240 * length is less than or equal to 7 bytes. In case the where the payload length
241 * is greater than 7 bytes, it would use the shared memory to send/receive the packet.
242 *
243 * This layer support control message communication between the MCU and the BT SS
244 * using the HPC channels. The HPC channel is used for power management,
245 * IO configuration, access for TRNG, etc. APIs are provided to send HPC packets to the
246 * BT SS. It also supports APIs to register the callback function to get notification on receiving
247 * the HPC packets from the BT SS. Multiple modules running on the MCU can register
248 * callback functions. Maximum number of HPC callbacks supported is decided by
249 * the MAX_BT_IPC_HPC_CB macro. All the shared buffer management mechanism
250 * is built into this layer.
251 * \note All the HCI APIs are intended to be called by the stack interface layer and
252 * not meant to be called by the application developers.
253 *
254 * \section group_ipc_configuration_cypipe Configuration Considerations - CYPIPE
255 *
256 * There are none. The startup files set up the required CYPIPE for system
257 * use. Do not modify the CYPIPE. It uses IPC channels 5 and 6 to implement full
258 * duplex communication between cores. See System Interrupt (SysInt) for background.
259 *
260 * To create your own pipe (<b>USRPIPE</b>) you should edit startup files
261 * and take 4 steps:
262 *   -# Define a pipe callbacks processing interrupt handler
263 *      (similar to <b>Cy_SysIpcPipeIsrCm0</b> or <b>Cy_SysIpcPipeIsrCm4</b>)
264 *   -# Define a callbacks array (similar to <b>systemIpcPipeSysCbArray</b>)
265 *   -# Define your pipe configuration with a cy_stc_ipc_pipe_config_t type structure
266 *      (similar to <b>systemIpcPipeConfigCm0</b> and <b>systemIpcPipeConfigCm4</b>)
267 *   -# Call Cy_IPC_Pipe_Init() from each core to initialize your pipe (similar
268 *      to call in the <b>SystemInit</b>)
269 *
270 * \section group_ipc_configuration_sema Configuration Considerations - SEMA
271 *
272 * Startup code calls Cy_IPC_Sema_Init() with default values to set up semaphore
273 * functionality. By default, the semaphore system uses IPC channel 4, and
274 * creates 128 semaphores. Do <b>not</b> change the IPC channel.
275 * You can change the number of semaphores.
276 *
277 * To change the number of semaphores, modify this line of code in system_psoc6.h.
278 *
279 * \code
280 * #define CY_IPC_SEMA_COUNT               (uint32_t)(128u)
281 * \endcode
282 *
283 * Startup also declares array ipcSemaArray to hold the semaphore
284 * flags based on the size defined for this symbol. Use increments of 32. You
285 * must have at least 32 semaphores. Semaphores 0-15 are reserved for
286 * system use. Your application can use semaphores greater than 15.
287 *
288 * \section group_ipc_configuration_btss Configuration Considerations - BTSS
289 *
290 * Application code calls Cy_BTIPC_Init() with configuration parameters to set up BTSS IPC
291 * functionality. By default, the BT IPC uses IPC channel 0,1,2 and 3.
292 * Do <b>not</b> change the IPC channel.
293 *
294 * To change the number of callbacks supported, modify this line of code in cy_ipc_bt.h.
295 *
296 * \code
297 * #define MAX_BT_IPC_HPC_CB           5
298 * \endcode
299 *
300 * To change the count of maximum number of buffers shared by BT SS,
301 * modify this line of code in cy_ipc_bt.h.
302 *
303 * \code
304 * #define MAX_BUF_COUNT               10
305 * \endcode
306 *
307 * \section group_ipc_more_information More Information
308 *
309 * If the default startup file is not used, or SystemInit() is not called in your
310 * project, call the following three functions prior to executing any flash or
311 * EmEEPROM write or erase operation:
312 *  -# Cy_IPC_Sema_Init()
313 *  -# Cy_IPC_Pipe_Config()
314 *  -# Cy_IPC_Pipe_Init()
315 *  -# Cy_Flash_Init()
316 *
317 * See the technical reference manual(TRM) for more information on the IPC.
318 *
319 * \section group_ipc_changelog Changelog
320 *
321 * <table class="doxtable">
322 *   <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
323 *   <tr>
324 *     <td>1.91</td>
325 *     <td>Updated \ref Cy_IPC_Sema_Set, \ref Cy_IPC_Sema_Clear, \ref Cy_IPC_Sema_Status, \ref Cy_IPC_Sema_GetMaxSems APIs
326 *      \n Added new macros</td>
327 *     <td>Support for CAT1D devices added.</td>
328 *   </tr>
329 *   <tr>
330 *     <td rowspan="2">1.90</td>
331 *     <td>Added structure \ref cy_stc_ipc_msg_inrush_mode_t and enum \ref cy_en_btipc_inrush_mode_t, Modified enums \ref cy_en_btipc_lpo_cmd_t
332 *         and \ref cy_en_btipc_hpcpti_t.</td>
333 *     <td>Support for inrush mode selection for CAT1B.</td>
334 *   </tr>
335 *   <tr>
336 *     <td> Added structure \ref cy_stc_ipc_pipe_ep_config_mask_t and \ref Cy_IPC_Pipe_EndpointInitExt API.</td>
337 *     <td> Support for multiple instance of IPC IPs for CAT1D.</td>
338 *   </tr>
339 *   <tr>
340 *     <td>1.80</td>
341 *     <td>
342 *         <ul>
343 *         <li>Defined CY_IPC_CHAN_SYSCALL macro and handled caches for CM7 device.<br>
344 *         <li>Other than CAT1A devices, pipe config structure \ref cy_stc_ipc_pipe_config_t description is changed.
345 *         ep0ConfigData is used for receiver endpoint and ep1ConfigData is used for send endpoint.
346 *         For CAT1A devices, ep0ConfigData is always used for first endpoint(CM0+) and ep1ConfigData is always used for second endpoint(CM4).<br>
347 *         <li>Updated argument name of Cy_IPC_Drv_SetInterruptMask(),
348 *             Cy_IPC_Drv_SetInterrupt() and Cy_IPC_Drv_ClearInterrupt() for better
349 *             user readability.<br>
350 *         <li>Added multiple IPs support.<br>
351 *         <li>Removed standard c library functions from cy_ipc_sema.c.</td>
352 *         </ul>
353 *     <td>
354 *         <ul>
355 *         <li>Added support for CM7.<br>
356 *         <li>Enhancement based on usability/efficiency.<br>
357 *         <li>To support multiple IPC IP instances.<br>
358 *         <li>Code cleanup.</td>
359 *         </ul>
360 *   <tr>
361 *     <td rowspan="1">1.70</td>
362 *     <td>Added BT IPC service layer.</td>
363 *     <td>To support communication between MCU and BTSS through IPC.</td>
364 *   </tr>
365 *   <tr>
366 *     <td >1.60</td>
367 *     <td>Added new APIs to use DATA0 and DATA1 for short messages.</td>
368 *     <td>Enhancement based on usability/efficiency.</td>
369 *   </tr>
370 *   <tr>
371 *     <td rowspan="2">1.50</td>
372 *     <td>Updated attribute usage for the linker section placement.</td>
373 *     <td>Enhancement based on usability feedback.</td>
374 *   </tr>
375 *   <tr>
376 *     <td>Fixed MISRA 2012 violations.</td>
377 *     <td>MISRA 2012 compliance.</td>
378 *   </tr>
379 *   <tr>
380 *     <td>1.40.2</td>
381 *     <td>Updated information about IPC resources reserved for the system usage
382 *         in \ref group_ipc_pipe_layer section.
383 *     </td>
384 *     <td>Documentation enhancement.</td>
385 *   </tr>
386 *   <tr>
387 *     <td>1.40.1</td>
388 *     <td>Minor documentation updates.</td>
389 *     <td>Documentation enhancement.</td>
390 *   </tr>
391 *   <tr>
392 *     <td rowspan="1">1.40</td>
393 *     <td>Moved cy_semaData structure to the RAM section called ".cy_sharedmem".</td>
394 *     <td>Support Secure Boot devices.</td>
395 *   </tr>
396 *   <tr>
397 *     <td rowspan="3">1.30</td>
398 *     <td>Flattened the organization of the driver source code into the single source directory and the single include directory.</td>
399 *     <td>Driver library directory-structure simplification.</td>
400 *   </tr>
401 *   <tr>
402 *     <td>Moved the Cy_IPC_SystemSemaInit(), Cy_IPC_SystemPipeInit() functions implementation from IPC to Startup, removed cy_ipc_config.c and cy_ipc_config.h files.</td>
403 *     <td>Changed IPC driver configuration method from compile time to run time.</td>
404 *   </tr>
405 *   <tr>
406 *     <td>Added register access layer. Use register access macros instead
407 *         of direct register access using dereferenced pointers.</td>
408 *     <td>Makes register access device-independent, so that the PDL does
409 *         not need to be recompiled for each supported part number.</td>
410 *   </tr>
411 *   <tr>
412 *     <td>1.20</td>
413 *     <td>Added \ref Cy_IPC_Pipe_ExecuteCallback function.
414 *         Updated documentation about user pipe initialization.
415 *     </td>
416 *     <td>Interface improvement, documentation update</td>
417 *   </tr>
418 *   <tr>
419 *     <td>1.10.1</td>
420 *     <td>Updated description of the \ref Cy_IPC_Pipe_Init,
421 *         \ref Cy_IPC_Pipe_EndpointInit, \ref Cy_IPC_Sema_Set functions.
422 *         Added / updated code snippets.
423 *     </td>
424 *     <td>Documentation update and clarification</td>
425 *   </tr>
426 *   <tr>
427 *     <td>1.10</td>
428 *     <td>Added support for more IPC structures</td>
429 *     <td>New device support</td>
430 *   </tr>
431 *   <tr>
432 *     <td>1.0</td>
433 *     <td>Initial version</td>
434 *     <td></td>
435 *   </tr>
436 * </table>
437 *
438 * \defgroup group_ipc_drv IPC driver layer (IPC_DRV)
439 * \{
440 *   The functions of this layer are used in the higher IPC levels
441 *   (Semaphores and Pipes).
442 *   Users are not expected to call any of these IPC functions directly (cy_ipc_drv.h).
443 *   Instead include either of cy_ipc_sema.h or cy_ipc_pipe.h.
444 *   Alternatively include cy_pdl.h to get access to all functions and declarations in the PDL.
445 *
446 *   \defgroup group_ipc_macros Macros
447 *       Macro definitions are used in the driver
448 *
449 *   \defgroup group_ipc_functions Functions
450 *       Functions are used in the driver
451 *
452 *   \defgroup group_ipc_data_structures Data Structures
453 *       Data structures are used in the driver
454 *
455 *   \defgroup group_ipc_enums Enumerated Types
456 *       Enumerations are used in the driver
457 * \}
458 *
459 * \defgroup group_ipc_sema IPC semaphores layer (IPC_SEMA)
460 * \defgroup group_ipc_pipe IPC pipes layer (IPC_PIPE)
461 * \defgroup group_ipc_bt IPC Bluetooth sub-system layer (IPC_BTSS)
462 *
463 */
464 
465 
466 /******************************************************************************/
467 /* Include files                                                              */
468 /******************************************************************************/
469 
470 #include "cy_device.h"
471 
472 #if defined (CY_IP_M4CPUSS) || defined (CY_IP_MXIPC) || defined (CY_IP_M7CPUSS)
473 
474 
475 #include "cy_syslib.h"
476 #include <stddef.h>
477 
478 /*******************************************************************************
479 *   Memory model definitions
480 *******************************************************************************/
481 #if defined(__ARMCC_VERSION)
482 /** To create cross compiler compatible code, use the CY_NOINIT, CY_SECTION, CY_UNUSED, CY_ALIGN
483  * attributes at the first place of declaration/definition.
484  * For example: CY_NOINIT uint32_t noinitVar;
485  */
486     #define CY_IPC_SECTION_BEGIN    __attribute__ ((section(".text.cy_ipc")))
487     #define CY_IPC_SECTION_END
488 #elif defined (__GNUC__)
489     #if defined (__clang__)
490         #define CY_IPC_SECTION_BEGIN    __attribute__ ((section("__DATA, .text.cy_ipc")))
491         #define CY_IPC_SECTION_END
492     #else
493         #define CY_IPC_SECTION_BEGIN    __attribute__ ((section(".text.cy_ipc")))
494         #define CY_IPC_SECTION_END
495     #endif
496 
497 #elif defined (__ICCARM__)
498     #define CY_IPC_SECTION_BEGIN    _Pragma("default_function_attributes = @\".text.cy_ipc\"")
499     #define CY_IPC_SECTION_END      _Pragma("default_function_attributes = ")
500 #else // if defined(__ARMCC_VERSION)
501     #error "An unsupported toolchain"
502 #endif // (__ARMCC_VERSION)
503 
504 
505 /**
506 * \addtogroup group_ipc_macros
507 * \{
508 */
509 
510 /** Driver major version */
511 #define CY_IPC_DRV_VERSION_MAJOR       1
512 
513 /** Driver minor version */
514 #define CY_IPC_DRV_VERSION_MINOR       91
515 
516 /** Defines a value to indicate that no notification events are needed */
517 #define CY_IPC_NO_NOTIFICATION         (uint32_t)(0x00000000UL)
518 
519 /* Error Code constants */
520 #define CY_IPC_ID CY_PDL_DRV_ID(0x22u)  /**< Software PDL driver ID for IPC */
521 
522 /** Return prefix for IPC driver function status codes */
523 #define CY_IPC_ID_INFO    (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_INFO )
524 /** Return prefix for IPC driver function warning return values */
525 #define CY_IPC_ID_WARNING (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_WARNING)
526 /** Return prefix for IPC driver function error return values */
527 #define CY_IPC_ID_ERROR   (uint32_t)( CY_IPC_ID | CY_PDL_STATUS_ERROR)
528 
529 /** Converts the IPC interrupt channel number to interrupt vector */
530 #define CY_IPC_INTR_NUM_TO_VECT(x)         ((int32_t) cy_device->cpussIpc0Irq + (x))
531 
532 /** \} group_ipc_macros */
533 
534 /* end of definition in device.h */
535 
536 /** \cond INTERNAL */
537 #if (CY_CPU_CORTEX_M0P)
538     #define CY_IPC_CHAN_SYSCALL         CY_IPC_CHAN_SYSCALL_CM0
539 #elif (defined (CY_CPU_CORTEX_M7) && CY_CPU_CORTEX_M7) && (defined (CY_IP_M7CPUSS)) /* CM7 */
540     #define CY_IPC_CHAN_SYSCALL         ((CY_IS_CM7_CORE_0) ? CY_IPC_CHAN_SYSCALL_CM7_0 : CY_IPC_CHAN_SYSCALL_CM7_1)
541 #else
542     #define CY_IPC_CHAN_SYSCALL         CY_IPC_CHAN_SYSCALL_CM4
543 #endif  /* (CY_CPU_CORTEX_M0P) */
544 /** \endcond */
545 
546 /**
547 * \addtogroup group_ipc_enums
548 * \{
549 */
550 
551 /**
552 * This is a list of ENUMs used for function return status.
553 */
554 typedef enum
555 {
556     /** Function was successfully executed */
557     CY_IPC_DRV_SUCCESS      = (0x00U),
558     /** Function was not executed due to an error.
559         Typical conditions for the error explained
560         in the function description */
561     CY_IPC_DRV_ERROR        = ( CY_IPC_ID_ERROR + 1UL),
562 } cy_en_ipcdrv_status_t;
563 
564 /** \} group_ipc_enums */
565 
566 
567 #ifdef __cplusplus
568 extern "C" {
569 #endif
570 
571 /** \cond INTERNAL */
572 
573 __STATIC_INLINE void     Cy_IPC_Drv_WriteDataValue (IPC_STRUCT_Type* base, uint32_t dataValue);
574 __STATIC_INLINE uint32_t Cy_IPC_Drv_ReadDataValue (IPC_STRUCT_Type const * base);
575 
576 __STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractAcquireMask (uint32_t intMask);
577 __STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractReleaseMask (uint32_t intMask);
578 
579 /** \endcond */
580 
581 /**
582 * \addtogroup group_ipc_functions
583 * \{
584 */
585 
586 __STATIC_INLINE IPC_STRUCT_Type*       Cy_IPC_Drv_GetIpcBaseAddress (uint32_t ipcIndex);
587 __STATIC_INLINE IPC_INTR_STRUCT_Type*  Cy_IPC_Drv_GetIntrBaseAddr (uint32_t ipcIntrIndex);
588 
589 __STATIC_INLINE void     Cy_IPC_Drv_AcquireNotify (IPC_STRUCT_Type * base, uint32_t notifyEventIntr);
590 __STATIC_INLINE void     Cy_IPC_Drv_ReleaseNotify (IPC_STRUCT_Type * base, uint32_t notifyEventIntr);
591 
592 __STATIC_INLINE  cy_en_ipcdrv_status_t Cy_IPC_Drv_LockAcquire (IPC_STRUCT_Type const * base);
593 cy_en_ipcdrv_status_t    Cy_IPC_Drv_LockRelease (IPC_STRUCT_Type * base, uint32_t releaseEventIntr);
594 __STATIC_INLINE bool     Cy_IPC_Drv_IsLockAcquired (IPC_STRUCT_Type const * base);
595 __STATIC_INLINE uint32_t Cy_IPC_Drv_GetLockStatus (IPC_STRUCT_Type const * base);
596 
597 cy_en_ipcdrv_status_t    Cy_IPC_Drv_SendMsgWord (IPC_STRUCT_Type * base, uint32_t notifyEventIntr, uint32_t message);
598 cy_en_ipcdrv_status_t    Cy_IPC_Drv_ReadMsgWord (IPC_STRUCT_Type const * base, uint32_t * message);
599 
600 #if (defined (CY_IP_M33SYSCPUSS_VERSION) || defined (CY_IP_M7CPUSS) || (defined (CY_IP_M4CPUSS) && (CY_IP_M4CPUSS_VERSION > 1))) || defined (CY_DOXYGEN)
601 cy_en_ipcdrv_status_t    Cy_IPC_Drv_SendMsgDWord (IPC_STRUCT_Type * base, uint32_t notifyEventIntr, uint32_t* message);
602 cy_en_ipcdrv_status_t    Cy_IPC_Drv_ReadMsgDWord (IPC_STRUCT_Type const * base, uint32_t* message);
603 #endif /* CY_IP_M4CPUSS, CY_IP_M4CPUSS_VERSION, CY_IP_M33SYSCPUSS_VERSION  CY_IP_M7CPUSS*/
604 
605 __STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgPtr (IPC_STRUCT_Type* base, uint32_t notifyEventIntr, void const * msgPtr);
606 __STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgPtr (IPC_STRUCT_Type const * base, void ** msgPtr);
607 
608 __STATIC_INLINE void     Cy_IPC_Drv_SetInterruptMask (IPC_INTR_STRUCT_Type * base,
609                                                       uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
610 __STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptMask (IPC_INTR_STRUCT_Type const * base);
611 __STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatusMasked (IPC_INTR_STRUCT_Type const * base);
612 __STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatus (IPC_INTR_STRUCT_Type const * base);
613 __STATIC_INLINE void     Cy_IPC_Drv_SetInterrupt (IPC_INTR_STRUCT_Type * base,
614                                                       uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
615 __STATIC_INLINE void     Cy_IPC_Drv_ClearInterrupt (IPC_INTR_STRUCT_Type * base,
616                                                       uint32_t ipcReleaseMask, uint32_t ipcNotifyMask);
617 
618 
619 /*******************************************************************************
620 * Function Name: Cy_IPC_Drv_GetIpcBaseAddress
621 ****************************************************************************//**
622 *
623 * This function takes an IPC channel index as a parameter and returns the base
624 * address the IPC registers corresponding to the IPC channel.
625 *
626 * \note The user is responsible for ensuring that ipcIndex does not exceed the
627 * limits.
628 *
629 * \param ipcIndex
630 * Represents the number of IPC structure. This is converted to the base address of
631 * the IPC channel registers. This comprises of total number of channels present in
632 * all IPC IP instances.
633 *
634 * \return
635 * Returns a pointer to the base of the IPC registers.
636 *
637 * \funcusage
638 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_SendMsgWord
639 *
640 *******************************************************************************/
Cy_IPC_Drv_GetIpcBaseAddress(uint32_t ipcIndex)641 __STATIC_INLINE IPC_STRUCT_Type* Cy_IPC_Drv_GetIpcBaseAddress (uint32_t ipcIndex)
642 {
643     CY_ASSERT_L1(CY_IPC_CHANNELS > ipcIndex);
644     return ( (IPC_STRUCT_Type*) CY_IPC_STRUCT_PTR(ipcIndex));
645 }
646 
647 
648 /*******************************************************************************
649 * Function Name: Cy_IPC_Drv_GetIntrBaseAddr
650 ****************************************************************************//**
651 *
652 * This function takes an IPC interrupt structure index and returns the base
653 * address of the IPC interrupt registers corresponding to the IPC Interrupt.
654 *
655 * \note The user is responsible for ensuring that ipcIntrIndex does not exceed the
656 * limits.
657 *
658 * \param ipcIntrIndex
659 * Represents the number of IPC interrupt structure. This is converted to the
660 * base address of the IPC interrupt registers. This comprises of total number
661 * of channels present in all IPC IP instances.
662 *
663 * \return
664 * Returns a pointer to the base of the IPC interrupt registers.
665 *
666 * \funcusage
667 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_GetInterruptStatus
668 *
669 *******************************************************************************/
Cy_IPC_Drv_GetIntrBaseAddr(uint32_t ipcIntrIndex)670 __STATIC_INLINE IPC_INTR_STRUCT_Type* Cy_IPC_Drv_GetIntrBaseAddr (uint32_t ipcIntrIndex)
671 {
672     CY_ASSERT_L1(CY_IPC_INTERRUPTS > ipcIntrIndex);
673     return ( (IPC_INTR_STRUCT_Type*) CY_IPC_INTR_STRUCT_PTR(ipcIntrIndex));
674 }
675 
676 
677 /*******************************************************************************
678 * Function Name: Cy_IPC_Drv_SetInterruptMask
679 ****************************************************************************//**
680 *
681 * This function is used to set the interrupt mask for an IPC Interrupt.
682 * The mask sets release or acquire notification events for all IPC channels.
683 *
684 * \param base
685 * This is a handle to the IPC interrupt. This handle can be calculated from the
686 * IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
687 *
688 * \param ipcReleaseMask
689 * An encoded list of all IPC channels that can trigger the interrupt on a
690 * release event. In case of devices having multiple IPC IP instances, this
691 * comprises of total number of channels present in only particular IPC IP.
692 *
693 * \param ipcNotifyMask
694 * An encoded list of all IPC channels that can trigger the interrupt on a
695 * notify event. In case of devices having multiple IPC IP instances, this
696 * comprises of total number of channels present in only particular IPC IP.
697 *
698 * \funcusage
699 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_GetInterruptStatusMasked
700 *
701 *******************************************************************************/
Cy_IPC_Drv_SetInterruptMask(IPC_INTR_STRUCT_Type * base,uint32_t ipcReleaseMask,uint32_t ipcNotifyMask)702 __STATIC_INLINE void  Cy_IPC_Drv_SetInterruptMask (IPC_INTR_STRUCT_Type* base,
703                                               uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
704 {
705     CY_ASSERT_L1(0UL == (ipcNotifyMask & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
706     CY_ASSERT_L1(0UL == (ipcReleaseMask & ~(uint32_t)(IPC_STRUCT_RELEASE_INTR_RELEASE_Msk)));
707     REG_IPC_INTR_STRUCT_INTR_MASK(base) = _VAL2FLD( IPC_INTR_STRUCT_INTR_MASK_NOTIFY,  ipcNotifyMask) |
708                       _VAL2FLD( IPC_INTR_STRUCT_INTR_MASK_RELEASE, ipcReleaseMask);
709 }
710 
711 
712 /*******************************************************************************
713 * Function Name: Cy_IPC_Drv_GetInterruptMask
714 ****************************************************************************//**
715 *
716 * This function is used to read the interrupt mask.
717 *
718 * \param base
719 * This is a handle to the IPC interrupt. This handle can be calculated from
720 * the IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
721 *
722 * \return
723 * In case of devices having multiple IPC IP instances, this
724 * comprises of total number of channels present in only particular IPC IP.
725 *   The return value is encoded as follows
726 *   <table>
727 *   <tr><th>Interrupt sources   <th>Value
728 *   <tr><td>Ipc_PORTX_RELEASE   <td>Xth bit set
729 *   <tr><td>Ipc_PORTX_NOTIFY    <td>X+16th bit set
730 *   </table>
731 *
732 * \funcusage
733 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_GetInterruptStatusMasked
734 *
735 *******************************************************************************/
Cy_IPC_Drv_GetInterruptMask(IPC_INTR_STRUCT_Type const * base)736 __STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptMask(IPC_INTR_STRUCT_Type const * base)
737 {
738     return REG_IPC_INTR_STRUCT_INTR_MASK(base);
739 }
740 
741 
742 /*******************************************************************************
743 * Function Name: Cy_IPC_Drv_GetInterruptStatusMasked
744 ****************************************************************************//**
745 *
746 * This function is used to read the active unmasked interrupt. This function
747 * can be used in the interrupt service routine to find which source triggered
748 * the interrupt.
749 *
750 * \param base
751 * This is a handle to the IPC interrupt. This handle can be calculated from the
752 * IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
753 *
754 * \return
755 * In case of devices having multiple IPC IP instances, this
756 * comprises of total number of channels present in only particular IPC IP.
757 *   The return value is encoded as follows
758 *   <table>
759 *   <tr><th>Interrupt sources   <th>Value
760 *   <tr><td>Ipc_PORTX_RELEASE   <td>Xth bit set
761 *   <tr><td>Ipc_PORTX_NOTIFY    <td>X+16th bit set
762 *   </table>
763 *
764 * \funcusage
765 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_GetInterruptStatusMasked
766 *
767 *******************************************************************************/
Cy_IPC_Drv_GetInterruptStatusMasked(IPC_INTR_STRUCT_Type const * base)768 __STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatusMasked (IPC_INTR_STRUCT_Type const * base)
769 {
770     return REG_IPC_INTR_STRUCT_INTR_MASKED(base);
771 }
772 
773 
774 /*******************************************************************************
775 * Function Name: Cy_IPC_Drv_GetInterruptStatus
776 ****************************************************************************//**
777 *
778 * This function is used to read the pending interrupts. Note that this read is
779 * an unmasked read of the interrupt status. Interrupt sources read as active by
780 * this function would generate interrupts only if they were not masked.
781 *
782 * \param base
783 * This is a handle to the IPC interrupt. This handle can be calculated from the
784 * IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
785 *
786 * \return
787 * In case of devices having multiple IPC IP instances, this
788 * comprises of total number of channels present in only particular IPC IP.
789 *   The return value is encoded as follows
790 *   <table>
791 *   <tr><th>Interrupt sources   <th>Value
792 *   <tr><td>Ipc_PORTX_RELEASE   <td>Xth bit set
793 *   <tr><td>Ipc_PORTX_NOTIFY    <td>X+16th bit set
794 *   </table>
795 *
796 * \funcusage
797 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_GetInterruptStatus
798 *
799 *******************************************************************************/
Cy_IPC_Drv_GetInterruptStatus(IPC_INTR_STRUCT_Type const * base)800 __STATIC_INLINE uint32_t Cy_IPC_Drv_GetInterruptStatus(IPC_INTR_STRUCT_Type const * base)
801 {
802     return REG_IPC_INTR_STRUCT_INTR(base);
803 }
804 
805 
806 /*******************************************************************************
807 * Function Name: Cy_IPC_Drv_SetInterrupt
808 ****************************************************************************//**
809 *
810 * This function is used to set the interrupt source. This function can be used
811 * to activate interrupts through software.
812 * \note That interrupt sources set using this interrupt would generate interrupts
813 * only if they are not masked.
814 *
815 * \param base
816 * This is a handle to the IPC interrupt. This handle can be calculated from the
817 * IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
818 *
819 * \param ipcReleaseMask
820 * An encoded list of all IPC channels that can trigger the interrupt on a
821 * release event. In case of devices having multiple IPC IP instances, this
822 * comprises of total number of channels present in only particular IPC IP.
823 *
824 * \param ipcNotifyMask
825 * An encoded list of all IPC channels that can trigger the interrupt on a
826 * notify event. In case of devices having multiple IPC IP instances, this
827 * comprises of total number of channels present in only particular IPC IP.
828 *
829 * \funcusage
830 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_SetInterrupt
831 *
832 *******************************************************************************/
Cy_IPC_Drv_SetInterrupt(IPC_INTR_STRUCT_Type * base,uint32_t ipcReleaseMask,uint32_t ipcNotifyMask)833 __STATIC_INLINE void  Cy_IPC_Drv_SetInterrupt(IPC_INTR_STRUCT_Type* base, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
834 {
835     CY_ASSERT_L1(0UL == (ipcNotifyMask  & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
836     CY_ASSERT_L1(0UL == (ipcReleaseMask & ~(uint32_t)(IPC_STRUCT_RELEASE_INTR_RELEASE_Msk)));
837     REG_IPC_INTR_STRUCT_INTR_SET(base) =  _VAL2FLD( IPC_INTR_STRUCT_INTR_NOTIFY,  ipcNotifyMask )  |
838                       _VAL2FLD( IPC_INTR_STRUCT_INTR_RELEASE, ipcReleaseMask );
839 }
840 
841 
842 /*******************************************************************************
843 * Function Name: Cy_IPC_Drv_ClearInterrupt
844 ****************************************************************************//**
845 *
846 * This function is used to clear the interrupt source. Use this function to clear
847 * a pending interrupt source in the interrupt status.
848 *
849 * \param base
850 * This is a handle to the IPC interrupt. This handle can be calculated from the
851 * IPC interrupt number using \ref Cy_IPC_Drv_GetIntrBaseAddr.
852 *
853 * \param ipcReleaseMask
854 * An encoded list of all IPC channels that can trigger the interrupt on a
855 * release event. In case of devices having multiple IPC IP instances, this
856 * comprises of total number of channels present in only particular IPC IP.
857 *
858 * \param ipcNotifyMask
859 * An encoded list of all IPC channels that can trigger the interrupt on a
860 * notify event. In case of devices having multiple IPC IP instances, this
861 * comprises of total number of channels present in only particular IPC IP.
862 *
863 * \funcusage
864 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_GetInterruptStatusMasked
865 *
866 *******************************************************************************/
Cy_IPC_Drv_ClearInterrupt(IPC_INTR_STRUCT_Type * base,uint32_t ipcReleaseMask,uint32_t ipcNotifyMask)867 __STATIC_INLINE void  Cy_IPC_Drv_ClearInterrupt(IPC_INTR_STRUCT_Type* base, uint32_t ipcReleaseMask, uint32_t ipcNotifyMask)
868 {
869     CY_ASSERT_L1(0UL == (ipcNotifyMask  & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
870     CY_ASSERT_L1(0UL == (ipcReleaseMask & ~(uint32_t)(IPC_STRUCT_RELEASE_INTR_RELEASE_Msk)));
871     REG_IPC_INTR_STRUCT_INTR(base) =  _VAL2FLD(IPC_INTR_STRUCT_INTR_NOTIFY,  ipcNotifyMask) |
872                   _VAL2FLD(IPC_INTR_STRUCT_INTR_RELEASE, ipcReleaseMask);
873     /* This dummy reading is necessary here. It provides a guarantee that interrupt is cleared at returning from this function. */
874     (void)REG_IPC_INTR_STRUCT_INTR(base);
875 }
876 
877 /** \} group_ipc_functions */
878 
879 /** \} group_ipc */
880 
881 
882 /*******************************************************************************
883 * Function Name: Cy_IPC_Drv_AcquireNotify
884 ****************************************************************************//**
885 *
886 * The function generates a acquire notification event by IPC interrupt structure.
887 *
888 * \param base
889 * This parameter is a handle that represents the base address of the registers
890 * of the IPC channel.
891 * The parameter is generally returned from a call to the \ref
892 * Cy_IPC_Drv_GetIpcBaseAddress.
893 *
894 * \param notifyEventIntr
895 * Bit encoded list of IPC interrupt structures that are triggered
896 * by a notification. Bit number correspond to number of the IPC interrupt
897 * structure. In case of devices having multiple IPC IP instances, this
898 * comprises of all IPC interrupts associated with only particular IPC IP.
899 *
900 * \funcusage
901 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_LockAcquire
902 *
903 *******************************************************************************/
Cy_IPC_Drv_AcquireNotify(IPC_STRUCT_Type * base,uint32_t notifyEventIntr)904 __STATIC_INLINE void  Cy_IPC_Drv_AcquireNotify (IPC_STRUCT_Type* base, uint32_t notifyEventIntr)
905 {
906     CY_ASSERT_L1(0UL == (notifyEventIntr  & ~(uint32_t)(IPC_STRUCT_NOTIFY_INTR_NOTIFY_Msk)));
907     REG_IPC_STRUCT_NOTIFY(base) = _VAL2FLD(IPC_STRUCT_NOTIFY_INTR_NOTIFY, notifyEventIntr);
908 }
909 
910 
911 /*******************************************************************************
912 * Function Name: Cy_IPC_Drv_ReleaseNotify
913 ****************************************************************************//**
914 *
915 * The function generates a release notification event by IPC interrupt structure.
916 *
917 * \param base
918 * This parameter is a handle that represents the base address of the registers
919 * of the IPC channel.
920 * The parameter is generally returned from a call to the \ref
921 * Cy_IPC_Drv_GetIpcBaseAddress.
922 *
923 * \param notifyEventIntr
924 * Bit encoded list of IPC interrupt lines that are triggered by a notification.
925 * In case of devices having multiple IPC IP instances, this comprises of all IPC
926 * interrupts associated with only particular IPC IP.
927 *
928 * \funcusage
929 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_ReadMsgWord
930 *
931 *******************************************************************************/
Cy_IPC_Drv_ReleaseNotify(IPC_STRUCT_Type * base,uint32_t notifyEventIntr)932 __STATIC_INLINE void  Cy_IPC_Drv_ReleaseNotify (IPC_STRUCT_Type* base, uint32_t notifyEventIntr)
933 {
934     CY_ASSERT_L1(0UL == (notifyEventIntr  & ~(uint32_t)(IPC_INTR_STRUCT_INTR_RELEASE_Msk)));
935     REG_IPC_STRUCT_RELEASE(base) = _VAL2FLD(IPC_INTR_STRUCT_INTR_RELEASE, notifyEventIntr);
936 }
937 
938 
939 /*******************************************************************************
940 * Function Name: Cy_IPC_Drv_WriteDataValue
941 ****************************************************************************//**
942 *
943 * The function writes a value to the DATA register of the IPC channel.
944 *
945 * This function is internal and should not be called directly by user
946 * software.
947 *
948 * \param base
949 * This parameter is a handle that represents the base address of the registers
950 * of the IPC channel.
951 * The parameter is generally returned from a call to the \ref
952 * Cy_IPC_Drv_GetIpcBaseAddress.
953 *
954 * \param dataValue
955 * Value to be written.
956 *
957 *******************************************************************************/
Cy_IPC_Drv_WriteDataValue(IPC_STRUCT_Type * base,uint32_t dataValue)958 __STATIC_INLINE void     Cy_IPC_Drv_WriteDataValue (IPC_STRUCT_Type* base, uint32_t dataValue)
959 {
960     REG_IPC_STRUCT_DATA(base) = dataValue;
961 }
962 
963 /*******************************************************************************
964 * Function Name: Cy_IPC_Drv_WriteDDataValue
965 ****************************************************************************//**
966 *
967 * The function writes two 32 bit values to the DATA registers of the IPC channel.
968 *
969 * This function is internal and should not be called directly by user
970 * software.
971 *
972 * \param base
973 * This parameter is a handle that represents the base address of the registers
974 * of the IPC channel.
975 * The parameter is generally returned from a call to the \ref
976 * Cy_IPC_Drv_GetIpcBaseAddress.
977 *
978 * \param pDataValue
979 * Value to be written.
980 *
981 *******************************************************************************/
982 #if (defined (CY_IP_M33SYSCPUSS_VERSION) || defined (CY_IP_M7CPUSS) || (defined (CY_IP_M4CPUSS) && (CY_IP_M4CPUSS_VERSION > 1)))
Cy_IPC_Drv_WriteDDataValue(IPC_STRUCT_Type * base,uint32_t * pDataValue)983 __STATIC_INLINE void Cy_IPC_Drv_WriteDDataValue (IPC_STRUCT_Type* base, uint32_t *pDataValue)
984 {
985     REG_IPC_STRUCT_DATA(base) = *pDataValue++;
986     REG_IPC_STRUCT_DATA1(base) = *pDataValue;
987 
988 }
989 #endif /* CY_IP_M4CPUSS, CY_IP_M4CPUSS_VERSION, CY_IP_M33SYSCPUSS_VERSION, CY_IP_M7CPUSS */
990 
991 /*******************************************************************************
992 * Function Name: Cy_IPC_Drv_ReadDataValue
993 ****************************************************************************//**
994 *
995 * The function reads a value from the DATA register of the IPC channel.
996 *
997 * This function is internal and should not be called directly by user
998 * software.
999 *
1000 * \param base
1001 * This parameter is a handle that represents the base address of the registers
1002 * of the IPC channel.
1003 * The parameter is generally returned from a call to the \ref
1004 * Cy_IPC_Drv_GetIpcBaseAddress.
1005 *
1006 * \return
1007 * Value from DATA register.
1008 *
1009 *******************************************************************************/
Cy_IPC_Drv_ReadDataValue(IPC_STRUCT_Type const * base)1010 __STATIC_INLINE uint32_t Cy_IPC_Drv_ReadDataValue (IPC_STRUCT_Type const * base)
1011 {
1012     return REG_IPC_STRUCT_DATA(base);
1013 }
1014 
1015 #if defined (CY_IP_M33SYSCPUSS_VERSION) || defined (CY_IP_M7CPUSS) || ( defined (CY_IP_M4CPUSS) && (CY_IP_M4CPUSS_VERSION > 1))
1016 /*******************************************************************************
1017 * Function Name: Cy_IPC_Drv_ReadDDataValue
1018 ****************************************************************************//**
1019 *
1020 * The function reads two 32-bit values from the DATA registers of the IPC channel.
1021 *
1022 * This function is internal and should not be called directly by user
1023 * software.
1024 *
1025 * \param base
1026 * This parameter is a handle that represents the base address of the registers
1027 * of the IPC channel.
1028 * The parameter is generally returned from a call to the \ref
1029 * Cy_IPC_Drv_GetIpcBaseAddress.
1030 *
1031 * \param pDataValue
1032 * Value to be written.
1033 *
1034 * \return
1035 * Value from DATA register.
1036 *
1037 *******************************************************************************/
Cy_IPC_Drv_ReadDDataValue(IPC_STRUCT_Type const * base,uint32_t * pDataValue)1038 __STATIC_INLINE void Cy_IPC_Drv_ReadDDataValue (IPC_STRUCT_Type const * base, uint32_t *pDataValue)
1039 {
1040     *pDataValue++ = REG_IPC_STRUCT_DATA(base);
1041     *pDataValue = REG_IPC_STRUCT_DATA1(base);
1042 }
1043 #endif /* CY_IP_M4CPUSS, CY_IP_M4CPUSS_VERSION, CY_IP_M33SYSCPUSS_VERSION, CY_IP_M7CPUSS */
1044 
1045 /*******************************************************************************
1046 * Function Name: Cy_IPC_Drv_IsLockAcquired
1047 ****************************************************************************//**
1048 *
1049 * The function is used to test the status of an IPC channel. The function
1050 * tells the reader if the IPC channel was in the locked or released state.
1051 *
1052 * \param base
1053 * This parameter is a handle that represents the base address of the registers
1054 * of the IPC channel.
1055 * The parameter is generally returned from a call to the \ref
1056 * Cy_IPC_Drv_GetIpcBaseAddress.
1057 *
1058 * \return
1059 *   Status for the function:
1060 *   true:  The IPC channel is in the Locked state.
1061 *   false: The IPC channel is in the Released state.
1062 *
1063 * \funcusage
1064 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_LockAcquire
1065 *
1066 *******************************************************************************/
Cy_IPC_Drv_IsLockAcquired(IPC_STRUCT_Type const * base)1067 __STATIC_INLINE bool Cy_IPC_Drv_IsLockAcquired (IPC_STRUCT_Type const * base)
1068 {
1069     return ( 0u != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_LOCK_STATUS(base)) );
1070 }
1071 
1072 
1073 /*******************************************************************************
1074 * Function Name: Cy_IPC_Drv_GetLockStatus
1075 ****************************************************************************//**
1076 *
1077 * The function is used to get the status of an IPC channel.
1078 *
1079 * \param base
1080 * This parameter is a handle that represents the base address of the registers
1081 * of the IPC channel.
1082 * The parameter is generally returned from a call to the \ref
1083 * Cy_IPC_Drv_GetIpcBaseAddress.
1084 *
1085 * \return
1086 * Value from LOCK_STATUS register.
1087 *
1088 * \funcusage
1089 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_GetLockStatus
1090 *
1091 *******************************************************************************/
Cy_IPC_Drv_GetLockStatus(IPC_STRUCT_Type const * base)1092 __STATIC_INLINE uint32_t Cy_IPC_Drv_GetLockStatus (IPC_STRUCT_Type const * base)
1093 {
1094     return REG_IPC_STRUCT_LOCK_STATUS(base);
1095 }
1096 
1097 
1098 /*******************************************************************************
1099 * Function Name: Cy_IPC_Drv_ExtractAcquireMask
1100 ****************************************************************************//**
1101 *
1102 * The function extracts an Acquire mask part from full interrupt mask value.
1103 *
1104 * This function is internal and should not be called directly by user
1105 * software.
1106 *
1107 * \param intMask
1108 * Interrupt mask value to be processed.
1109 *
1110 * \return
1111 * Acquire mask value.
1112 *
1113 *******************************************************************************/
Cy_IPC_Drv_ExtractAcquireMask(uint32_t intMask)1114 __STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractAcquireMask (uint32_t intMask)
1115 {
1116     return _FLD2VAL(IPC_INTR_STRUCT_INTR_MASK_NOTIFY, intMask);
1117 }
1118 
1119 
1120 /*******************************************************************************
1121 * Function Name: Cy_IPC_Drv_ExtractReleaseMask
1122 ****************************************************************************//**
1123 *
1124 * The function extracts a Release mask part from full interrupt mask value.
1125 *
1126 * This function is internal and should not be called directly by user
1127 * software.
1128 *
1129 * \param intMask
1130 * Interrupt mask value to be processed.
1131 *
1132 * \return
1133 * Release mask value.
1134 *
1135 *******************************************************************************/
Cy_IPC_Drv_ExtractReleaseMask(uint32_t intMask)1136 __STATIC_INLINE uint32_t Cy_IPC_Drv_ExtractReleaseMask (uint32_t intMask)
1137 {
1138     return _FLD2VAL(IPC_INTR_STRUCT_INTR_MASK_RELEASE, intMask);
1139 }
1140 
1141 
1142 /*******************************************************************************
1143 * Function Name: Cy_IPC_Drv_SendMsgPtr
1144 ****************************************************************************//**
1145 *
1146 * This function is used to send a message pointer through an IPC channel.
1147 * The message structure may hold a generic pointer that may contain the address
1148 * of any user data type or structure. This parameter could be a pointer to a 32-bit
1149 * integer, an array, or even a data structure defined in the user code. This
1150 * function acts as a transfer engine for sending the pointer. Any memory
1151 * management of the pointer allocation and deallocation is up to the application
1152 * code.
1153 * The function also has an associated notification field that will let the
1154 * message notify one or multiple interrupts.
1155 *
1156 * \param base
1157 * This parameter is a handle that represents the base address of the registers
1158 * of the IPC channel.
1159 * The parameter is generally returned from a call to the \ref
1160 * Cy_IPC_Drv_GetIpcBaseAddress.
1161 *
1162 * \param notifyEventIntr
1163 * Bit encoded list of IPC interrupt lines that are triggered during the release
1164 * action. In case of devices having multiple IPC IP instances, this comprises of
1165 * all IPC interrupts associated with only particular IPC IP.
1166 *
1167 * \param msgPtr
1168 * The message pointer that is being sent over the IPC channel.
1169 *
1170 * \return   Status of the operation:
1171 *   \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
1172 *   \retval CY_IPC_DRV_ERROR:   The IPC channel is unavailable because
1173 *                               it is already locked.
1174 *
1175 * \funcusage
1176 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_SendMsgPtr
1177 *
1178 *******************************************************************************/
Cy_IPC_Drv_SendMsgPtr(IPC_STRUCT_Type * base,uint32_t notifyEventIntr,void const * msgPtr)1179 __STATIC_INLINE cy_en_ipcdrv_status_t  Cy_IPC_Drv_SendMsgPtr(IPC_STRUCT_Type* base, uint32_t notifyEventIntr, void const * msgPtr)
1180 {
1181     CY_ASSERT_L1(NULL != msgPtr);
1182     return Cy_IPC_Drv_SendMsgWord(base, notifyEventIntr, (uint32_t)msgPtr);
1183 }
1184 
1185 
1186 /*******************************************************************************
1187 * Function Name: Cy_IPC_Drv_ReadMsgPtr
1188 ****************************************************************************//**
1189 *
1190 * This function is used to read a 32-bit pointer message through an IPC channel.
1191 *
1192 * \param base
1193 * This parameter is a handle that represents the base address of the registers
1194 * of the IPC channel.
1195 * The parameter is generally returned from a call to the \ref
1196 * Cy_IPC_Drv_GetIpcBaseAddress.
1197 *
1198 * \param msgPtr
1199 * Pointer variable to hold the data pointer that is being read from the IPC
1200 * channel.
1201 *
1202 *
1203 * \return Status of the operation
1204 *   \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
1205 *                       was acquired.
1206 *   \retval CY_IPC_DRV_ERROR:   The function encountered an error because the IPC
1207 *                       channel was already in a released state meaning the data
1208 *                       in it is invalid.
1209 *
1210 * \funcusage
1211 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_ReadMsgPtr
1212 *
1213 *******************************************************************************/
Cy_IPC_Drv_ReadMsgPtr(IPC_STRUCT_Type const * base,void ** msgPtr)1214 __STATIC_INLINE  cy_en_ipcdrv_status_t  Cy_IPC_Drv_ReadMsgPtr (IPC_STRUCT_Type const * base, void ** msgPtr)
1215 {
1216     CY_ASSERT_L1(NULL != msgPtr);
1217     return Cy_IPC_Drv_ReadMsgWord(base, (uint32_t *)msgPtr);
1218 }
1219 
1220 
1221 /*******************************************************************************
1222 * Function Name: Cy_IPC_Drv_LockAcquire
1223 ****************************************************************************//**
1224 *
1225 * This function is used to acquire the IPC channel.
1226 *
1227 * \param base
1228 * This parameter is a handle that represents the base address of the registers
1229 * of the IPC channel.
1230 * The parameter is generally returned from a call to the \ref
1231 * Cy_IPC_Drv_GetIpcBaseAddress
1232 *
1233 * \return   Status of the operation
1234 *   \retval CY_IPC_DRV_SUCCESS: The IPC was successfully acquired
1235 *   \retval CY_IPC_DRV_ERROR:   The IPC was not acquired because it was already acquired
1236 *                       by another master
1237 *
1238 * \funcusage
1239 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_LockAcquire
1240 *
1241 *******************************************************************************/
Cy_IPC_Drv_LockAcquire(IPC_STRUCT_Type const * base)1242 __STATIC_INLINE cy_en_ipcdrv_status_t Cy_IPC_Drv_LockAcquire (IPC_STRUCT_Type const * base)
1243 {
1244     return ( 0UL != _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(base))) ? CY_IPC_DRV_SUCCESS : CY_IPC_DRV_ERROR;
1245 }
1246 
1247 #ifdef __cplusplus
1248 }
1249 #endif
1250 
1251 #endif /* CY_IP_M4CPUSS  CY_IP_M7CPUSS*/
1252 
1253 #endif /* !defined (CY_IPC_DRV_H) */
1254 
1255 /* [] END OF FILE */
1256