1 /***************************************************************************//**
2 * \file cy_ipc_drv.c
3 * \version 1.60
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_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 *
49 * \return   Status of the operation
50 *   \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC channel
51 *                       was released.
52 *   \retval CY_IPC_DRV_ERROR: The IPC channel was not acquired before the
53 *                       function call.
54 *
55 * \funcusage
56 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_ReadMsgPtr
57 *
58 *******************************************************************************/
Cy_IPC_Drv_LockRelease(IPC_STRUCT_Type * base,uint32_t releaseEventIntr)59 cy_en_ipcdrv_status_t Cy_IPC_Drv_LockRelease (IPC_STRUCT_Type* base, uint32_t releaseEventIntr)
60 {
61     cy_en_ipcdrv_status_t retStatus;
62 
63     /* Check to make sure the IPC is Acquired */
64     if( Cy_IPC_Drv_IsLockAcquired(base) )
65     {
66         /* The IPC was acquired, release the IPC channel */
67         Cy_IPC_Drv_ReleaseNotify(base, releaseEventIntr);
68 
69         retStatus = CY_IPC_DRV_SUCCESS;
70     }
71     else   /* The IPC channel was already released (not acquired) */
72     {
73         retStatus = CY_IPC_DRV_ERROR;
74     }
75 
76     return (retStatus);
77 }
78 
79 
80 /*******************************************************************************
81 * Function Name: Cy_IPC_Drv_SendMsgWord
82 ****************************************************************************//**
83 *
84 * This function is used to send a 32-bit word message through an IPC channel.
85 * The function also has an associated notification field that will let the
86 * message notify one or multiple IPC interrupts. The IPC channel is locked and
87 * remains locked after the function returns.  The receiver of the message should
88 * release the channel.
89 *
90 * \param base
91 * This parameter is a handle that represents the base address of the registers
92 * of the IPC channel.
93 * The parameter is generally returned from a call to the \ref
94 * Cy_IPC_Drv_GetIpcBaseAddress.
95 *
96 * \param notifyEventIntr
97 * Bit encoded list of IPC interrupt lines that are triggered by a notification.
98 *
99 * \param message
100 * The message word that is the data placed in the IPC data register.
101 *
102 * \return   Status of the operation:
103 *   \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
104 *   \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because it is already locked.
105 *
106 * \funcusage
107 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_SendMsgWord
108 *
109 *******************************************************************************/
Cy_IPC_Drv_SendMsgWord(IPC_STRUCT_Type * base,uint32_t notifyEventIntr,uint32_t message)110 cy_en_ipcdrv_status_t  Cy_IPC_Drv_SendMsgWord (IPC_STRUCT_Type* base, uint32_t notifyEventIntr, uint32_t message)
111 {
112     cy_en_ipcdrv_status_t retStatus;
113 
114     if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(base) )
115     {
116         /* If the channel was acquired, send the message. */
117         Cy_IPC_Drv_WriteDataValue(base, message);
118 
119         Cy_IPC_Drv_AcquireNotify(base, notifyEventIntr);
120 
121         retStatus = CY_IPC_DRV_SUCCESS;
122     }
123     else
124     {
125         /* Channel was already acquired, return Error */
126         retStatus = CY_IPC_DRV_ERROR;
127     }
128     return (retStatus);
129 }
130 
131 
132 /*******************************************************************************
133 * Function Name: Cy_IPC_Drv_ReadMsgWord
134 ****************************************************************************//**
135 *
136 * This function is used to read a 32-bit word message through an IPC channel.
137 * This function assumes that the channel is locked (for a valid message).
138 * If the channel is not locked, the message is invalid.  The user must call
139 * Cy_IPC_Drv_Release() function after reading the message to release the
140 * IPC channel.
141 *
142 * \param base
143 * This parameter is a handle that represents the base address of the registers
144 * of the IPC channel.
145 * The parameter is generally returned from a call to the \ref
146 * Cy_IPC_Drv_GetIpcBaseAddress.
147 *
148 * \param message
149 *  A variable where the read data is copied.
150 *
151 * \return  Status of the operation
152 *   \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
153 *                       was acquired.
154 *   \retval CY_IPC_DRV_ERROR:   The function encountered an error because the IPC
155 *                       channel was already in a released state, meaning the data
156 *                       may be invalid.
157 *
158 * \funcusage
159 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_ReadMsgWord
160 *
161 *******************************************************************************/
Cy_IPC_Drv_ReadMsgWord(IPC_STRUCT_Type const * base,uint32_t * message)162 cy_en_ipcdrv_status_t  Cy_IPC_Drv_ReadMsgWord (IPC_STRUCT_Type const * base, uint32_t * message)
163 {
164     cy_en_ipcdrv_status_t retStatus;
165 
166     CY_ASSERT_L1(NULL != message);
167 
168     if ( Cy_IPC_Drv_IsLockAcquired(base) )
169     {
170         /* The channel is locked; message is valid. */
171         *message = Cy_IPC_Drv_ReadDataValue(base);
172 
173         retStatus = CY_IPC_DRV_SUCCESS;
174     }
175     else
176     {
177         /* The channel is not locked so channel is invalid. */
178         retStatus = CY_IPC_DRV_ERROR;
179     }
180     return(retStatus);
181 }
182 
183 #if (CY_IP_M4CPUSS_VERSION > 1) || defined (CY_IP_M33SYSCPUSS_VERSION) || defined (CY_DOXYGEN)
184 /*******************************************************************************
185 * Function Name: Cy_IPC_Drv_SendMsgDWord
186 ****************************************************************************//**
187 *
188 * This function is used to send two 32-bit word message through an IPC channel.
189 * The function also has an associated notification field that will let the
190 * message notify one or multiple IPC interrupts. The IPC channel is locked and
191 * remains locked after the function returns.  The receiver of the message should
192 * release the channel.
193 *
194 * \param base
195 * This parameter is a handle that represents the base address of the registers
196 * of the IPC channel.
197 * The parameter is generally returned from a call to the \ref
198 * Cy_IPC_Drv_GetIpcBaseAddress.
199 *
200 * \param notifyEventIntr
201 * Bit encoded list of IPC interrupt lines that are triggered by a notification.
202 *
203 * \param message
204 * The message word that is the data placed in the IPC data register.
205 *
206 * \return   Status of the operation:
207 *   \retval CY_IPC_DRV_SUCCESS: The send operation was successful.
208 *   \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because it is already locked.
209 *
210 * \funcusage
211 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_SendMsgWord
212 *
213 *******************************************************************************/
Cy_IPC_Drv_SendMsgDWord(IPC_STRUCT_Type * base,uint32_t notifyEventIntr,uint32_t * message)214 cy_en_ipcdrv_status_t  Cy_IPC_Drv_SendMsgDWord (IPC_STRUCT_Type* base, uint32_t notifyEventIntr, uint32_t* message)
215 {
216     cy_en_ipcdrv_status_t retStatus = CY_IPC_DRV_ERROR;
217 
218     CY_ASSERT_L1(NULL != message);
219 
220     if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(base) )
221     {
222         /* If the channel was acquired, send the message. */
223         Cy_IPC_Drv_WriteDDataValue(base, message);
224         Cy_IPC_Drv_AcquireNotify(base, notifyEventIntr);
225         retStatus = CY_IPC_DRV_SUCCESS;
226     }
227     else
228     {
229         /* Channel was already acquired, return Error */
230         retStatus = CY_IPC_DRV_ERROR;
231     }
232     return (retStatus);
233 }
234 
235 /*******************************************************************************
236 * Function Name: Cy_IPC_Drv_ReadMsgDWord
237 ****************************************************************************//**
238 *
239 * This function is used to read two 32-bit word message through an IPC channel.
240 * This function assumes that the channel is locked (for a valid message).
241 * If the channel is not locked, the message is invalid.  The user must call
242 * Cy_IPC_Drv_Release() function after reading the message to release the
243 * IPC channel.
244 *
245 * \param base
246 * This parameter is a handle that represents the base address of the registers
247 * of the IPC channel.
248 * The parameter is generally returned from a call to the \ref
249 * Cy_IPC_Drv_GetIpcBaseAddress.
250 *
251 * \param message
252 *  A variable where the read data is copied.
253 *
254 * \return  Status of the operation
255 *   \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC
256 *                       was acquired.
257 *   \retval CY_IPC_DRV_ERROR:   The function encountered an error because the IPC
258 *                       channel was already in a released state, meaning the data
259 *                       may be invalid.
260 *
261 * \funcusage
262 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Drv_ReadMsgWord
263 *
264 *******************************************************************************/
Cy_IPC_Drv_ReadMsgDWord(IPC_STRUCT_Type const * base,uint32_t * message)265 cy_en_ipcdrv_status_t  Cy_IPC_Drv_ReadMsgDWord (IPC_STRUCT_Type const* base, uint32_t* message)
266 {
267     cy_en_ipcdrv_status_t retStatus;
268 
269     CY_ASSERT_L1(NULL != message);
270 
271     if ( Cy_IPC_Drv_IsLockAcquired(base) )
272     {
273         /* The channel is locked; message is valid. */
274         Cy_IPC_Drv_ReadDDataValue(base, message);
275         retStatus = CY_IPC_DRV_SUCCESS;
276     }
277     else
278     {
279         /* The channel is not locked so channel is invalid. */
280         retStatus = CY_IPC_DRV_ERROR;
281     }
282     return(retStatus);
283 }
284 #endif
285 
286 #endif /* CY_IP_M4CPUSS */
287 /* [] END OF FILE */
288