LPSPI and EDMA MIMXRT1042 Delay

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

LPSPI and EDMA MIMXRT1042 Delay

Jump to solution
1,921 Views
adde_ado
Contributor III

Hello,

I am working on a custom board that is based on MIMXRT1042 and my issue is that I have a delay between every frame transaction on the LPSPI bus during communication with a display.

Data that is transferred can be a few bytes or up to (32*1024U - 1) bytes per chunk.

LPSPI_CLK_ROOT is configured to 132MHz and transfer baud rate is 50MHz.

The delay between frames is ~74ns (see the attached image) and that is affecting the display frame rate. 

Can that delay be removed and if not what can I do to reduce it even more?

Best regards,

Adde

Tags (2)
0 Kudos
Reply
1 Solution
1,817 Views
adde_ado
Contributor III

Hi Miguel,

I have increased LPSPI bitsPerFrame from 8 to 16 and I don't see any delays between transactions. The display frame rate is ~34 fps that is acceptable.

Thanks for the support!

Best regards,

Adde

 

View solution in original post

0 Kudos
Reply
5 Replies
1,894 Views
lucas_cao
NXP Employee
NXP Employee

The max baudrate is 30M

lucas_cao_0-1679449743287.png

 

0 Kudos
Reply
1,899 Views
Miguel04
NXP TechSupport
NXP TechSupport

Hi @adde_ado 

Can you tell me the display you are using? Also, make sure to use the SDK examples to avoid a peripheral configuration issue.

I'll be looking into your problem, however, since you are using a custom board, we cannot discard any hardware issues.

Best Regards, Miguel.

0 Kudos
Reply
1,886 Views
adde_ado
Contributor III

Hi Miguel and Lucas, 

The display we are using is ST7789V2 and LPSPI communication is One-directional (CPU to Display). 

We are using latest SDK (SDK_2_13_0_MIMXRT1042xxxxB) and our LPSPI/EDMA code is more or less based on example from SDK.

I have now decreaset baudrate to 30MHz but I still have delay between frames (see the attached image).

This is my source code that is relevant for LPSPI/EDMA.

 

#define LPSPI_MASTER_BASEADDR             (LPSPI1)


//#define TRANSFER_BAUDRATE               5000000U /*! Transfer baudrate - 5 MHz */
//#define TRANSFER_BAUDRATE               10000000U /*! Transfer baudrate - 10 MHz */
//#define TRANSFER_BAUDRATE               20000000U /*! Transfer baudrate - 20 MHz */
#define TRANSFER_BAUDRATE               30000000U /*! Transfer baudrate - 30 MHz */
//#define TRANSFER_BAUDRATE               40000000U /*! Transfer baudrate - 40 MHz */
//#define TRANSFER_BAUDRATE               50000000U /*! Transfer baudrate - 50 MHz */
#define LPSPI_MASTER_PCS_FOR_INIT       (kLPSPI_Pcs0)
#defi

#define LPSPI_MASTER_DMA_MUX_BASEADDR      (DMAMUX)
#define LPSPI_MASTER_DMA_RX_REQUEST_SOURCE kDmaRequestMuxLPSPI1Rx
#define LPSPI_MASTER_DMA_TX_REQUEST_SOURCE kDmaRequestMuxLPSPI1Tx
#define LPSPI_MASTER_DMA_BASEADDR          (DMA0)
#define LPSPI_MASTER_DMA_RX_CHANNEL        1U
#define LPSPI_MASTER_DMA_TX_CHANNEL        3U
#define MAX_TRANSMIT_SIZE_FOR_EDMA         (32*1024U - 1)

/* LPSPI user callback */
void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, status_t status, void *userData);
static uint32_t st7789v2_hal_split_in_chunks(uint32_t items_to_transmit,  uint32_t * chunk_size);

AT_NONCACHEABLE_SECTION_INIT(lpspi_master_edma_handle_t g_m_edma_handle) = {0};
edma_handle_t lpspiEdmaMasterRxRegToRxDataHandle;
edma_handle_t lpspiEdmaMasterTxDataToTxRegHandle;
edma_config_t userConfig = {0};
volatile BOOL isTransferCompleted  = false;
void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, status_t status, void *userData)
{

    if (status == kStatus_Success)
    {
        __NOP();
    }

    isTransferCompleted = TRUE;
}


   IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK, 0);   // SPI clock         GPIO_SD_B0_00                          LCD_SCLK1       SCL
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0, 0);  // SPI chip select   GPIO_SD_B0_01                          LCD_/CSB        CSX
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO, 0);   // SDA (data)        GPIO_SD_B0_02                          LCD_SDA         SDA
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI, 0);   // SDA2              GPIO_SD_B0_03                          LCD_SDA2        SDA2/WRX

