查看: 1552|回复: 2

[讨论] RT1064 LPI2C异常

[复制链接]
  • TA的每日心情
    郁闷
    2022-4-20 09:47
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    1

    主题

    6

    帖子

    0

    新手上路

    Rank: 1

    积分
    39
    最后登录
    2022-4-20
    发表于 2021-10-28 14:55:58 | 显示全部楼层 |阅读模式
    在RT1064芯片使用中,遇到LPI2C总线异常,同样代码在RT1062上没问题,LPI2C引脚:
    如LPI2C配置。
    代码就拿的SDK例程代码:

    /*
    * Copyright 2017 NXP
    * All rights reserved.
    *
    * SPDX-License-Identifier: BSD-3-Clause
    */

    /*  Standard C Included Files */
    #include <stdio.h>
    #include <string.h>
    #include "pin_mux.h"
    #include "clock_config.h"
    #include "board.h"
    #include "fsl_debug_console.h"
    #include "fsl_lpi2c.h"

    /*******************************************************************************
    * Definitions
    ******************************************************************************/
    #define EXAMPLE_I2C_MASTER_BASE (LPI2C3_BASE)

    /* Select USB1 PLL (480 MHz) as master lpi2c clock source */
    #define LPI2C_CLOCK_SOURCE_SELECT (0U)
    /* Clock divider for master lpi2c clock source */
    #define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
    /* Get frequency of lpi2c clock */
    #define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))

    #define LPI2C_MASTER_CLOCK_FREQUENCY LPI2C_CLOCK_FREQUENCY
    #define WAIT_TIME                    10U


    #define EXAMPLE_I2C_MASTER ((LPI2C_Type *)EXAMPLE_I2C_MASTER_BASE)

    #define LPI2C_MASTER_SLAVE_ADDR_7BIT 0x7EU
    #define LPI2C_BAUDRATE               100000U
    #define LPI2C_DATA_LENGTH            33U

    /*******************************************************************************
    * Prototypes
    ******************************************************************************/

    /*******************************************************************************
    * Variables
    ******************************************************************************/

    uint8_t g_master_txBuff[LPI2C_DATA_LENGTH];
    uint8_t g_master_rxBuff[LPI2C_DATA_LENGTH];

    /*******************************************************************************
    * Code
    ******************************************************************************/

    /*!
    * @brief Main function
    */
    int lpi2c_test(void)
    {
        lpi2c_master_config_t masterConfig;
        status_t reVal        = kStatus_Fail;
        uint8_t deviceAddress = 0x01U;
        size_t txCount        = 0xFFU;



        /*Clock setting for LPI2C*/
        CLOCK_SetMux(kCLOCK_Lpi2cMux, LPI2C_CLOCK_SOURCE_SELECT);
        CLOCK_SetDiv(kCLOCK_Lpi2cDiv, LPI2C_CLOCK_SOURCE_DIVIDER);

        PRINTF("\r\nLPI2C board2board polling example -- Master transfer.\r\n");

        /* Set up i2c master to send data to slave*/
        /* First data in txBuff is data length of the transmiting data. */
        g_master_txBuff[0] = LPI2C_DATA_LENGTH - 1U;
        for (uint32_t i = 1U; i < LPI2C_DATA_LENGTH; i++)
        {
            g_master_txBuff[i] = i - 1;
        }

        PRINTF("Master will send data :");
        for (uint32_t i = 0U; i < LPI2C_DATA_LENGTH - 1U; i++)
        {
            if (i % 8 == 0)
            {
                PRINTF("\r\n");
            }
            PRINTF("0x%2x  ", g_master_txBuff[i + 1]);
        }
        PRINTF("\r\n\r\n");

        /*
         * masterConfig.debugEnable = false;
         * masterConfig.ignoreAck = false;
         * masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
         * masterConfig.baudRate_Hz = 100000U;
         * masterConfig.busIdleTimeout_ns = 0;
         * masterConfig.pinLowTimeout_ns = 0;
         * masterConfig.sdaGlitchFilterWidth_ns = 0;
         * masterConfig.sclGlitchFilterWidth_ns = 0;
         */
        LPI2C_MasterGetDefaultConfig(&masterConfig);

        /* Change the default baudrate configuration */
        masterConfig.baudRate_Hz = LPI2C_BAUDRATE;

        /* Initialize the LPI2C master peripheral */
        LPI2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, LPI2C_MASTER_CLOCK_FREQUENCY);

        /* Send master blocking data to slave */
        if (kStatus_Success == LPI2C_MasterStart(EXAMPLE_I2C_MASTER, LPI2C_MASTER_SLAVE_ADDR_7BIT, kLPI2C_Write))
        {
            /* Check master tx FIFO empty or not */
            LPI2C_MasterGetFifoCounts(EXAMPLE_I2C_MASTER, NULL, &txCount);
            while (txCount)
            {
                LPI2C_MasterGetFifoCounts(EXAMPLE_I2C_MASTER, NULL, &txCount);
            }
            /* Check communicate with slave successful or not */
            if (LPI2C_MasterGetStatusFlags(EXAMPLE_I2C_MASTER) & kLPI2C_MasterNackDetectFlag)
            {
                return kStatus_LPI2C_Nak;
            }

            /* subAddress = 0x01, data = g_master_txBuff - write to slave.
              start + slaveaddress(w) + subAddress + length of data buffer + data buffer + stop*/
            reVal = LPI2C_MasterSend(EXAMPLE_I2C_MASTER, &deviceAddress, 1);
            if (reVal != kStatus_Success)
            {
                if (reVal == kStatus_LPI2C_Nak)
                {
                    LPI2C_MasterStop(EXAMPLE_I2C_MASTER);
                }
                return -1;
            }

            reVal = LPI2C_MasterSend(EXAMPLE_I2C_MASTER, g_master_txBuff, LPI2C_DATA_LENGTH);
            if (reVal != kStatus_Success)
            {
                if (reVal == kStatus_LPI2C_Nak)
                {
                    LPI2C_MasterStop(EXAMPLE_I2C_MASTER);
                }
                return -1;
            }

            reVal = LPI2C_MasterStop(EXAMPLE_I2C_MASTER);
            if (reVal != kStatus_Success)
            {
                return -1;
            }
        }

        /* Wait until the slave is ready for transmit, wait time depend on user's case.
           Slave devices that need some time to process received byte or are not ready yet to
           send the next byte, can pull the clock low to signal to the master that it should wait.*/
        for (uint32_t i = 0U; i < WAIT_TIME; i++)
        {
            __NOP();
        }

        PRINTF("Receive sent data from slave :");

        /* Receive blocking data from slave */
        /* subAddress = 0x01, data = g_master_rxBuff - read from slave.
          start + slaveaddress(w) + subAddress + repeated start + slaveaddress(r) + rx data buffer + stop */
        if (kStatus_Success == LPI2C_MasterStart(EXAMPLE_I2C_MASTER, LPI2C_MASTER_SLAVE_ADDR_7BIT, kLPI2C_Write))
        {
            /* Check master tx FIFO empty or not */
            LPI2C_MasterGetFifoCounts(EXAMPLE_I2C_MASTER, NULL, &txCount);
            while (txCount)
            {
                LPI2C_MasterGetFifoCounts(EXAMPLE_I2C_MASTER, NULL, &txCount);
            }
            /* Check communicate with slave successful or not */
            if (LPI2C_MasterGetStatusFlags(EXAMPLE_I2C_MASTER) & kLPI2C_MasterNackDetectFlag)
            {
                return kStatus_LPI2C_Nak;
            }

            reVal = LPI2C_MasterSend(EXAMPLE_I2C_MASTER, &deviceAddress, 1);
            if (reVal != kStatus_Success)
            {
                if (reVal == kStatus_LPI2C_Nak)
                {
                    LPI2C_MasterStop(EXAMPLE_I2C_MASTER);
                }
                return -1;
            }

            reVal = LPI2C_MasterRepeatedStart(EXAMPLE_I2C_MASTER, LPI2C_MASTER_SLAVE_ADDR_7BIT, kLPI2C_Read);
            if (reVal != kStatus_Success)
            {
                return -1;
            }

            reVal = LPI2C_MasterReceive(EXAMPLE_I2C_MASTER, g_master_rxBuff, LPI2C_DATA_LENGTH - 1);
            if (reVal != kStatus_Success)
            {
                if (reVal == kStatus_LPI2C_Nak)
                {
                    LPI2C_MasterStop(EXAMPLE_I2C_MASTER);
                }
                return -1;
            }

            reVal = LPI2C_MasterStop(EXAMPLE_I2C_MASTER);
            if (reVal != kStatus_Success)
            {
                return -1;
            }
        }

        for (uint32_t i = 0U; i < LPI2C_DATA_LENGTH - 1; i++)
        {
            if (i % 8 == 0)
            {
                PRINTF("\r\n");
            }
            PRINTF("0x%2x  ", g_master_rxBuff[i]);
        }
        PRINTF("\r\n\r\n");

        /* Transfer completed. Check the data.*/
        for (uint32_t i = 0U; i < LPI2C_DATA_LENGTH - 1U; i++)
        {
            if (g_master_rxBuff[i] != g_master_txBuff[i + 1])
            {
                PRINTF("\r\nError occurred in the transfer ! \r\n");
                break;
            }
        }

        PRINTF("\r\nEnd of LPI2C example .\r\n");
        while (1)
        {
        }
    }

    特意量了下波形发现波形异常如下:


    LPI2C通信波形所示。
    从图中看到只发了个start信号,就异常了,地址都没发出去。

    LPI2C配置

    LPI2C配置

    LPI2C通讯波形

    LPI2C通讯波形
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2022-4-20 09:47
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    1

    主题

    6

    帖子

    0

    新手上路

    Rank: 1

    积分
    39
    最后登录
    2022-4-20
     楼主| 发表于 2021-10-28 17:17:30 | 显示全部楼层
    已解决,这是MCUXpress IDE 挖的坑,外设配置生成的pin_mux.c 中
      IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_LPI2C3_SDA, 0U);
      IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_LPI2C3_SCL, 0U);
    给配置成0,而使用LPI2C 功能必须设置为“1”以使能引脚的 SION 功能
      IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_LPI2C3_SDA, 1U);
      IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_LPI2C3_SCL, 1U);
    修改后功能正常
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20103
    最后登录
    2024-5-1
    发表于 2021-10-29 10:16:48 | 显示全部楼层
    eefocus_3775499 发表于 2021-10-28 17:17
    已解决,这是MCUXpress IDE 挖的坑,外设配置生成的pin_mux.c 中
      IOMUXC_SetPinMux(IOMUXC_GPIO_EM ...

    楼主息怒!找到问题就好!
    RT1060,RT1064 I2C IP是一样的,所以问题就在代码端,通常遇到这种问题,直接把RT1060的pinmux, i2c 驱动,I2C调用代码拿过来就能用了。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-5-2 08:26 , Processed in 0.115594 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表