I want to configure S32K144 DMA to communicate with an external SPI FRAM/FLASH chip, but I am not able to find any example with processor expert how to configure DMA and LPSPI for this application and how to access FRAM read and write. Kindly give some example project or correct method to do this using PE.
Solved! Go to Solution.
Hi @Selva24,
The example showcases a simple way to configure the eDMA and the LPSPI modules. The EDMA_DRV_Init function configures the DMA component, and both LPSPI_DRV_MasterTransfer/SlaveTransfer trigger a MultiBlock transfer if DMA is configured. It is meant to be used as reference and showcases the basic configuration for these peripherals.
You can also take a look at the edma_transfer_s32k144 example, which may prove more useful for understanding the DMA driver. It demonstrates the following eDMA use cases:
Depending on the transfer method, it uses one of the functions you mentioned. You could either configure a loop transfer or a multiblock transfer each time the LPSPI module triggers, as the example shows.
Best regards,
Julián
Hi @Selva24,
You can use the included example from the RTM v3.0.0:
There is also this non-SDK example, which uses the PIT module, and every trigger starts a minor DMA loop (8 bytes) transfer to the LPSPI1 TX FIFO: Example S32K144 LPIT DMA LPSPI - NXP Community.
Best regards,
Julián
I have written the following code. With this I am able to read ID of FLASH chip using LPSPI_DRV_MasterTransferBlocking function.
I also tried to use EDMA_DRV_ConfigSingleBlockTransfer function to do the same but with this I am not able to read the received data from FLASH chip, although on scope I can verify correct data is received from external FLASH in both case.
What should be done so that I can receive data using EDMA_DRV_ConfigSingleBlockTransfer function. I have noticed that clock pulses are only output when data is sent to external flash i.e. in TX mode. In RX mode no clock is sent so I have sent dummy 3-byte data to receive 3 bytes of data from FLASH. But I believe I should send 1 byte data in TX and receive 3byte data in RX if using EDMA driver. Let me know what I am doing wrong here.
#include "Cpu.h"
volatile int exit_code = 0;
uint32_t JEDEC_ID;
uint32_t JEDEC_DMA_ID;
uint64_t UNIQUE_ID;
uint8_t SendData[10];
uint8_t ReceiveData[10];
uint8_t ReceiveDataDMA[10];
uint8_t TxDataSize;
/* User includes (#include below this line is not maintained by Processor Expert) */
#define TIMEOUT 10
int main(void)
{
/* Processor Expert internal initialization */
#ifdef PEX_RTOS_INIT
PEX_RTOS_INIT();
#endif
/* Clock and Pin Initialization */
CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT, g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);
EDMA_DRV_Init(&dmaController1_State, &dmaController1_InitConfig0, edmaChnStateArray, edmaChnConfigArray, EDMA_CONFIGURED_CHANNELS_COUNT);
/* Initialize LPSPI2 */
LPSPI_DRV_MasterInit(LPSPICOM2, &lpspiCom2State, &lpspiCom2_MasterConfig0);
LPSPI_DRV_MasterSetDelay(LPSPICOM2, 1, 1, 1);
JEDEC_ID = 0;
JEDEC_DMA_ID = 0;
/* Send command 0x9F to read status */
SendData[0] = 0x9F;
SendData[1] = 0xFF;
SendData[2] = 0xFF;
SendData[3] = 0xFF;
TxDataSize = 0x04;
LPSPI_DRV_MasterTransferBlocking(LPSPICOM2, &SendData, &ReceiveData, TxDataSize, TIMEOUT);
JEDEC_ID = ((ReceiveData[1] << 16) | (ReceiveData[2] << | (ReceiveData[3]));
/* Configure DMA for the next transfer */
EDMA_DRV_ConfigSingleBlockTransfer(EDMA_CHN1_NUMBER, EDMA_TRANSFER_MEM2PERIPH, SendData,
(uint32_t)&(LPSPI2->TDR), EDMA_TRANSFER_SIZE_1B, 4);
EDMA_DRV_ConfigSingleBlockTransfer(EDMA_CHN0_NUMBER, EDMA_TRANSFER_PERIPH2MEM, (uint32_t)&(LPSPI2->RDR),
ReceiveDataDMA, EDMA_TRANSFER_SIZE_1B, 3);
/* Start the SPI transfer using DMA */
EDMA_DRV_TriggerSwRequest(EDMA_CHN1_NUMBER); // Trigger the DMA to start sending the command
EDMA_DRV_TriggerSwRequest(EDMA_CHN0_NUMBER); // Trigger the DMA to start receiving the data
OSIF_TimeDelay(100); // mS Delay
while (1);
/* RTOS startup code */
#ifdef PEX_RTOS_START
PEX_RTOS_START();
#endif
for (;;)
{
if (exit_code != 0)
{
break;
}
}
return exit_code;
}
I have used lpspi_dma_s32k144 example and able to send receive data with this. But I am confused if this is proper method of using DMA for data transfer with an external FRAM/FLASH device. I was assuming we have to use:
EDMA_DRV_ConfigSingleBlockTransfer();
EDMA_DRV_ConfigLoopTransfer();
EDMA_DRV_ConfigScatterGatherTransfer();
EDMA_DRV_ConfigMultiBlockTransfer();
one of these functions to do data transfer. Am I wrong? When will this function be used can someone clarify?
What I want to do is I have to store a data log from processor to external FRAM device at periodic intervals and after some particular time or memory fill, I want to transfer FRAM data into external Flash. My FRAM and FLASH will be on same SPI lines with different CS. In this case DMA should take the load off processor and do all this automatically without or with minimum main processor intervention. So which method will be proper way? Is lpspi_dma_s32k144 example correct method or I have to use one of above function or any other function of EDMA driver. I believe EDMA driver should be configured for this, but I am not able to get the correct way to do it. Also, I would prefer to use SDK or processor expert functions to do it. Can you guide me in the right way to achieve this.
Hi @Selva24,
The example showcases a simple way to configure the eDMA and the LPSPI modules. The EDMA_DRV_Init function configures the DMA component, and both LPSPI_DRV_MasterTransfer/SlaveTransfer trigger a MultiBlock transfer if DMA is configured. It is meant to be used as reference and showcases the basic configuration for these peripherals.
You can also take a look at the edma_transfer_s32k144 example, which may prove more useful for understanding the DMA driver. It demonstrates the following eDMA use cases:
Depending on the transfer method, it uses one of the functions you mentioned. You could either configure a loop transfer or a multiblock transfer each time the LPSPI module triggers, as the example shows.
Best regards,
Julián
Hi @Selva24,
The LPSPI_DRV_MasterTransferBlocking will still block the processor since the function does not return any value until the transfer is complete. DMA only helps with memory to peripheral (or peripheral to peripheral) data transmission once the transfer is completed.
Best regards,
Julián
Hi @Selva24,
Yes, that is correct.