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