In s32k144 using FOC control demo based on FreeRTOS operating system, the transmission of SPI data uses counting semaphores. I want to know what the function of using counting semaphores here is
status_t LPSPI_DRV_MasterTransferBlocking(uint32_t instance,
const uint8_t * sendBuffer,
uint8_t * receiveBuffer,
uint16_t transferByteCount,
uint32_t timeout)
{
DEV_ASSERT(instance < LPSPI_INSTANCE_COUNT);
DEV_ASSERT(g_lpspiStatePtr[instance] != NULL);
/* Instantiate local variable of type lpspi_state_t and point to global state */
lpspi_state_t * lpspiState = g_lpspiStatePtr[instance];
LPSPI_Type *base = g_lpspiBase[instance];
status_t error = STATUS_SUCCESS;
status_t osifError;
/* If the transfer count is zero, then return immediately.*/
if (transferByteCount == (uint16_t)0)
{
return error;
}
/* Check if another transfer is in progress */
if (LPSPI_GetStatusFlag(base, LPSPI_MODULE_BUSY))
{
return STATUS_BUSY;
}
/* Dummy wait to ensure the semaphore is 0, no need to check result */
(void)OSIF_SemaWait(&(lpspiState->lpspiSemaphore), 0);
lpspiState->isBlocking = true;
error = LPSPI_DRV_MasterStartTransfer(instance, sendBuffer, receiveBuffer,
transferByteCount);
/* Start the transfer process, if it returns an error code, return this back to user */
if (error != STATUS_SUCCESS)
{
/* Disable interrupt requests*/
LPSPI_SetIntMode(base, LPSPI_TX_DATA_FLAG, false);
LPSPI_SetIntMode(base, LPSPI_RX_DATA_FLAG, false);
LPSPI_DRV_DisableTEIEInterrupts(instance);
LPSPI_SetIntMode(base, LPSPI_TRANSFER_COMPLETE, false);
(void)LPSPI_ClearStatusFlag(base, LPSPI_TRANSFER_COMPLETE);
lpspiState->isBlocking = false;
return error;
}
/* As this is a synchronous transfer, wait until the transfer is complete.*/
osifError = OSIF_SemaWait(&(lpspiState->lpspiSemaphore), timeout);
/* If a timeout occurs, stop the transfer by setting the isTransferInProgress to false and
* disabling interrupts, then return the timeout error status.
*/
if (osifError == STATUS_TIMEOUT)
{
/* Set isBlocking variable to false to avoid dummy semaphore post. */
lpspiState->isBlocking = false;
/* Complete transfer. */
LPSPI_DRV_MasterCompleteTransfer(instance);
return(STATUS_TIMEOUT);
}
LPSPI_DRV_DisableTEIEInterrupts(instance);
LPSPI_SetIntMode(base, LPSPI_TRANSFER_COMPLETE, false);
(void)LPSPI_ClearStatusFlag(base, LPSPI_TRANSFER_COMPLETE);
return error;
}
Hi,
the semaphore is used for synchronization between tasks and for timeout when transferring a data.
Can you see any issues?
Regards,
Lukas