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