This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G3519: SPI time between transfers

Part Number: MSPM0G3519

Tool/software:

Hi, I'm using SPI for a tft display and I measure that when I do a poll for TX FIFO full it takes 1.5 uS between transfers and if I write the TX FIFO without polling it takes 100nS, is it normal? how can I achieve minimun time between transfers?

for (;;) {
        vTaskDelay(pdMS_TO_TICKS(500));
        SPI_Write_9bits(0x15);
        SPI_Write_9bits(0x14);
        SPI_Write_9bits(0x13);
        SPI_Write_9bits(0x12);
        vTaskDelay(pdMS_TO_TICKS(500));
        DL_SPI_transmitData16(SPI_0_INST, 0x15);
        DL_SPI_transmitData16(SPI_0_INST, 0x15);
        DL_SPI_transmitData16(SPI_0_INST, 0x15);
        DL_SPI_transmitData16(SPI_0_INST, 0x15);*/
    }
    
    void SPI_Write_9bits(uint16_t writeData) {
    
    while(DL_SPI_isTXFIFOFull(SPI_0_INST)){};
    DL_SPI_transmitData16(SPI_0_INST, writeData);

    }

I also notice that even if I set DL_SPI_FRAME_FORMAT_MOTO4_POL0_PHA1 the CS line is not held down between transfers, this is the spi config:

static const DL_SPI_Config gSPI_0_config = {
    .mode = DL_SPI_MODE_CONTROLLER,
    .frameFormat = DL_SPI_FRAME_FORMAT_MOTO4_POL0_PHA1,
    .parity = DL_SPI_PARITY_NONE,
    .dataSize = DL_SPI_DATA_SIZE_9,
    .bitOrder = DL_SPI_BIT_ORDER_MSB_FIRST,
    .chipSelectPin = DL_SPI_CHIP_SELECT_0,
};

static const DL_SPI_ClockConfig gSPI_0_clockConfig = {.clockSel = DL_SPI_CLOCK_BUSCLK,
                                                      .divideRatio = DL_SPI_CLOCK_DIVIDE_RATIO_1};

SYSCONFIG_WEAK void SYSCFG_DL_SPI_0_init(void) {
    DL_SPI_setClockConfig(SPI_0_INST, (DL_SPI_ClockConfig *)&gSPI_0_clockConfig);

    DL_SPI_init(SPI_0_INST, (DL_SPI_Config *)&gSPI_0_config);

    DL_SPI_setBitRateSerialClockDivider(SPI_0_INST, 0);


    /* Enable module */
    DL_SPI_enable(SPI_0_INST);
}
The clock is at 80Mhz and SPI at 40Mhz, I'm also using freeRTOS.

thank you in advance

Rafael

  • For Question 2: This gets to the definition of "continuous back-to-back" in TRM (SLAU846B) Sec 19.2.3.1. From history and context I've concluded that this means "The TX FIFO never goes empty".  With SCK = CPUCLK/2 you have 18 CPU clocks to get the next frame into the FIFO. This is fewer than it seems, and it seems not unlikely the frame could get shifted out before you write the next frame, which puts you into the "single-word transfer" category so /CS is de-asserted. This is one of many reasons I always do /CS with a GPIO.

    For Question 1: I find it plausible that DL_SPI_isTXFIFOFull adds some overhead. I wonder where 100ns comes from -- my calculator says a 9-bit frame at 40MHz takes 225ns. As I recall that's an inline function, so maybe it can be improved with -Os (or similar). I expect DMA could help as well.

    [Edit: Forgot to mention DMA.]

  • For Question 1: I find it plausible that DL_SPI_isTXFIFOFull adds some overhead. I wonder where 100ns comes from -- my calculator says a 9-bit frame at 40MHz takes 225ns. As I recall that's an inline function, so maybe it can be improved with -Os (or similar). I expect DMA could help as well.

    DL_SPI_isTXFIFOFull just read a register (return ((spi->STAT & SPI_STAT_TNF_MASK) == SPI_STAT_TNF_FULL);) but maybe this register is not updated that fast and I get this 1.5 uS delay.

    For Question 2: This gets to the definition of "continuous back-to-back" in TRM (SLAU846B) Sec 19.2.3.1. From history and context I've concluded that this means "The TX FIFO never goes empty".  With SCK = CPUCLK/2 you have 18 CPU clocks to get the next frame into the FIFO. This is fewer than it seems, and it seems not unlikely the frame could get shifted out before you write the next frame, which puts you into the "single-word transfer" category so /CS is de-asserted. This is one of many reasons I always do /CS with a GPIO.

    You are right, I lowered the clock to 20MHz and now I see a continuous transmission without time between transfers and CS holding low(only in the no polling code), I don't know why DL_SPI_transmitData16() is not fast enough when SPI is at 40MHz, it writes a value to the TXDATA regsiter, can it take more than 18 CPU clocks? I will try to implement DMA to se if I can get a continuous back-to-back transmission at 40MHz.

    Thank you for your help

  • Another of my "many reasons" is when my brain inserts a (hypothetical) stray timer interrupt in the middle of loading the FIFO. Yet another is envisioning the DMA unit round-robin-ing to another channel in the middle of loading the FIFO. These are ordinary foreseeable (though unpredictable) events that will wreck my SPI transaction. My conclusion has been that "continuous back-to-back" is too tenuous to rely on, so I control /CS myself to make sure.

    That said: I expect (from experience) that DMA will improve your TFT updates.