IMX8M mini Cortex M4 SDK ECSPI1 Issue

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

IMX8M mini Cortex M4 SDK ECSPI1 Issue

Jump to solution
1,238 Views
Dhevan
Contributor IV

Hi,

   We are facing issue on ECSPI timing issue.

Dhevan_0-1646675717306.png

In waveform we are seeing issue on write after read delay and chip select in between going to high.

Due to this 9us delay we unable to read data from sensor.

 

/*

 * Copyright (c) 2016, Freescale Semiconductor, Inc.

 * Copyright 2016-2017 NXP

 * All rights reserved.

 *

 * SPDX-License-Identifier: BSD-3-Clause

 */



#include "fsl_device_registers.h"

#include "fsl_debug_console.h"

#include "fsl_ecspi.h"

#include "pin_mux.h"

#include "clock_config.h"

#include "board.h"

#include "fsl_gpt.h"

#include "fsl_gpio.h"

#include "kx134_1211_registers.h"





#define EXAMPLE_LED_GPIO     GPIO5

#define EXAMPLE_LED_GPIO_PIN 9U



#define PT_SPI_READ                                     0x80

#define PT_SPI_WRITE                                    0x7F





/*******************************************************************************

 * Definitions

 ******************************************************************************/

#define EXAMPLE_ECSPI_MASTER_BASEADDR ECSPI1

#define EXAMPLE_ECSPI_DEALY_COUNT     1000000U

#define ECSPI_MASTER_CLK_FREQ                                                                 \

    (CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootEcspi1)) / \

     (CLOCK_GetRootPostDivider(kCLOCK_RootEcspi1)))

#define TRANSFER_SIZE     64U     /*! Transfer dataSize */

#define TRANSFER_BAUDRATE 500000U /*! Transfer baudrate - 500k */



#define GPT_IRQ_ID  GPT1_IRQn

#define EXAMPLE_GPT GPT1

#define EXAMPLE_GPT_CLK_FREQ                                                                \

    (CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootGpt1)) / \

     (CLOCK_GetRootPostDivider(kCLOCK_RootGpt1)) / 2) /* SYSTEM PLL1 DIV2 */

#define EXAMPLE_GPT_IRQHandler GPT1_IRQHandler



/*******************************************************************************

 * Variables

 ******************************************************************************/

uint8_t masterRxData[TRANSFER_SIZE] = {0U};

uint8_t masterTxData[TRANSFER_SIZE] = {0U};

uint8_t pt_txbuf[10], pt_rxbuf[10];

volatile uint32_t g_systickCounter   = 20U;
    ecspi_master_config_t masterConfig;

    ecspi_transfer_t masterXfer;

/*******************************************************************************

 * Prototypes

 ******************************************************************************/



/*******************************************************************************

 * Code

 ******************************************************************************/

void SysTick_Handler(void)

{

    if (g_systickCounter != 0U)

    {

        g_systickCounter--;

    }

}



int loop_count = 0;



void EXAMPLE_GPT_IRQHandler(void)

{

    /* Clear interrupt flag.*/

    GPT_ClearStatusFlags(EXAMPLE_GPT, kGPT_OutputCompare1Flag);

        masterXfer.txData   = (uint32_t *)pt_txbuf;

        masterXfer.rxData   = (uint32_t *)masterRxData;

        masterXfer.dataSize = 7;

        masterXfer.channel  = kECSPI_Channel0;

        GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

        ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);



    //PRINTF("Count - %d \r\n", loop_count);

    //loop_count = 0;

    //PRINTF("ADC Data - %d \r\n", masterRxData[0]);



/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F, Cortex-M7, Cortex-M7F Store immediate overlapping

  exception return operation might vector to incorrect interrupt */

#if defined __CORTEX_M && (__CORTEX_M == 4U || __CORTEX_M == 7U)

    __DSB();

#endif

}



int main(void)

