1 /***************************************************************************//**
2 * \file cy_ipc_sema.c
3 * \version 1.91
4 *
5 * Description:
6 * IPC Semaphore Driver - This source file contains the source code for the
7 * semaphore level APIs for the IPC interface.
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) && (CY_IPC_INSTANCES > 1U))
29
30 #include "cy_ipc_drv.h"
31 #include "cy_ipc_sema.h"
32 #include "cy_syslib.h"
33 #include <string.h> /* The memset() definition */
34
35 /* Defines a mask to Check if semaphore count is a multiple of 32 */
36 #define CY_IPC_SEMA_PER_WORD_MASK (CY_IPC_SEMA_PER_WORD - 1UL)
37
38 /* Pointer to IPC structure used for semaphores */
39 static IPC_STRUCT_Type* cy_semaIpcStruct;
40
41
42 /*******************************************************************************
43 * Function Name: Cy_IPC_Sema_Init
44 ****************************************************************************//**
45 *
46 * This function initializes the semaphores subsystem. The user must create an
47 * array of unsigned 32-bit words to hold the semaphore bits. The number
48 * of semaphores will be the size of the array * 32. The total semaphores count
49 * will always be a multiple of 32.
50 *
51 * \note In a multi-CPU system this init function should be called with all
52 * initialized parameters on one CPU only to provide a pointer to SRAM that can
53 * be shared between all the CPUs in the system that will use semaphores.
54 * On other CPUs user must specify the IPC semaphores channel and pass 0 / NULL
55 * to count and memPtr parameters correspondingly.
56 *
57 * CM7 cores in CAT1C devices support Data Cache. Data Cache line is 32 bytes.
58 * User needs to make sure that the memPtr pointer passed to the Cy_IPC_Sema_Init
59 * function points to 32 byte aligned array of words that contain the semaphore data.
60 * User can use CY_ALIGN(32) macro for 32 byte alignment.
61 *
62 * \param ipcChannel
63 * The IPC channel number used for semaphores
64 *
65 * \param count
66 * The maximum number of semaphores to be supported (multiple of 32).
67 *
68 * \param memPtr
69 * This points to the array of (count/32) words that contain the semaphore data.
70 *
71 * \return Status of the operation
72 * \retval CY_IPC_SEMA_SUCCESS: Successfully initialized
73 * \retval CY_IPC_SEMA_BAD_PARAM: Memory pointer is NULL and count is not zero,
74 * or count not multiple of 32
75 * \retval CY_IPC_SEMA_ERROR_LOCKED: Could not acquire semaphores IPC channel
76 *
77 * \funcusage
78 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Sema_Init
79 *
80 *******************************************************************************/
Cy_IPC_Sema_Init(uint32_t ipcChannel,uint32_t count,uint32_t memPtr[])81 cy_en_ipcsema_status_t Cy_IPC_Sema_Init(uint32_t ipcChannel,
82 uint32_t count, uint32_t memPtr[])
83 {
84 /* Structure containing semaphores control data */
85 CY_SECTION_SHAREDMEM
86 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
87 static cy_stc_ipc_sema_t cy_semaData CY_ALIGN(__SCB_DCACHE_LINE_SIZE);
88 #else
89 static cy_stc_ipc_sema_t cy_semaData;
90 #endif
91 cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_BAD_PARAM;
92
93 if( (NULL == memPtr) && (0u == count))
94 {
95 cy_semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipcChannel);
96
97 retStatus = CY_IPC_SEMA_SUCCESS;
98 }
99
100 /* Check for non Null pointers and count value */
101 else if ((NULL != memPtr) && (0u != count))
102 {
103 cy_semaData.maxSema = count;
104 cy_semaData.arrayPtr = memPtr;
105
106 retStatus = Cy_IPC_Sema_InitExt(ipcChannel, &cy_semaData);
107 }
108
109 else
110 {
111 retStatus = CY_IPC_SEMA_BAD_PARAM;
112 }
113
114 return(retStatus);
115 }
116
117
118 /*******************************************************************************
119 * Function Name: Cy_IPC_Sema_InitExt
120 ****************************************************************************//**
121 * This function initializes the semaphores subsystem. The user must create an
122 * array of unsigned 32-bit words to hold the semaphore bits. The number
123 * of semaphores will be the size of the array * 32. The total semaphores count
124 * will always be a multiple of 32.
125 *
126 * \note In a multi-CPU system this init function should be called with all
127 * initialized parameters on one CPU only to provide a pointer to SRAM that can
128 * be shared between all the CPUs in the system that will use semaphores.
129 * On other CPUs user must specify the IPC semaphores channel and pass 0 / NULL
130 * to count and memPtr parameters correspondingly.
131 *
132 * \param ipcChannel
133 * The IPC channel number used for semaphores
134 *
135 * \param ipcSema
136 * This is configuration structure of the IPC semaphore.
137 * See \ref cy_stc_ipc_sema_t.
138 *
139 * \return Status of the operation
140 * \retval CY_IPC_SEMA_SUCCESS: Successfully initialized
141 * \retval CY_IPC_SEMA_BAD_PARAM: Memory pointer is NULL and count is not zero,
142 * or count not multiple of 32
143 * \retval CY_IPC_SEMA_ERROR_LOCKED: Could not acquire semaphores IPC channel
144 *
145 *******************************************************************************/
Cy_IPC_Sema_InitExt(uint32_t ipcChannel,cy_stc_ipc_sema_t * ipcSema)146 cy_en_ipcsema_status_t Cy_IPC_Sema_InitExt(uint32_t ipcChannel, cy_stc_ipc_sema_t *ipcSema)
147 {
148 cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_BAD_PARAM;
149
150 if (ipcChannel >= CY_IPC_CHANNELS)
151 {
152 retStatus = CY_IPC_SEMA_BAD_PARAM;
153 }
154 else
155 {
156 if(NULL != ipcSema)
157 {
158 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
159 SCB_CleanDCache_by_Addr((uint32_t*)&ipcSema->maxSema, (int32_t)sizeof(ipcSema->maxSema));
160 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
161 /* Check if semaphore count is a multiple of 32 */
162 if( 0UL == (ipcSema->maxSema & CY_IPC_SEMA_PER_WORD_MASK))
163 {
164 cy_semaIpcStruct = Cy_IPC_Drv_GetIpcBaseAddress(ipcChannel);
165
166 /* Initialize all semaphores to released */
167 for (uint32_t index=0; index<(uint32_t)(ipcSema->maxSema / CY_IPC_SEMA_PER_WORD); index++)
168 {
169 ipcSema->arrayPtr[index] = 0UL;
170 }
171
172 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
173 SCB_CleanDCache_by_Addr((uint32_t*)ipcSema->arrayPtr, (int32_t)sizeof(*ipcSema->arrayPtr));
174 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
175
176 /* Make sure semaphores start out released. */
177 /* Ignore the return value since it is OK if it was already released. */
178 (void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
179
180 /* Set the IPC Data with the pointer to the array. */
181 if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_SendMsgPtr (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION, ipcSema))
182 {
183 if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION))
184 {
185 retStatus = CY_IPC_SEMA_SUCCESS;
186 }
187 else
188 {
189 /* IPC channel not released, still semaphored */
190 retStatus = CY_IPC_SEMA_ERROR_LOCKED;
191 }
192 }
193 else
194 {
195 /* Could not acquire semaphore channel */
196 retStatus = CY_IPC_SEMA_ERROR_LOCKED;
197 }
198 }
199 else
200 {
201 retStatus = CY_IPC_SEMA_BAD_PARAM;
202 }
203 }
204 else
205 {
206 retStatus = CY_IPC_SEMA_BAD_PARAM;
207 }
208 }
209
210 return(retStatus);
211 }
212
213
214 /*******************************************************************************
215 * Function Name: Cy_IPC_Sema_Set
216 ****************************************************************************//**
217 *
218 * This function tries to acquire a semaphore. If the
219 * semaphore is not available, this function returns immediately with
220 * CY_IPC_SEMA_LOCKED.
221 *
222 * It first acquires the IPC channel that is used for all the semaphores, sets
223 * the semaphore if it is cleared, then releases the IPC channel used for the
224 * semaphore.
225 *
226 * \param semaNumber
227 * The semaphore number to acquire.
228 * \note CAT1D has two shared memories. One is a secure memory area which is accessible from
229 * secure domains only. Another memory area which is accessible from both secure and non-secure
230 * domains. To use secure area for semaphore, user has to use \ref CY_IPC_SEMA_SEC macro to create
231 * a secure semaphore.
232 *
233 * \param preemptable
234 * When this parameter is enabled the function can be preempted by another
235 * task or other forms of context switching in an RTOS environment.
236 *
237 * \note
238 * If <b>preemptable</b> is enabled (true), the user must ensure that there are
239 * no deadlocks in the system, which can be caused by an interrupt that occurs
240 * after the IPC channel is locked. Unless the user is ready to handle IPC
241 * channel locks correctly at the application level, set <b>preemptable</b> to
242 * false.
243 *
244 * \return Status of the operation
245 * \retval CY_IPC_SEMA_SUCCESS: The semaphore was set successfully
246 * \retval CY_IPC_SEMA_LOCKED: The semaphore channel is busy or locked
247 * by another process
248 * \retval CY_IPC_SEMA_NOT_ACQUIRED: Semaphore was already set
249 * \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
250 *
251 * \funcusage
252 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Sema_Set
253 *
254 *******************************************************************************/
Cy_IPC_Sema_Set(uint32_t semaNumber,bool preemptable)255 cy_en_ipcsema_status_t Cy_IPC_Sema_Set(uint32_t semaNumber, bool preemptable)
256 {
257 uint32_t semaIndex;
258 uint32_t semaMask;
259 uint32_t interruptState = 0UL;
260
261 cy_stc_ipc_sema_t *semaStruct;
262 cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_LOCKED;
263 uint32_t *ptrArray;
264 uint32_t semaNum;
265
266 /** check cy_semaIpcStruct != NULL */
267 if (cy_semaIpcStruct == NULL)
268 {
269 return CY_IPC_SEMA_NOT_ACQUIRED;
270 }
271
272
273 /* Get pointer to structure */
274 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
275 semaNum = CY_IPC_SEMA_GET_NUM(semaNumber);
276 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
277 #else
278 semaNum = semaNumber;
279 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
280 #endif
281
282 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
283 SCB_InvalidateDCache_by_Addr((uint32_t*)&semaStruct->maxSema, (int32_t)sizeof(semaStruct->maxSema));
284 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
285
286 if (semaNum < semaStruct->maxSema)
287 {
288 semaIndex = semaNum / CY_IPC_SEMA_PER_WORD;
289 semaMask = (uint32_t)(1UL << (semaNum - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
290 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
291 ptrArray = CY_IPC_SEMA_IS_SEC(semaNumber) ? semaStruct->arrayPtr_sec : (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
292 #else
293 ptrArray = semaStruct->arrayPtr;
294 #endif
295 if (!preemptable)
296 {
297 interruptState = Cy_SysLib_EnterCriticalSection();
298 }
299
300 /* Check to make sure the IPC channel is released
301 If so, check if specific channel can be locked. */
302 if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
303 {
304 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
305 SCB_InvalidateDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
306 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
307
308 if((ptrArray[semaIndex] & semaMask) == 0UL)
309 {
310 ptrArray[semaIndex] |= semaMask;
311 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
312 SCB_CleanDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
313 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
314 retStatus = CY_IPC_SEMA_SUCCESS;
315 }
316 else
317 {
318 retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
319 }
320
321 /* Release, but do not trigger a release event */
322 (void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
323 }
324
325 if (!preemptable)
326 {
327 Cy_SysLib_ExitCriticalSection(interruptState);
328 }
329 }
330 else
331 {
332 retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
333 }
334
335 return(retStatus);
336 }
337
338
339 /*******************************************************************************
340 * Function Name: Cy_IPC_Sema_Clear
341 ****************************************************************************//**
342 *
343 * This functions tries to releases a semaphore.
344 *
345 * It first acquires the IPC channel that is used for all the semaphores, clears
346 * the semaphore if it is set, then releases the IPC channel used for the
347 * semaphores.
348 *
349 * \param semaNumber
350 * The index of the semaphore to release.
351 * \note CAT1D has two shared memories. One is a secure memory area which is accessible from
352 * secure domains only. Another memory area which is accessible from both secure and non-secure
353 * domains. To use secure area for semaphore, user has to use \ref CY_IPC_SEMA_SEC macro to create
354 * a secure semaphore.
355 *
356 * \param preemptable
357 * When this parameter is enabled the function can be preempted by another
358 * task or other forms of context switching in an RTOS environment.
359 *
360 * \note
361 * If <b>preemptable</b> is enabled (true), the user must ensure that there are
362 * no deadlocks in the system, which can be caused by an interrupt that occurs
363 * after the IPC channel is locked. Unless the user is ready to handle IPC
364 * channel locks correctly at the application level, set <b>preemptable</b> to
365 * false.
366 *
367 * \return Status of the operation
368 * \retval CY_IPC_SEMA_SUCCESS: The semaphore was cleared successfully
369 * \retval CY_IPC_SEMA_NOT_ACQUIRED: The semaphore was already cleared
370 * \retval CY_IPC_SEMA_LOCKED: The semaphore channel was semaphored or busy
371 * \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
372 *
373 * \funcusage
374 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Sema_Clear
375 *
376 *******************************************************************************/
Cy_IPC_Sema_Clear(uint32_t semaNumber,bool preemptable)377 cy_en_ipcsema_status_t Cy_IPC_Sema_Clear(uint32_t semaNumber, bool preemptable)
378 {
379 uint32_t semaIndex;
380 uint32_t semaMask;
381 uint32_t interruptState = 0UL;
382
383 cy_stc_ipc_sema_t *semaStruct;
384 cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_LOCKED;
385 uint32_t *ptrArray;
386 uint32_t semaNum;
387
388 /** check cy_semaIpcStruct != NULL */
389 if (cy_semaIpcStruct == NULL)
390 {
391 return CY_IPC_SEMA_NOT_ACQUIRED;
392 }
393
394
395 /* Get pointer to structure */
396 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
397 semaNum = CY_IPC_SEMA_GET_NUM(semaNumber);
398 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
399 #else
400 semaNum = semaNumber;
401 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
402 #endif
403
404 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
405 SCB_InvalidateDCache_by_Addr((uint32_t*)&semaStruct->maxSema, (int32_t)sizeof(semaStruct->maxSema));
406 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
407
408 if (semaNum < semaStruct->maxSema)
409 {
410 semaIndex = semaNum / CY_IPC_SEMA_PER_WORD;
411 semaMask = (uint32_t)(1UL << (semaNum - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
412 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
413 ptrArray = CY_IPC_SEMA_IS_SEC(semaNumber) ? semaStruct->arrayPtr_sec : (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
414 #else
415 ptrArray = semaStruct->arrayPtr;
416 #endif
417
418 if (!preemptable)
419 {
420 interruptState = Cy_SysLib_EnterCriticalSection();
421 }
422
423 /* Check to make sure the IPC channel is released
424 If so, check if specific channel can be locked. */
425 if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
426 {
427 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
428 SCB_InvalidateDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
429 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
430 if((ptrArray[semaIndex] & semaMask) != 0UL)
431 {
432 ptrArray[semaIndex] &= ~semaMask;
433 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
434 SCB_CleanDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
435 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
436 retStatus = CY_IPC_SEMA_SUCCESS;
437 }
438 else
439 {
440 retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
441 }
442
443 /* Release, but do not trigger a release event */
444 (void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
445 }
446
447 if (!preemptable)
448 {
449 Cy_SysLib_ExitCriticalSection(interruptState);
450 }
451 }
452 else
453 {
454 retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
455 }
456 return(retStatus);
457 }
458
459
460 /*******************************************************************************
461 * Function Name: Cy_IPC_Sema_Status
462 ****************************************************************************//**
463 *
464 * This function returns the status of the semaphore.
465 *
466 * \param semaNumber
467 * The index of the semaphore to return status.
468 * \note CAT1D has two shared memories. One is a secure memory area which is accessible from
469 * secure domains only. Another memory area which is accessible from both secure and non-secure
470 * domains. To use secure area for semaphore, user has to use \ref CY_IPC_SEMA_SEC macro to create
471 * a secure semaphore.
472 *
473 * \return Status of the operation
474 * \retval CY_IPC_SEMA_STATUS_LOCKED: The semaphore is in the set state.
475 * \retval CY_IPC_SEMA_STATUS_UNLOCKED: The semaphore is in the cleared state.
476 * \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
477 *
478 * \funcusage
479 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Sema_Status
480 *
481 *******************************************************************************/
Cy_IPC_Sema_Status(uint32_t semaNumber)482 cy_en_ipcsema_status_t Cy_IPC_Sema_Status(uint32_t semaNumber)
483 {
484 cy_en_ipcsema_status_t retStatus;
485 uint32_t semaIndex;
486 uint32_t semaMask;
487 cy_stc_ipc_sema_t *semaStruct;
488 uint32_t *ptrArray;
489 uint32_t semaNum;
490
491 /** check cy_semaIpcStruct != NULL */
492 if (cy_semaIpcStruct == NULL)
493 {
494 return CY_IPC_SEMA_NOT_ACQUIRED;
495 }
496
497
498 /* Get pointer to structure */
499 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
500 semaNum = CY_IPC_SEMA_GET_NUM(semaNumber);
501 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
502 #else
503 semaNum = semaNumber;
504 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
505 #endif
506
507 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
508 SCB_InvalidateDCache_by_Addr((uint32_t*)&semaStruct->maxSema, (int32_t)sizeof(semaStruct->maxSema));
509 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
510
511 if (semaNum < semaStruct->maxSema)
512 {
513 /* Get the index into the semaphore array and calculate the mask */
514 semaIndex = semaNum / CY_IPC_SEMA_PER_WORD;
515 semaMask = (uint32_t)(1UL << (semaNum - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
516 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
517 ptrArray = CY_IPC_SEMA_IS_SEC(semaNumber) ? semaStruct->arrayPtr_sec : (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
518 #else
519 ptrArray = semaStruct->arrayPtr;
520 #endif
521
522 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
523 SCB_InvalidateDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
524 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
525
526 if((ptrArray[semaIndex] & semaMask) != 0UL)
527 {
528 retStatus = CY_IPC_SEMA_STATUS_LOCKED;
529 }
530 else
531 {
532 retStatus = CY_IPC_SEMA_STATUS_UNLOCKED;
533 }
534 }
535 else
536 {
537 retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
538 }
539 return(retStatus);
540 }
541
542
543 /*******************************************************************************
544 * Function Name: Cy_IPC_Sema_GetMaxSems
545 ****************************************************************************//**
546 *
547 * This function returns the number of semaphores in the semaphores subsystem.
548 *
549 * \return
550 * Returns the semaphores quantity.
551 *
552 * \funcusage
553 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Sema_GetMaxSems
554 *
555 *******************************************************************************/
Cy_IPC_Sema_GetMaxSems(void)556 uint32_t Cy_IPC_Sema_GetMaxSems(void)
557 {
558 cy_stc_ipc_sema_t *semaStruct;
559
560 /* Get pointer to structure */
561 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
562 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
563 #else
564 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
565 #endif
566 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
567 SCB_InvalidateDCache_by_Addr((uint32_t*)&semaStruct->maxSema, (int32_t)sizeof(semaStruct->maxSema));
568 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
569 return (semaStruct->maxSema);
570 }
571
572 #endif
573
574 /* [] END OF FILE */
575