/******************************************************************************* * Function Name: Cy_IPC_Sema_Set ****************************************************************************//** * * This function tries to acquire a semaphore. If the * semaphore is not available, this function returns immediately with * CY_IPC_SEMA_LOCKED. * * It first acquires the IPC channel that is used for all the semaphores, sets * the semaphore if it is cleared, then releases the IPC channel used for the * semaphore. * * \param semaNumber * The semaphore number to acquire. * * \param preemptable * When this parameter is enabled the function can be preempted by another * task or other forms of context switching in an RTOS environment. * * \note * If <b>preemptable</b> is enabled (true), the user must ensure that there are * no deadlocks in the system, which can be caused by an interrupt that occurs * after the IPC channel is locked. Unless the user is ready to handle IPC * channel locks correctly at the application level, set <b>premptable</b> to * false. * * \return Status of the operation * \retval CY_IPC_SEMA_SUCCESS: The semaphore was set successfully * \retval CY_IPC_SEMA_LOCKED: The semaphore channel is busy or locked * by another process * \retval CY_IPC_SEMA_NOT_ACQUIRED: Semaphore was already set * \retval CY_IPC_SEMA_OUT_OF_RANGE: The semaphore number is not valid * * \funcusage * \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_Set * *******************************************************************************/ cy_en_ipcsema_status_t Cy_IPC_Sema_Set(uint32_t semaNumber, bool preemptable) { uint32_t semaIndex; uint32_t semaMask; uint32_t interruptState = 0ul; cy_stc_ipc_sema_t *semaStruct; cy_en_ipcsema_status_t retStatus = CY_IPC_SEMA_LOCKED; /* Get pointer to structure */ semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct); if (semaNumber < semaStruct->maxSema) { semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD; semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) )); if (!preemptable) { interruptState = Cy_SysLib_EnterCriticalSection(); } /* Check to make sure the IPC channel is released If so, check if specific channel can be locked. */ if(CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire (cy_semaIpcStruct)) { if((semaStruct->arrayPtr[semaIndex] & semaMask) == 0ul) { semaStruct->arrayPtr[semaIndex] |= semaMask; retStatus = CY_IPC_SEMA_SUCCESS; } else { retStatus = CY_IPC_SEMA_NOT_ACQUIRED; } /* Release, but do not trigger a release event */ (void) Cy_IPC_Drv_LockRelease (cy_semaIpcStruct, CY_IPC_NO_NOTIFICATION); } if (!preemptable) { Cy_SysLib_ExitCriticalSection(interruptState); } } else { retStatus = CY_IPC_SEMA_OUT_OF_RANGE; } return(retStatus); }
/******************************************************************************* * Function Name: Cy_IPC_Drv_SendMsgWord ****************************************************************************//** * * This function is used to send a 32-bit word message through an IPC channel. * The function also has an associated notification field that will let the * message notify one or multiple IPC interrupts. The IPC channel is locked and * remains locked after the function returns. The receiver of the message should * release the channel. * * \param base * This parameter is a handle that represents the base address of the registers * of the IPC channel. * The parameter is generally returned from a call to the \ref * Cy_IPC_Drv_GetIpcBaseAddress. * * \param notifyEventIntr * Bit encoded list of IPC interrupt lines that are triggered by a notification. * * \param message * The message word that is the data placed in the IPC data register. * * \return Status of the operation: * \retval CY_IPC_DRV_SUCCESS: The send operation was successful. * \retval CY_IPC_DRV_ERROR: The IPC channel is unavailable because it is already locked. * * \funcusage * \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_SendMsgWord * *******************************************************************************/ cy_en_ipcdrv_status_t Cy_IPC_Drv_SendMsgWord (IPC_STRUCT_Type* base, uint32_t notifyEventIntr, uint32_t message) { cy_en_ipcdrv_status_t retStatus; if( CY_IPC_DRV_SUCCESS == Cy_IPC_Drv_LockAcquire(base) ) { /* If the channel was acquired, send the message. */ Cy_IPC_Drv_WriteDataValue(base, message); Cy_IPC_Drv_AcquireNotify(base, notifyEventIntr); retStatus = CY_IPC_DRV_SUCCESS; } else { /* Channel was already acquired, return Error */ retStatus = CY_IPC_DRV_ERROR; } return (retStatus); }