{

    uint32_t gptFreq;

    gpt_config_t gptConfig;

    /* Board specific RDC settings */

    BOARD_RdcInit();



    BOARD_InitPins();

    BOARD_BootClockRUN();

    BOARD_InitDebugConsole();

    BOARD_InitMemory();



    CLOCK_SetRootMux(kCLOCK_RootEcspi1, kCLOCK_EcspiRootmuxSysPll1); /* Set ECSPI2 source to SYSTEM PLL1 800MHZ */

    CLOCK_SetRootDivider(kCLOCK_RootEcspi1, 2U, 5U);                 /* Set root clock to 800MHZ / 10 = 80MHZ */



    PRINTF("ECSPI board to board polling example.\r\n");

    PRINTF("This example use one board as master and another as slave.\r\n");

    PRINTF("Master uses polling way and slave uses interrupt way. \r\n");

    PRINTF("Please make sure you make the correct line connection. Basically, the connection is: \r\n");

    PRINTF("ECSPI_master -- ECSPI_slave   \r\n");

    PRINTF("   CLK      --    CLK  \r\n");

    PRINTF("   PCS      --    PCS \r\n");

    PRINTF("   MOSI     --    MOSI \r\n");

    PRINTF("   MISO     --    MISO  \r\n");

    PRINTF("   GND      --    GND \r\n");



    uint32_t errorCount;

    uint32_t loopCount = 1U;

    uint32_t i;

    status_t status;

    signed short adc_data = 0;



    /* Define the init structure for the output LED pin*/

    gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};



    masterConfig.channel = kECSPI_Channel0;



    /* Master config:

     * masterConfig.channel = kECSPI_Channel0;

     * masterConfig.burstLength = 8;

     * masterConfig.samplePeriodClock = kECSPI_spiClock;

     * masterConfig.baudRate_Bps = TRANSFER_BAUDRATE;

     * masterConfig.chipSelectDelay = 0;

     * masterConfig.samplePeriod = 0;

     * masterConfig.txFifoThreshold = 1;

     * masterConfig.rxFifoThreshold = 0;

     */

    ECSPI_MasterGetDefaultConfig(&masterConfig);

    masterConfig.baudRate_Bps = TRANSFER_BAUDRATE;

    masterConfig.burstLength = 8;

    masterConfig.channelConfig.clockInactiveState    = kECSPI_ClockInactiveStateLow;    /*!< Clock line (SCLK) inactive state */

    masterConfig.channelConfig.dataLineInactiveState = kECSPI_DataLineInactiveStateLow; /*!< Data line (MOSI&MISO) inactive state */

    masterConfig.channelConfig.chipSlectActiveState  = kECSPI_ChipSelectActiveStateLow; /*!< Chip select(SS) line active state */

    masterConfig.channelConfig.polarity              = kECSPI_PolarityActiveHigh;      /*!< Clock polarity */

    masterConfig.channelConfig.phase                 = kECSPI_ClockPhaseFirstEdge;      /*!< clock phase */



    ECSPI_MasterInit(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterConfig, ECSPI_MASTER_CLK_FREQ);



    /* Init output LED GPIO. */

    GPIO_PinInit(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, &led_config);

    GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);



    CLOCK_SetRootMux(kCLOCK_RootGpt1, kCLOCK_GptRootmuxSysPll1Div2); /* Set GPT1 source to SYSTEM PLL1 DIV2 400MHZ */

    CLOCK_SetRootDivider(kCLOCK_RootGpt1, 1U, 4U);                   /* Set root clock to 400MHZ / 4 = 100MHZ */



    GPT_GetDefaultConfig(&gptConfig);



    /* Initialize GPT module */

    GPT_Init(EXAMPLE_GPT, &gptConfig);



    /* Divide GPT clock source frequency by 3 inside GPT module */

    GPT_SetClockDivider(EXAMPLE_GPT, 3);



    /* Get GPT clock frequency */

    gptFreq = EXAMPLE_GPT_CLK_FREQ;



    /* GPT frequency is divided by 3 inside module */

    gptFreq = 2500;



    /* Set both GPT modules to 1 second duration */

    GPT_SetOutputCompareValue(EXAMPLE_GPT, kGPT_OutputCompare_Channel1, gptFreq);



    /* Enable GPT Output Compare1 interrupt */

    GPT_EnableInterrupts(EXAMPLE_GPT, kGPT_OutputCompare1InterruptEnable);



    /* Enable at the Interrupt */

    EnableIRQ(GPT_IRQ_ID);



    PRINTF("\r\nStarting GPT timer ...");

    GPT_StartTimer(EXAMPLE_GPT);

