1 /***************************************************************************//**
2 * \file cy_ipc_drv.c
3 * \version 1.91
4 *
5 *  \brief
6 *   IPC Driver - This source file contains the low-level driver code for
7 *   the IPC hardware.
8 *
9 ********************************************************************************
10 * Copyright 2016-2020 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *     http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 #include "cy_device.h"
27 
28 #if defined (CY_IP_M4CPUSS) || defined (CY_IP_M7CPUSS) || defined (CY_IP_MXIPC)
29 
30 #include "cy_ipc_drv.h"
31 
32 /*******************************************************************************
33 * Function Name: Cy_IPC_Drv_LockRelease
34 ****************************************************************************//**
35 *
36 * The function is used to release an IPC channel from the locked state.
37 * The function also has a way to specify through a parameter which IPC
38 * interrupts must be notified during the release event.
39 *
40 * \param base
41 * This parameter is a handle that represents the base address of the registers
42 * of the IPC channel.
43 * The parameter is generally returned from a call to the \ref
44 * Cy_IPC_Drv_GetIpcBaseAddress.
45 *
46 * \param releaseEventIntr
47 * Bit encoded list of IPC interrupt lines that are triggered by a release event.
48 * In case of devices having multiple IPC IP instances, this comprises of all IPC
49 * interrupts associated with only particular IPC IP.
50 *
51 * \return   Status of the operation
52 *   \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC channel
53 *                       was released.
54 *   \retval CY_IPC_DRV_ERROR: The IPC channel was not acquired before the
55 *                       function call.
56 *
57 * \funcusage
58 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_ReadMsgPtr
59 *
60 *******************************************************************************/
Cy_IPC_Drv_LockRelease(IPC_STRUCT_Type * base,uint32_t releaseEventIntr)61 cy_en_ipcdrv_status_t Cy_IPC_Drv_LockRelease (IPC_STRUCT_Type* base, uint32_t releaseEventIntr)
62 {
63     cy_en_ipcdrv_status_t retStatus;
64 
65     /* Check to make sure the IPC is Acquired */
66     if( Cy_IPC_Drv_IsLockAcquired(base) )
67     {
68         /* The IPC was acquired, release the IPC channel */
69         Cy_IPC_Drv_ReleaseNotify(base, releaseEventIntr);
70 
71         retStatus = CY_IPC_DRV_SUCCESS;
72     }
73     else   /* The IPC channel was already released (not acquired) */
74     {
75         retStatus = CY_IPC_DRV_ERROR;
76     }
77 
78     return (retStatus);
79 }
80 
81 
82 /*******************************************************************************
83 * Function Name: Cy_IPC_Drv_SendMsgWord
84 ****************************************************************************//**
85 *
86 * This function is used to send a 32-bit word message through an IPC channel.
87 * The function also has an associated notification field that will let the
88 * message notify one or multiple IPC interrupts. The IPC channel is locked and
89 * remains locked after the function returns.  The receiver of the message should
90 * release the channel.
91 *
92 * \param base
93 * This parameter is a handle that represents the base address of the registers
94 * of the IPC channel.
95 * The parameter is generally returned from a call to the \ref
96 * Cy_IPC_Drv_GetIpcBaseAddress.
97 *
98 * \param notifyEventIntr
99 * Bit encoded list of IPC interrupt lines that are triggered by a notification.
100 * In case of devices having multiple IPC IP instances, this comprises of all IPC
101 * interrupts associated with only particular IPC IP.
102 *
103 * \param message
104 * The message word that is the data placed in the IPC data register.
105 *
106 * \return   Status of the operation:
107 *   \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
108 *   \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because it is already locked.
109 *
110 * \funcusage
111 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_SendMsgWord
112 *
113 *******************************************************************************/
Cy_IPC_Drv_SendMsgWord(IPC_STRUCT_Type * base,uint32_t notifyEventIntr,uint32_t message)114 cy_en_ipcdrv_status_t  Cy_IPC_Drv_SendMsgWord (IPC_STRUCT_Type* base, uint32_t notifyEventIntr, uint32_t message)
115 {
116     cy_en_ipcdrv_status_t retStatus;
117 
118     if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(base) )
119     {
120         /* If the channel was acquired, send the message. */
121         Cy_IPC_Drv_WriteDataValue(base, message);
122 
123         Cy_IPC_Drv_AcquireNotify(base, notifyEventIntr);
124 
125         retStatus = CY_IPC_DRV_SUCCESS;
126     }
127     else
128     {
129         /* Channel was already acquired, return Error */
130         retStatus = CY_IPC_DRV_ERROR;
131     }
132     return (retStatus);
133 }
134 
135 
136 /*******************************************************************************
137 * Function Name: Cy_IPC_Drv_ReadMsgWord
138 ****************************************************************************//**
139 *
140 * This function is used to read a 32-bit word message through an IPC channel.
141 * This function assumes that the channel is locked (for a valid message).
142 * If the channel is not locked, the message is invalid.  The user must call
143 * Cy_IPC_Drv_Release() function after reading the message to release the
144 * IPC channel.
145 *
146 * \param base
147 * This parameter is a handle that represents the base address of the registers
148 * of the IPC channel.
149 * The parameter is generally returned from a call to the \ref
150 * Cy_IPC_Drv_GetIpcBaseAddress.
151 *
152 * \param message
153 *  A variable where the read data is copied.
154 *
155 * \return  Status of the operation
156 *   \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
157 *                       was acquired.
158 *   \retval CY_IPC_DRV_ERROR:   The function encountered an error because the IPC
159 *                       channel was already in a released state, meaning the data
160 *                       may be invalid.
161 *
162 * \funcusage
163 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_ReadMsgWord
164 *
165 *******************************************************************************/
Cy_IPC_Drv_ReadMsgWord(IPC_STRUCT_Type const * base,uint32_t * message)166 cy_en_ipcdrv_status_t  Cy_IPC_Drv_ReadMsgWord (IPC_STRUCT_Type const * base, uint32_t * message)
167 {
168     cy_en_ipcdrv_status_t retStatus;
169 
170     CY_ASSERT_L1(NULL != message);
171 
172     if ( Cy_IPC_Drv_IsLockAcquired(base) )
173     {
174         /* The channel is locked; message is valid. */
175         *message = Cy_IPC_Drv_ReadDataValue(base);
176 
177         retStatus = CY_IPC_DRV_SUCCESS;
178     }
179     else
180     {
181         /* The channel is not locked so channel is invalid. */
182         retStatus = CY_IPC_DRV_ERROR;
183     }
184     return(retStatus);
185 }
186 
187 #if defined (CY_IP_M33SYSCPUSS_VERSION) || defined (CY_IP_M7CPUSS) || ( defined (CY_IP_M4CPUSS) && (CY_IP_M4CPUSS_VERSION > 1)) || defined (CY_DOXYGEN)
188 /*******************************************************************************
189 * Function Name: Cy_IPC_Drv_SendMsgDWord
190 ****************************************************************************//**
191 *
192 * This function is used to send two 32-bit word message through an IPC channel.
193 * The function also has an associated notification field that will let the
194 * message notify one or multiple IPC interrupts. The IPC channel is locked and
195 * remains locked after the function returns.  The receiver of the message should
196 * release the channel.
197 *
198 * \param base
199 * This parameter is a handle that represents the base address of the registers
200 * of the IPC channel.
201 * The parameter is generally returned from a call to the \ref
202 * Cy_IPC_Drv_GetIpcBaseAddress.
203 *
204 * \param notifyEventIntr
205 * Bit encoded list of IPC interrupt lines that are triggered by a notification.
206 * In case of devices having multiple IPC IP instances, this comprises of all IPC
207 * interrupts associated with only particular IPC IP.
208 *
209 * \param message
210 * The message word that is the data placed in the IPC data register.
211 *
212 * \return   Status of the operation:
213 *   \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
214 *   \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because it is already locked.
215 *
216 * \funcusage
217 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_SendMsgWord
218 *
219 *******************************************************************************/
220 CY_IPC_SECTION_BEGIN
Cy_IPC_Drv_SendMsgDWord(IPC_STRUCT_Type * base,uint32_t notifyEventIntr,uint32_t * message)221 cy_en_ipcdrv_status_t  Cy_IPC_Drv_SendMsgDWord (IPC_STRUCT_Type* base, uint32_t notifyEventIntr, uint32_t* message)
222 {
223     cy_en_ipcdrv_status_t retStatus = CY_IPC_DRV_ERROR;
224 
225     CY_ASSERT_L1(NULL != message);
226 
227     if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(base) )
228     {
229         /* If the channel was acquired, send the message. */
230         Cy_IPC_Drv_WriteDDataValue(base, message);
231         Cy_IPC_Drv_AcquireNotify(base, notifyEventIntr);
232         retStatus = CY_IPC_DRV_SUCCESS;
233     }
234     else
235     {
236         /* Channel was already acquired, return Error */
237         retStatus = CY_IPC_DRV_ERROR;
238     }
239     return (retStatus);
240 }
241 CY_IPC_SECTION_END
242 
243 /*******************************************************************************
244 * Function Name: Cy_IPC_Drv_ReadMsgDWord
245 ****************************************************************************//**
246 *
247 * This function is used to read two 32-bit word message through an IPC channel.
248 * This function assumes that the channel is locked (for a valid message).
249 * If the channel is not locked, the message is invalid.  The user must call
250 * Cy_IPC_Drv_Release() function after reading the message to release the
251 * IPC channel.
252 *
253 * \param base
254 * This parameter is a handle that represents the base address of the registers
255 * of the IPC channel.
256 * The parameter is generally returned from a call to the \ref
257 * Cy_IPC_Drv_GetIpcBaseAddress.
258 *
259 * \param message
260 *  A variable where the read data is copied.
261 *
262 * \return  Status of the operation
263 *   \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
264 *                       was acquired.
265 *   \retval CY_IPC_DRV_ERROR:   The function encountered an error because the IPC
266 *                       channel was already in a released state, meaning the data
267 *                       may be invalid.
268 *
269 * \funcusage
270 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_ReadMsgWord
271 *
272 *******************************************************************************/
Cy_IPC_Drv_ReadMsgDWord(IPC_STRUCT_Type const * base,uint32_t * message)273 cy_en_ipcdrv_status_t  Cy_IPC_Drv_ReadMsgDWord (IPC_STRUCT_Type const* base, uint32_t* message)
274 {
275     cy_en_ipcdrv_status_t retStatus;
276 
277     CY_ASSERT_L1(NULL != message);
278 
279     if ( Cy_IPC_Drv_IsLockAcquired(base) )
280     {
281         /* The channel is locked; message is valid. */
282         Cy_IPC_Drv_ReadDDataValue(base, message);
283         retStatus = CY_IPC_DRV_SUCCESS;
284     }
285     else
286     {
287         /* The channel is not locked so channel is invalid. */
288         retStatus = CY_IPC_DRV_ERROR;
289     }
290     return(retStatus);
291 }
292 #endif /* CY_IP_M33SYSCPUSS_VERSION, CY_IP_M4CPUSS, CY_IP_M4CPUSS_VERSION,  CY_IP_M7CPUSS*/
293 
294 #endif /* CY_IP_M4CPUSS, CY_IP_M7CPUSS*/
295 /* [] END OF FILE */
296