Why use semaphores for SPI data transmission

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why use semaphores for SPI data transmission

667 Views
qiansan
Contributor I

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;
}
0 Kudos
Reply
1 Reply

654 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

the semaphore is used for synchronization between tasks and for timeout when transferring a data.

Can you see any issues?

Regards,

Lukas

0 Kudos
Reply