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.

[参考译文] MSPM0C1104:MSPM0C1104 I2C 控制器无法读取寄存器数据

Guru**** 2348500 points
Other Parts Discussed in Thread: MSPM0C1104
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1461293/mspm0c1104-mspm0c1104-i2c-controller-can-not-read-register-data

器件型号:MSPM0C1104

工具与软件:

我在 MSPM0C1104 EVB 上开发软件代码。

现在、我们需要从 I2C 从器件中读取寄存器内容。

而不是规格。 I2C 器件的读取时序是多少  

 此器件的读取流程为:  

I2C_START、Slave_Addr + W、Reg_Addr、  

I2C_START、 DATA+R、Slave_Addr、Data1、Data2、Data3、 DATA4、I2C_STOP。

我使用并从示例代码"C:\ti\mspm0_sdk_2_03_00_07\examples\nortos\LP_MSPM0C1104\driverlib\i2c_controller_rw_multibyte_fifo_polar"中修改。

 

#include "ti_msp_dl_config.h"

/*
 * Number of bytes to send from Controller to target.
 *  This example uses FIFO with polling, and the maximum FIFO size is 4.
 *  Refer to interrupt examples to handle larger packets
 */
#define I2C_TX_PACKET_SIZE (3)

/*
 * Number of bytes to received from target.
 *  This example uses FIFO with polling, and the maximum FIFO size is 4.
 *  Refer to interrupt examples to handle larger packets
 */
#define I2C_RX_PACKET_SIZE (3)

/* Data sent to the Target */
uint8_t gTxPacket[I2C_TX_PACKET_SIZE] = {0x00, 0x61, 0x00};

/*  Read Register Address*/
uint8_t gRegisterAddr[2] = {0x10, 0x14};

/* Data received from Target */
volatile uint8_t gRxPacket[I2C_RX_PACKET_SIZE];

/* I2C Target address */
#define I2C_TARGET_ADDRESS (0x29)

int main(void)
{
    SYSCFG_DL_init();

    /* Set LED to indicate start of transfer */
    DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);

    /*
     * Fill FIFO with data. This example will send a MAX of 4 bytes since it
     * doesn't handle the case where FIFO is full
     */
    DL_I2C_fillControllerTXFIFO(I2C_INST, &gTxPacket[0], I2C_TX_PACKET_SIZE);

    /* Wait for I2C to be Idle */
    while (!(
        DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
        ;

    /* Send the packet to the controller.
     * This function will send Start + Stop automatically.
     */
    DL_I2C_startControllerTransfer(I2C_INST, I2C_TARGET_ADDRESS,
        DL_I2C_CONTROLLER_DIRECTION_TX, I2C_TX_PACKET_SIZE);

    /* Poll until the Controller writes all bytes */
    while (DL_I2C_getControllerStatus(I2C_INST) &
           DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
        ;

    /* Trap if there was an error */
    if (DL_I2C_getControllerStatus(I2C_INST) &
        DL_I2C_CONTROLLER_STATUS_ERROR) {
        /* LED will remain high if there is an error */
        __BKPT(0);
    }

    /* Wait for I2C to be Idle */
    while (!(
        DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
        ;

    /* Add delay between transfers */
    delay_cycles(1000);

    /* Send a read request to Target */
    DL_I2C_startControllerTransfer(I2C_INST, I2C_TARGET_ADDRESS,
        DL_I2C_CONTROLLER_DIRECTION_RX, I2C_RX_PACKET_SIZE);

    /*
     * Receive all bytes from target. LED will remain high if not all bytes
     * are received
     */
    for (uint8_t i = 0; i < I2C_RX_PACKET_SIZE; i++) {
        while (DL_I2C_isControllerRXFIFOEmpty(I2C_INST))
            ;
        gRxPacket[i] = DL_I2C_receiveControllerData(I2C_INST);
    }

    // Test: read target register data
    /* 1: Do Dummy Write  */
        DL_I2C_fillControllerTXFIFO(I2C_INST, &gRegisterAddr[0], 1);
        // Wait for I2C to be Idle */
        while (!(
            DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
            ; 
        // Transfer register address w/o i2c_STOP
        DL_I2C_startControllerTransferAdvanced(I2C_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX,\
            1, DL_I2C_CONTROLLER_START_ENABLE, DL_I2C_CONTROLLER_STOP_DISABLE, DL_I2C_CONTROLLER_ACK_ENABLE);
        
        // wait Poll until the Controller writes all bytes */
        while (DL_I2C_getControllerStatus(I2C_INST) &
            DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
            ;

    /* 2: Read data */
        /* Wait for I2C to be Idle */
        while (!(
            DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
            ;

            /* Add delay between transfers */
            delay_cycles(1000);

            /* Send a read request to Target */
            //DL_I2C_startControllerTransfer(I2C_INST, I2C_TARGET_ADDRESS,
            //    DL_I2C_CONTROLLER_DIRECTION_RX, I2C_RX_PACKET_SIZE);
            DL_I2C_startControllerTransferAdvanced(I2C_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_RX,\
            I2C_RX_PACKET_SIZE, DL_I2C_CONTROLLER_START_ENABLE, DL_I2C_CONTROLLER_STOP_ENABLE, DL_I2C_CONTROLLER_ACK_DISABLE);

        /*
        * Receive all bytes from target. LED will remain high if not all bytes
        * are received
        */
        for (uint8_t i = 0; i < I2C_RX_PACKET_SIZE; i++) {
            while (DL_I2C_isControllerRXFIFOEmpty(I2C_INST))
                ;
            gRxPacket[i] = DL_I2C_receiveControllerData(I2C_INST);
        }    


    /* If write and read were successful, toggle LED */
    while (1) {
        DL_GPIO_togglePins(GPIO_LEDS_PORT,
            GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN);
        delay_cycles(12000000);
    }
}

在主函数中、我在最后一个 while 循环之前添加该读取函数。

遗憾的是、程序在 I2C 读取中停止、因为 SCK 保持低电平

有人能解决这个问题吗? 谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为这应该是2、而不是1。 可以重试吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、EASON

      作为您的建议、该号码已修改为2  

        DL_I2C_fillControllerTXFIFO (I2C_0_INST、&regAddr[0]2);
    这是同样的,  
    感谢您的答复。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能否将其更改为启用、并将值从1更改为2。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    >while (DL_I2C_getControllerStatus(I2C_INST)&
    >  DL_I2C_CONTROLLER_STATUS_BUS_BUS)

    BUSBSY 将被设定、直到停止、所以它不会在这里清除。 请尝试改用:

    >while (DL_I2C_getControllerStatus(I2C_INST)&
    > DL_I2C_CONTROLLER_STATUS_BUSY)

    ---

    或者更好的是:使用 RD_ON_TXEMPTY 特性。  不进行初始(TX)半事务、而是调用:

    DL_I2C_resetControllerTransfer(I2C_INST);  // Set MCTR=0 to avoid enableControllerReadOnTXEmpty hazard
    DL_I2C_enableControllerReadOnTXEmpty(I2C_INST); // Write then read

    然后执行事务的 RX 部分。 I2C 单元将在 Tx FIFO 中写入字节、然后执行 Rx 事务。