IMX8M mini Cortex M4 SDK ECSPI1 Issue

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

IMX8M mini Cortex M4 SDK ECSPI1 Issue

跳至解决方案
1,188 次查看
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

标签 (1)
0 项奖励
1 解答
1,154 次查看
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 项奖励
3 回复数
1,183 次查看
kef2
Senior Contributor IV

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 项奖励
1,174 次查看
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 项奖励
1,155 次查看
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 项奖励