******************************** configure LPSPI/EDMA ***********************
    /* DMA MUX init*/
    DMAMUX_Init(LPSPI_MASTER_DMA_MUX_BASEADDR);

    DMAMUX_SetSource(LPSPI_MASTER_DMA_MUX_BASEADDR, LPSPI_MASTER_DMA_RX_CHANNEL,
            LPSPI_MASTER_DMA_RX_REQUEST_SOURCE);
    DMAMUX_EnableChannel(LPSPI_MASTER_DMA_MUX_BASEADDR, LPSPI_MASTER_DMA_RX_CHANNEL);

    DMAMUX_SetSource(LPSPI_MASTER_DMA_MUX_BASEADDR, LPSPI_MASTER_DMA_TX_CHANNEL,
            LPSPI_MASTER_DMA_TX_REQUEST_SOURCE);
    DMAMUX_EnableChannel(LPSPI_MASTER_DMA_MUX_BASEADDR, LPSPI_MASTER_DMA_TX_CHANNEL);

    EDMA_GetDefaultConfig(&userConfig);
	userConfig.enableRoundRobinArbitration = true;
    EDMA_Init(LPSPI_MASTER_DMA_BASEADDR, &userConfig);

    // To use the second data lane: CFGR1[PCSCFG] = 1 --> Use pin PCS2/DATA[2] as data 2. See [2], Table 45.12.
    LPSPI_Reset(LPSPI_MASTER_BASEADDR);


    /*Master config*/
    LPSPI_MasterGetDefaultConfig(&masterConfig);
    masterConfig.baudRate = TRANSFER_BAUDRATE;
    masterConfig.whichPcs = LPSPI_MASTER_PCS_FOR_INIT;
    masterConfig.bitsPerFrame = 8; // 8 bits to transfer.
    masterConfig.pinCfg = kLPSPI_SdiInSdoOut; // According to [2], page 2625, PINCFG: "If performing parallel transfers, the Pin Configuration field must be 00."
    masterConfig.betweenTransferDelayInNanoSec = 1000000000 / (masterConfig.baudRate * 2);
    masterConfig.dataOutConfig = kLpspiDataOutRetained;
    masterConfig.cpha = kLPSPI_ClockPhaseSecondEdge; // kLPSPI_ClockPhaseFirstEdge
    masterConfig.cpol = kLPSPI_ClockPolarityActiveLow;

    srcClock_Hz = BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT; //132MHz;
    LPSPI_MasterInit(LPSPI_MASTER_BASEADDR, &masterConfig, srcClock_Hz);

    LPSPI_Enable(LPSPI_MASTER_BASEADDR, false);
    LPSPI_MASTER_BASEADDR->CR |= LPSPI_CR_DBGEN(1); // Support debugging.
    // Change PCS[3:2] from chip selects to be used as data lines. See [2] page 2624.
    LPSPI_MASTER_BASEADDR->CFGR1 &= ~(LPSPI_CFGR1_PCSCFG_MASK);
    LPSPI_MASTER_BASEADDR->CFGR1 |= LPSPI_CFGR1_PCSCFG(1);
    LPSPI_MASTER_BASEADDR->SR |= LPSPI_SR_TCF_MASK; // Clear Transfer Complete Flag.
    LPSPI_Enable(LPSPI_MASTER_BASEADDR, true);

    /*Set up lpspi master*/
    memset(&(lpspiEdmaMasterRxRegToRxDataHandle), 0, sizeof(lpspiEdmaMasterRxRegToRxDataHandle));
    memset(&(lpspiEdmaMasterTxDataToTxRegHandle), 0, sizeof(lpspiEdmaMasterTxDataToTxRegHandle));

    EDMA_CreateHandle(&(lpspiEdmaMasterRxRegToRxDataHandle), LPSPI_MASTER_DMA_BASEADDR,
            LPSPI_MASTER_DMA_RX_CHANNEL);
    EDMA_CreateHandle(&(lpspiEdmaMasterTxDataToTxRegHandle), LPSPI_MASTER_DMA_BASEADDR,
            LPSPI_MASTER_DMA_TX_CHANNEL);

    LPSPI_MasterTransferCreateHandleEDMA(LPSPI_MASTER_BASEADDR, &g_m_edma_handle, LPSPI_MasterUserCallback,
            NULL, &lpspiEdmaMasterRxRegToRxDataHandle,
            &lpspiEdmaMasterTxDataToTxRegHandle);

************************* Start Transffer **************************


 masterXfer.rxData = NULL;
 masterXfer.configFlags = LPSPI_MASTER_PCS_FOR_TRANSFER |  kLPSPI_MasterByteSwap | kLPSPI_MasterPcsContinuous;
  
 masterXfer.txData = tx_data;
 masterXfer.dataSize = items_to_transmit * bytes_per_item;
 isTransferCompleted = FALSE;
 LPSPI_MasterTransferEDMA(LPSPI_MASTER_BASEADDR, &g_m_edma_handle, &masterXfer);

      /* Wait until transfer completed */
                while (!isTransferCompleted)
                {
                }
            }

 

 

I have also seen that others have had similara issues but I don't know how thay have solved it.

They are using a different CPU (1050).

https://community.nxp.com/t5/i-MX-Processors/LPSPI-and-EDMA-RT1050-Too-Slow/td-p/1269109 

Best regards,

Adde

 

 

 

 

0 Kudos
Reply
1,869 Views
Miguel04
NXP TechSupport
NXP TechSupport

Hi @adde_ado 

According to the community thread, the customer added a delay between the transfers and jeremyzhou posted some steps to transfer the data faster.

"1) The steps of modifying the lpspi_edma_b2b_transfer_master demo (SDK library version is 2.8.5)
a) in lpspi_edma_b2b_transfer_master.c, increae the number of tranmit data and transfer baudrate."

See the complete reply and follow the steps using the parameters you need for the display.

Best Regards, Miguel.

0 Kudos
Reply
1,818 Views
adde_ado
Contributor III

Hi Miguel,

I have increased LPSPI bitsPerFrame from 8 to 16 and I don't see any delays between transactions. The display frame rate is ~34 fps that is acceptable.

Thanks for the support!

Best regards,

Adde

 

0 Kudos
Reply