AnsweredAssumed Answered

i-MX7 - Chip Select Signal behavior with SS_CTL

Question asked by einarikoivu on Feb 12, 2016
Latest reply on Jul 12, 2017 by Yuri Muhin

I'm trying to implement a driver for an SPI peripheral. The code would be executed in M4. I'm using the Sabre board Rev B

 

The peripheral requires the data in a format of 9-bit words, the first bit is a control bit followed by eight data bits. The Chip Select signal must be active diring the whole data transfer.

 

For that, I need to have burst length of 9 bits. (BURST_LENGTH = 8). The behavior of the Chip Select should be controlled by SS_CTL. My problem is that SS_CTL has no effect on the behavior of the Chip Select.

 

I have set SMC (Start Mode Control) to zero, as suggested by the reference manual. After that I write four 9-bit words to TXFIFO and start the burst with writing to XCH. This sends the first 9-bit burst and negates the Chip Select back to inactive. After Writing to XCH three more times, all data is sent, but the Chip Select signal negates between all bursts.

 

This (Figure 10-8) is what I expect, with 9-bit words:

correct.png

But this (Figure 10-9) is what I get, regardless of the position of SS_CTL bits

incorrect.png

 

In Linux this seems to work. However, I haven't checked, is the Chip Select implemented by SW or by HW.

 

I have been testing the functionality with a sligthly modified version of the example ecspi code in the board support package. (FreeRTOS_BSP_1.0.0_iMX7D)

 

 

ECSPI_SetSSMultipleBurst(BOARD_ECSPI3_BASEADDR, ecspiSelectChannel0, false);
ecspi_init_t ecspiInitConfig = {
    .clockRate = get_ecspi_clock_freq(BOARD_ECSPI3_BASEADDR),
    .baudRate = 500000,
    .mode = ecspiMasterMode,
    .burstLength = 8, // 9 -1
    .channelSelect = ecspiSelectChannel0,
    .clockPhase = ecspiClockPhaseSecondEdge,
    .clockPolarity = ecspiClockPolarityActiveLow,
    .ecspiAutoStart = false
};
ECSPI_XFER_Config(&ecspiInitConfig);

...

 

bool ECSPI_XFER_TransmitBurst(int command)
{
    uint8_t bytes;
    uint32_t data;

    ECSPI_SetBurstLength(ECSPI3, 8); // 9 bits - 1
    
    /* Fill the TXFIFO */
    while((ecspiState.txSize > 0) && (ECSPI_GetStatusFlag(ECSPI3, ecspiFlagTxfifoFull) == 0))
    {
        bytes = 1;             

        if(!(ecspiState.txBuffPtr))
        {
            data = 0xFFFFFFFF;
        }
        else
        {
            data = 0;
            data = *(ecspiState.txBuffPtr)++;
            if (command)
            {
                command = 0;
            }
            else
            {
                data |= 1 << 8;
            }
        }
               
        ECSPI_SendData(ECSPI3, data);
        
        ecspiState.txSize -= bytes;
        if(ecspiState.rxBuffPtr)
        {
            ecspiState.rxSize += bytes;
        }
    }
    /* start transmission */
    ECSPI_StartBurst(ECSPI3); // Transfer the first word

    while(ECSPI_GetTxfifoCounter(ECSPI3) > 0)
    {
        // Transfer the rest of the words
        while(ECSPI_GetStatusFlag(ECSPI3, ecspiFlagTxfifoTc) == 0);
        ECSPI_StartBurst(ECSPI3);
    }
    return true;
}

 

Questions:

- Is there something wrong with my configuration, or is the HW working incorrectly? Of course the SW developers tend to blame HW rather than own code.

- Should Writing to XCH transfer all words that are in TXFIFO or just the first one, like in my case?

Outcomes