Ok, there seems to be problems with transfers >16 bytes (i.e. more than the SPI FIFO capacity) with both Interrupt and DMA modes when there is no Rx buffer (half duplex, i.e. NULL for receiveBuffer in the LPSPI_DRV_MasterTransferBlocking() call). In both cases it seems to be unhandled receive overruns.
To get Interrupt driven half duplex working I had to make a change to
S32SDK_S32K14x_EAR_0.8.4/platform/drivers/src/lpspi/lpspi_master_driver.c .
In LPSPI_DRV_MasterIRQHandler(), I replaced the existing code:
if(LPSPI_GetStatusFlag(base,LPSPI_RX_DATA_FLAG) && (rxCount != (uint16_t)0))
{
LPSPI_DRV_ReadRXBuffer(instance);
}
...with this:
if (rxCount) {
if (LPSPI_GetStatusFlag(base,LPSPI_RX_DATA_FLAG))
{
LPSPI_DRV_ReadRXBuffer(instance);
}
} else {
/* No RX wanted so clear RX FIFO -- Pontus Hedman 20171031 */
LPSPI_SetFlushFifoCmd(base, false, true);
}
That seemed to take care of IRQ driven code. Meanwhile, to get DMA half duplex with >16 byte transfers working, I had to change LPSPI_DRV_MasterStartTransfer() in the same file. I replaced the existing code:
LPSPI_SetIntMode(base,LPSPI_RECEIVE_ERROR , true);
...with this conditional code:
/* Catch Rx errors only if we actually want to receive -- Pontus Hedman 20171031 */
if (receiveBuffer) {
LPSPI_SetIntMode(base, LPSPI_RECEIVE_ERROR , true);
}
In addition, in my main() of the lpspi_transfer_s32k144 sample project I had to turn on NOSTALL so the SPI doesn't choke when transferring more than 16 bytes (FIFO capacity):
/* Don't stall on Rx FIFO overrun on large DMAs; don't care in half duplex */
LPSPI_Disable(g_lpspiBase[SEND]);
g_lpspiBase[SEND]->CFGR1 |= LPSPI_CFGR1_NOSTALL(1);
LPSPI_Enable(g_lpspiBase[SEND]);
I don't know if this is all the best or even correct solution, but it seems to work. I'm not keen on the NOSTALL since it can cause Tx underruns, but from testing I haven't seen any.
Feedback appreciated...