/******************************************************************************* * Function Name: Cy_IPC_Sema_Status ****************************************************************************//** * * This function returns the status of the semaphore. * * \param semaNumber * The index of the semaphore to return status. * * \return Status of the operation * \retval CY_IPC_SEMA_STATUS_LOCKED: The semaphore is in the set state. * \retval CY_IPC_SEMA_STATUS_UNLOCKED: The semaphore is in the cleared state. * \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_Status * *******************************************************************************/ cy_en_ipcsema_status_t Cy_IPC_Sema_Status(uint32_t semaNumber) { cy_en_ipcsema_status_t retStatus; uint32_t semaIndex; uint32_t semaMask; cy_stc_ipc_sema_t *semaStruct; /* Get pointer to structure */ semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct); if (semaNumber < semaStruct->maxSema) { /* Get the index into the semaphore array and calculate the mask */ semaIndex = semaNumber / CY_IPC_SEMA_PER_WORD; semaMask = (uint32_t)(1ul << (semaNumber - (semaIndex * CY_IPC_SEMA_PER_WORD) )); if((semaStruct->arrayPtr[semaIndex] & semaMask) != 0ul) { retStatus = CY_IPC_SEMA_STATUS_LOCKED; } else { retStatus = CY_IPC_SEMA_STATUS_UNLOCKED; } } else { retStatus = CY_IPC_SEMA_OUT_OF_RANGE; } return(retStatus); }
/******************************************************************************* * Function Name: Cy_IPC_Sema_GetMaxSems ****************************************************************************//** * * This function returns the number of semaphores in the semaphores subsystem. * * \return * Returns the semaphores quantity. * * \funcusage * \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Sema_GetMaxSems * *******************************************************************************/ uint32_t Cy_IPC_Sema_GetMaxSems(void) { cy_stc_ipc_sema_t *semaStruct; /* Get pointer to structure */ semaStruct = (cy_stc_ipc_sema_t *)Cy_IPC_Drv_ReadDataValue(cy_semaIpcStruct); return (semaStruct->maxSema); }
/******************************************************************************* * 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_ReadMsgWord ****************************************************************************//** * * This function is used to read a 32-bit word message through an IPC channel. * This function assumes that the channel is locked (for a valid message). * If the channel is not locked, the message is invalid. The user must call * Cy_IPC_Drv_Release() function after reading the message to release the * IPC 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 message * A variable where the read data is copied. * * \return Status of the operation * \retval CY_IPC_DRV_SUCCESS: The function executed successfully and the IPC * was acquired. * \retval CY_IPC_DRV_ERROR: The function encountered an error because the IPC * channel was already in a released state, meaning the data * may be invalid. * * \funcusage * \snippet IPC_sut_01.cydsn/main_cm4.c snippet_Cy_IPC_Drv_ReadMsgWord * *******************************************************************************/ cy_en_ipcdrv_status_t Cy_IPC_Drv_ReadMsgWord (IPC_STRUCT_Type const * base, uint32_t * message) { cy_en_ipcdrv_status_t retStatus; CY_ASSERT_L1(NULL != message); if ( Cy_IPC_Drv_IsLockAcquired(base) ) { /* The channel is locked; message is valid. */ *message = Cy_IPC_Drv_ReadDataValue(base); retStatus = CY_IPC_DRV_SUCCESS; } else { /* The channel is not locked so channel is invalid. */ retStatus = CY_IPC_DRV_ERROR; } return(retStatus); }