1 /***************************************************************************//**
2 * \file cy_ipc_sema.c
3 * \version 1.130
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)
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 #elif defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT==1)
278 semaNum = semaNumber;
279 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
280 #else
281 semaNum = semaNumber;
282 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
283 #endif
284
285 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
286 SCB_InvalidateDCache_by_Addr((uint32_t*)&semaStruct->maxSema, (int32_t)sizeof(semaStruct->maxSema));
287 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
288
289 if (semaNum < semaStruct->maxSema)
290 {
291 semaIndex = semaNum / CY_IPC_SEMA_PER_WORD;
292 semaMask = (uint32_t)(1UL << (semaNum - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
293 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
294 ptrArray = CY_IPC_SEMA_IS_SEC(semaNumber) ? semaStruct->arrayPtr_sec : (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
295 #elif defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT==1)
296 ptrArray = (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
297 #else
298 ptrArray = semaStruct->arrayPtr;
299 #endif
300 if (!preemptable)
301 {
302 interruptState = Cy_SysLib_EnterCriticalSection();
303 }
304
305 /* Check to make sure the IPC channel is released
306 If so, check if specific channel can be locked. */
307 if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
308 {
309 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
310 SCB_InvalidateDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
311 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
312
313 if((ptrArray[semaIndex] & semaMask) == 0UL)
314 {
315 ptrArray[semaIndex] |= semaMask;
316 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
317 SCB_CleanDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
318 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
319 retStatus = CY_IPC_SEMA_SUCCESS;
320 }
321 else
322 {
323 retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
324 }
325
326 /* Release, but do not trigger a release event */
327 (void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
328 }
329
330 if (!preemptable)
331 {
332 Cy_SysLib_ExitCriticalSection(interruptState);
333 }
334 }
335 else
336 {
337 retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
338 }
339
340 return(retStatus);
341 }
342
343
344 /*******************************************************************************
345 * Function Name: Cy_IPC_Sema_Clear
346 ****************************************************************************//**
347 *
348 * This functions tries to releases a semaphore.
349 *
350 * It first acquires the IPC channel that is used for all the semaphores, clears
351 * the semaphore if it is set, then releases the IPC channel used for the
352 * semaphores.
353 *
354 * \param semaNumber
355 * The index of the semaphore to release.
356 * \note CAT1D has two shared memories. One is a secure memory area which is accessible from
357 * secure domains only. Another memory area which is accessible from both secure and non-secure
358 * domains. To use secure area for semaphore, user has to use \ref CY_IPC_SEMA_SEC macro to create
359 * a secure semaphore.
360 *
361 * \param preemptable
362 * When this parameter is enabled the function can be preempted by another
363 * task or other forms of context switching in an RTOS environment.
364 *
365 * \note
366 * If <b>preemptable</b> is enabled (true), the user must ensure that there are
367 * no deadlocks in the system, which can be caused by an interrupt that occurs
368 * after the IPC channel is locked. Unless the user is ready to handle IPC
369 * channel locks correctly at the application level, set <b>preemptable</b> to
370 * false.
371 *
372 * \return Status of the operation
373 * \retval CY_IPC_SEMA_SUCCESS: The semaphore was cleared successfully
374 * \retval CY_IPC_SEMA_NOT_ACQUIRED: The semaphore was already cleared
375 * \retval CY_IPC_SEMA_LOCKED: The semaphore channel was semaphored or busy
376 * \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
377 *
378 * \funcusage
379 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Sema_Clear
380 *
381 *******************************************************************************/
Cy_IPC_Sema_Clear(uint32_t semaNumber,bool preemptable)382 cy_en_ipcsema_status_t Cy_IPC_Sema_Clear(uint32_t semaNumber, bool preemptable)
383 {
384 uint32_t semaIndex;
385 uint32_t semaMask;
386 uint32_t interruptState = 0UL;
387
388 cy_stc_ipc_sema_t *semaStruct;
389 cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_LOCKED;
390 uint32_t *ptrArray;
391 uint32_t semaNum;
392
393 /** check cy_semaIpcStruct != NULL */
394 if (cy_semaIpcStruct == NULL)
395 {
396 return CY_IPC_SEMA_NOT_ACQUIRED;
397 }
398
399
400 /* Get pointer to structure */
401 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
402 semaNum = CY_IPC_SEMA_GET_NUM(semaNumber);
403 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
404 #elif defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT==1)
405 semaNum = semaNumber;
406 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
407 #else
408 semaNum = semaNumber;
409 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
410 #endif
411
412 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
413 SCB_InvalidateDCache_by_Addr((uint32_t*)&semaStruct->maxSema, (int32_t)sizeof(semaStruct->maxSema));
414 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
415
416 if (semaNum < semaStruct->maxSema)
417 {
418 semaIndex = semaNum / CY_IPC_SEMA_PER_WORD;
419 semaMask = (uint32_t)(1UL << (semaNum - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
420 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
421 ptrArray = CY_IPC_SEMA_IS_SEC(semaNumber) ? semaStruct->arrayPtr_sec : (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
422 #elif defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT==1)
423 ptrArray = (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
424 #else
425 ptrArray = semaStruct->arrayPtr;
426 #endif
427
428 if (!preemptable)
429 {
430 interruptState = Cy_SysLib_EnterCriticalSection();
431 }
432
433 /* Check to make sure the IPC channel is released
434 If so, check if specific channel can be locked. */
435 if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct))
436 {
437 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
438 SCB_InvalidateDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
439 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
440 if((ptrArray[semaIndex] & semaMask) != 0UL)
441 {
442 ptrArray[semaIndex] &= ~semaMask;
443 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
444 SCB_CleanDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
445 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
446 retStatus = CY_IPC_SEMA_SUCCESS;
447 }
448 else
449 {
450 retStatus = CY_IPC_SEMA_NOT_ACQUIRED;
451 }
452
453 /* Release, but do not trigger a release event */
454 (void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION);
455 }
456
457 if (!preemptable)
458 {
459 Cy_SysLib_ExitCriticalSection(interruptState);
460 }
461 }
462 else
463 {
464 retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
465 }
466 return(retStatus);
467 }
468
469
470 /*******************************************************************************
471 * Function Name: Cy_IPC_Sema_Status
472 ****************************************************************************//**
473 *
474 * This function returns the status of the semaphore.
475 *
476 * \param semaNumber
477 * The index of the semaphore to return status.
478 * \note CAT1D has two shared memories. One is a secure memory area which is accessible from
479 * secure domains only. Another memory area which is accessible from both secure and non-secure
480 * domains. To use secure area for semaphore, user has to use \ref CY_IPC_SEMA_SEC macro to create
481 * a secure semaphore.
482 *
483 * \return Status of the operation
484 * \retval CY_IPC_SEMA_STATUS_LOCKED: The semaphore is in the set state.
485 * \retval CY_IPC_SEMA_STATUS_UNLOCKED: The semaphore is in the cleared state.
486 * \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid
487 *
488 * \funcusage
489 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Sema_Status
490 *
491 *******************************************************************************/
Cy_IPC_Sema_Status(uint32_t semaNumber)492 cy_en_ipcsema_status_t Cy_IPC_Sema_Status(uint32_t semaNumber)
493 {
494 cy_en_ipcsema_status_t retStatus;
495 uint32_t semaIndex;
496 uint32_t semaMask;
497 cy_stc_ipc_sema_t *semaStruct;
498 uint32_t *ptrArray;
499 uint32_t semaNum;
500
501 /** check cy_semaIpcStruct != NULL */
502 if (cy_semaIpcStruct == NULL)
503 {
504 return CY_IPC_SEMA_NOT_ACQUIRED;
505 }
506
507
508 /* Get pointer to structure */
509 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
510 semaNum = CY_IPC_SEMA_GET_NUM(semaNumber);
511 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
512 #elif defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT==1)
513 semaNum = semaNumber;
514 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
515 #else
516 semaNum = semaNumber;
517 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
518 #endif
519
520 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
521 SCB_InvalidateDCache_by_Addr((uint32_t*)&semaStruct->maxSema, (int32_t)sizeof(semaStruct->maxSema));
522 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
523
524 if (semaNum < semaStruct->maxSema)
525 {
526 /* Get the index into the semaphore array and calculate the mask */
527 semaIndex = semaNum / CY_IPC_SEMA_PER_WORD;
528 semaMask = (uint32_t)(1UL << (semaNum - (semaIndex * CY_IPC_SEMA_PER_WORD) ));
529 #if defined(CY_IPC_SECURE_SEMA_DEVICE)
530 ptrArray = CY_IPC_SEMA_IS_SEC(semaNumber) ? semaStruct->arrayPtr_sec : (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
531 #elif defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT==1)
532 ptrArray = (uint32_t*)GET_ALIAS_ADDRESS(semaStruct->arrayPtr);
533 #else
534 ptrArray = semaStruct->arrayPtr;
535 #endif
536
537 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
538 SCB_InvalidateDCache_by_Addr((uint32_t*)ptrArray, (int32_t)sizeof(*ptrArray));
539 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
540
541 if((ptrArray[semaIndex] & semaMask) != 0UL)
542 {
543 retStatus = CY_IPC_SEMA_STATUS_LOCKED;
544 }
545 else
546 {
547 retStatus = CY_IPC_SEMA_STATUS_UNLOCKED;
548 }
549 }
550 else
551 {
552 retStatus = CY_IPC_SEMA_OUT_OF_RANGE;
553 }
554 return(retStatus);
555 }
556
557
558 /*******************************************************************************
559 * Function Name: Cy_IPC_Sema_GetMaxSems
560 ****************************************************************************//**
561 *
562 * This function returns the number of semaphores in the semaphores subsystem.
563 *
564 * \return
565 * Returns the semaphores quantity.
566 *
567 * \funcusage
568 * \snippet ipc/snippet/main.c snippet_Cy_IPC_Sema_GetMaxSems
569 *
570 *******************************************************************************/
Cy_IPC_Sema_GetMaxSems(void)571 uint32_t Cy_IPC_Sema_GetMaxSems(void)
572 {
573 cy_stc_ipc_sema_t *semaStruct;
574
575 /* Get pointer to structure */
576 #if defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT==1)
577 semaStruct = (cy_stc_ipc_sema_t *)(GET_ALIAS_ADDRESS(Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct)));
578 #else
579 semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct);
580 #endif
581 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
582 SCB_InvalidateDCache_by_Addr((uint32_t*)&semaStruct->maxSema, (int32_t)sizeof(semaStruct->maxSema));
583 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
584 return (semaStruct->maxSema);
585 }
586
587 #endif
588
589 /* [] END OF FILE */
590