Hi,
I am facing problems with fsl_spi_freertos API lib. When I use SPI_RTOS_Transfer() method (see detail below) with a output data length less then 4 bytes, SPI_RTOS_Transfer() stuck forever at :
/* Wait for transfer to finish */ xSemaphoreTake(handle->event, portMAX_DELAY);
portMAX_DELAY set timeout to an infinity duration. And if I change portMAX_DELAY to 100ms for example, error happen at next call of SPI_RTOS_Transfer() with an error type kStatus_SPI_Busy. So no transfer occurred at the second call.
To resume :
//Call with timeout = portMAX_DELAY SPI_RTOS_Transfer() //Wait transfer to finish for ever ... //First call with timeout = 100ms. SPI_RTOS_Transfer() //Ok, no problem //Second call and so on SPI_RTOS_Transfer() //method return error kStatus_SPI_Busy
Now, if a I do the same thing with 4 bytes output, SPI_RTOS_Transfer() don't block at all in any case...
And this is pretty annoying because my application does a lot of quick SPI transfer with less then 4 bytes.
So why and how can I solve this ?
I am working with FRDM-KL46Z, KSDKv2, KDSv3
Here is the FreeRTOS SPI method (from fsl_spi_freertos.c)
status_t SPI_RTOS_Transfer(spi_rtos_handle_t *handle, spi_transfer_t *transfer) { status_t status; /* Lock resource mutex */ if (xSemaphoreTake(handle->mutex, portMAX_DELAY) != pdTRUE) { return kStatus_SPI_Busy; } status = SPI_MasterTransferNonBlocking(handle->base, &handle->drv_handle, transfer); if (status != kStatus_Success) { xSemaphoreGive(handle->mutex); return status; } /* Wait for transfer to finish */ xSemaphoreTake(handle->event, portMAX_DELAY); /* Unlock resource mutex */ xSemaphoreGive(handle->mutex); /* Return status captured by callback function */ return handle->async_status; }
Ok thank you.
I am using the blocking SPI_MasterTransferBlocking() method. It work but I really prefer to use the non blocking SPI_RTOS_Transfer() method in order to have a better integrity with FreeRTOS philosophy.
Waiting for your update.
Hi Maxime:
Have you enabled tx FIFO mode?
Regards
Daniel
Hi Daniel,
I initialise SPI with API function SPI_MasterGetDefaultConfig() :
void SPI_MasterGetDefaultConfig(spi_master_config_t *config)
{
config->enableMaster = true;
config->enableStopInWaitMode = false;
config->polarity = kSPI_ClockPolarityActiveHigh;
config->phase = kSPI_ClockPhaseFirstEdge;
config->direction = kSPI_MsbFirst;
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
config->dataMode = kSPI_8BitMode;
#endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
config->txWatermark = kSPI_TxFifoOneHalfEmpty;
config->rxWatermark = kSPI_RxFifoOneHalfFull;
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
config->pinMode = kSPI_PinModeNormal;
config->outputMode = kSPI_SlaveSelectAutomaticOutput;
config->baudRate_Bps = 500000U;
}
Lines betwen FSL_FEATURE_SPI_HAS_FIFO are not greyed, so I guess that tx FIFO is enabled but not sure (?)
I checked my SPI port and I can see correct bytes outputs.
Still have no idea what is wrong.
Hi Maxime:
There is a watermark feature when FIFO is enabled. When the data < water mark, the SPI module is requesting more entries to be added to the TxFIFO. From your description, it seems the water mark is 32 bits.
I think you can try to disable the FIFO feature if you need to transfer data less than 4 bytes
Regards
Daniel