/*

    uint8_t buf[2];



    buf[0] = KX134_1211_CNTL2;

    buf[0] &= PT_SPI_WRITE;

    buf[1] = KX134_1211_CNTL2_SRST;





    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = NULL;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);



    buf[0] = KX134_1211_CNTL2;

    buf[0] |= PT_SPI_READ;

    buf[1] = 0x00;



    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = (uint32_t *)masterRxData;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    PRINTF("CNTL2 - %x %x\r\n", masterRxData[0], masterRxData[1]);



	buf[0] = KX134_1211_CNTL1;

	buf[0] &= PT_SPI_WRITE;

    buf[1] = KX134_1211_CNTL1_POPC1;

    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = NULL;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);



	buf[0] = KX134_1211_CNTL1;

	buf[0] &= PT_SPI_WRITE;

    buf[1] =  KX134_1211_CNTL1_RES | KX134_1211_CNTL1_GSEL_64G;

    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = NULL;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);



	buf[0] = KX134_1211_CNTL1;

	buf[0] |= PT_SPI_READ;

    buf[1] = 0x00;

    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = (uint32_t *)masterRxData;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    PRINTF("CNTL1 - %x %x\r\n", masterRxData[0], masterRxData[1]);





	buf[0] = KX134_1211_ODCNTL;

	buf[0] &= PT_SPI_WRITE;

    buf[1] =  KX134_1211_ODCNTL_OSA_12800 | KX134_1211_ODCNTL_IIR_BYPASS_BYPASSED | KX134_1211_ODCNTL_LPRO_ODR_9;

    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = NULL;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);



	buf[0] = KX134_1211_ODCNTL;

	buf[0] |= PT_SPI_READ;

    buf[1] = 0x00;

    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = (uint32_t *)masterRxData;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    PRINTF("ODCNTL - %x %x\r\n", masterRxData[0], masterRxData[1]);



	buf[0] = KX134_1211_CNTL1;

	buf[0] &= PT_SPI_WRITE;

	//KX134_1211_CNTL1_RES | KX134_1211_CNTL1_GSEL_64G |

    buf[1] =  KX134_1211_CNTL1_RES | KX134_1211_CNTL1_GSEL_64G | KX134_1211_CNTL1_PC1;

    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = NULL;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);



	buf[0] = KX134_1211_CNTL1;

	buf[0] |= PT_SPI_READ;

    buf[1] = 0x00;

    masterXfer.txData   = (uint32_t *)buf;

    masterXfer.rxData   = (uint32_t *)masterRxData;

    masterXfer.dataSize = 2;

    masterXfer.channel  = kECSPI_Channel0;

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

    ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        //GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

    PRINTF("CNTL1 - %x %x\r\n", masterRxData[0], masterRxData[1]);

*/

        pt_txbuf[0] = KX134_1211_XOUT_L;

        pt_txbuf[0] |= PT_SPI_READ;

        pt_txbuf[1] = 0x00;



    while (1)

    {
/*

        pt_txbuf[0] = KX134_1211_WHO_AM_I;

        pt_txbuf[0] |= PT_SPI_READ;

        pt_txbuf[1] = 0x00;



        masterXfer.txData   = (uint32_t *)pt_txbuf;

        masterXfer.rxData   = (uint32_t *)masterRxData;

        masterXfer.dataSize = 2;

        masterXfer.channel  = kECSPI_Channel0;

        GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

        status = ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

        if (status == kStatus_Success){

            PRINTF("Transfer Success \n");

        }

        else{

            PRINTF("Transfer Failed - %d \n", status);

        }

        //adc_data = ((signed short)masterRxData[0] <<  | (masterRxData[1]);

        PRINTF("Who i am - %x %x \r\n", masterRxData[0], masterRxData[1]);

        SDK_DelayAtLeastUs(1000000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        loop_count++;
*/

    }

}

 

How to solve this delay issue ?

Thanks & Regards,

       Vasu

Labels (1)
0 Kudos
1 Solution
1,204 Views
Dhevan
Contributor IV

my issue is resolved.

I have used gpio pin for controlling chip select pin.

receive buffer changed to uint8_t to uint16_t then i can able to read data from sensor.

 

View solution in original post

0 Kudos
3 Replies
1,233 Views
kef2
Senior Contributor V

With ECSPI hardware toggled CS you need to use ECSPIx_CONNREG.BURST_LENGTH (.burstLength in your code) to let ECSPI controller know when to toggle CS back to inactive state. Your code sets .burstLength up once to 8 bits. You need to update it prior to each transfer. Though, I'm not sure if your SDK supports HW CS properly, ECSPI HW CS support in Linux is broken.

0 Kudos
1,224 Views
Dhevan
Contributor IV

Hi @kef2,

Thanks for the reply.

I have changed burst length to 16 bits but it's sending some one byte extra dummy bytes. This solution does not worked.

Now i have used gpio pin for chip select pin but data does not received from processor side but in logic analyzer i could see data is coming form sensor.

Dhevan_0-1646814101368.png\

Processor Side :

 

        pt_txbuf[0] = KX134_1211_WHO_AM_I;

        pt_txbuf[0] |= PT_SPI_READ;

        pt_txbuf[1] = 0x00;



        masterXfer.txData   = (uint32_t *)pt_txbuf;

        masterXfer.rxData   = (uint32_t *)masterRxData;

        masterXfer.dataSize = 2;

        masterXfer.channel  = kECSPI_Channel0;

        GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);

        status = ECSPI_MasterTransferBlocking(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterXfer);

        //SDK_DelayAtLeastUs(5, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

        GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);

        if (status == kStatus_Success){

            PRINTF("Transfer Success \n");

        }

        else{

            PRINTF("Transfer Failed - %d \n", status);

        }

        //adc_data = ((signed short)masterRxData[0] <<  | (masterRxData[1]);

        PRINTF("Who i am - %x %x \r\n", masterRxData[0], masterRxData[1]);

        SDK_DelayAtLeastUs(1000000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

 

 

Debug Message:

 

 

Transfer Success 
                 Who i am - 0 0 
Transfer Success 
                 Who i am - 0 0 
Transfer Success 
                 Who i am - 0 0 
Transfer Success 
                 Who i am - 0 0 
Transfer Success 
                 Who i am - 0 0 

Why receive buffer unable to get data ?

Thanks & Regards,

     Vasu 

0 Kudos
1,205 Views
Dhevan
Contributor IV

my issue is resolved.

I have used gpio pin for controlling chip select pin.

receive buffer changed to uint8_t to uint16_t then i can able to read data from sensor.

 

0 Kudos