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