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.

[参考译文] CC1352P:I2C 从器件和寄存器访问

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1228233/cc1352p-i2c-slave-device-and-register-access

器件型号:CC1352P
主题中讨论的其他器件:SysConfig

大家好。 我正在尝试使用 CC1352P1实现 I2C 从设备。  我要在该器件上激活从模式。

我一直在试验 i2ctmp_CC1352P1_LAUNCHXL_nortos_ticlang 示例代码。

我无法访问/更改寄存器。

到目前为止、我遇到了与我的实施相关的以下线程:

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/789735/ccs-cc1350-cc1350/2921199?tisearch=e2e-sitesearch&keymatch=enable%20sctl#2921199

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1088655/cc2652rb-how-to-realize-i2c-slave-from-empty-example/4030473?tisearch=e2e-sitesearch&keymatch=I2CSlaveIntClear#4030473

我正在尝试使用中断来控制 I2C 总线上的数据流。 不过、我似乎无法修改和看到某些寄存器值。 下面是调试模式/寄存器的屏幕截图:

我无法更改或看到 SCTL DA 位是什么。 数据表指定该位在设置为1时使能 I2C 从机操作。

器件规格:

  • SCL 在引脚16上、SDA 在引脚17上。
  • SCL 和 SDA 线连接到主器件的引脚。 这些引脚使用~6K Ω 负载上拉至主器件的3V3引脚。
  • 从器件和主器件采用公共接地。
  • 主器件可以与另一个器件通信(STM32至 STM32、具有中断功能)。 因此我知道主器件向地址0x3E 发送请求。

包含项目的选项:

我想知道:

  1.  如何修改 SCTL 寄存器值。
  2.  MTPR 改变的内容。 这是否会影响从器件的运行? 我无法修改该寄存器值。
  3.  当我定期在 SDR 寄存器上激活主器件时、我不断看到一些垃圾值、如"9F"、"3F"、"FC"等。 为什么它不是0x05或101 (0)? (参考我的代码)

/*
 *  ======== main_nortos.c ========
 */
#include <stdint.h>
#include <stddef.h>

#include <NoRTOS.h>
#include <ti/drivers/Board.h>
#include <unistd.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>

/* Driver configuration */
#include "ti_drivers_config.h"
/*  User includes   */
#include "i2c_protocol.h"
#include "i2c_registers.h"
#include "D:/ccs/simplelink_cc13xx_cc26xx_sdk_6_41_00_17/source/ti/devices/cc13x2_cc26x2/driverlib/prcm.h"
extern uint8_t aTxBuffer[];
#define TASKSTACKSIZE 640

/*User function prototypes*/
void I2C_Slave_Command(void);
void Init_I2C_Slave(void);
/*
 *  ======== mainThread ========
 */
int mainThread(void )
{
    /* Call driver init functions */
    GPIO_init();
//    HWREG(GPIO_BASE + 0x48)    |= (1 << 0) | (1 << 8); // GPIO initialization example (it works!)

    /* Configure the LED and if applicable, the TMP_EN pin */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    /*TRYING new implementation*/
    return 0;
}
/*
 *  ======== main ========
 */
I2C_Params i2cParams;
I2C_Handle i2cHandle; // Declare handle for I2C module

int main(void)
{
    Board_init();

    /* Start NoRTOS */
    NoRTOS_start();
    Init_I2C_Slave();
    /* Call mainThread function */
    mainThread();
    while (1) {

        // Run continuously
    }
}

void i2c_callback(void)
{
    uint32_t status = I2CSlaveIntStatus(I2C0_BASE, true);
    I2CSlaveIntClear(I2C0_BASE, status);

    if(status & I2C_SLAVE_INT_DATA)
    {

        while( I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_TREQ)
        {
            I2CSlaveDataPut(I2C0_BASE, 0x05); // send stuff
            GPIO_toggle(CONFIG_GPIO_LED_0);
        }
    }
}

void Init_I2C_Slave()
{
    // Initialize I2C module
    i2cHandle = I2C_open(0, &i2cParams);
    // i2c_open defaults to master mode?
    I2CMasterDisable(I2C0_BASE); // discard master settings

    // Enable Slave operation
    I2CSlaveEnable(I2C0_BASE);
    I2CSlaveIntEnable(I2C0_BASE, I2C_SLAVE_INT_START | I2C_SLAVE_INT_STOP | I2C_SLAVE_INT_DATA);

    I2CIntRegister(I2C0_BASE, i2c_callback);

    // Enable Serial Power Domain
    PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0);
    PRCMPeripheralSleepEnable(PRCM_PERIPH_I2C0);

    HWREG(PRCM_BASE + I2CCLKGR)     |= (1 << 0) | (1 << 8); // clk config

    // Mandatory Load PRCM settings
    HWREG(PRCM_BASE + CLKLOADCTL)   |= (1 << 0);
    // Configure IOC module to use I2C pins
    IOCPinTypeI2c(I2C0_BASE, Board_I2C_SDA, Board_I2C_SCL);


    // Write the slave address
    HWREG(I2C0_BASE + I2C_SOAR)    = 0x3E; // 0x3E

}

请帮帮我。

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

    尊敬的 Yusuf:

    首先、我建议不要混合使用 I2C 驱动程序调用(I2C_open)和 I2C driverlib、因为 I2C 驱动程序确实会配置许多可能与您使用 I2C 从器件的目标不符的东西。

    对于您的第一个问题、您可以按照所述修改 SCTL、但请注意、寄存器是只写入的(请参阅技术参考手册的第23.5.1.3章)。 如果要检查值是否确实已写入、可读取 SSTAT 寄存器。

    第二个问题、MTPR 只影响主器件。

    对于第三个问题、您是否完成了逻辑捕获、您能否共享 I2C 总线上的数据是什么样子?

    此外、将其他拓扑使用可能  I2CSlaveAddressSet() I2CSlaveInit() 要设置从器件地址、请执行以下操作: https://dev.ti.com/tirex/explore/content/simplelink_cc13xx_cc26xx_sdk_7_10_00_98/docs/driverlib_cc13xx_cc26xx/cc13x2_cc26x2/driverlib/group__i2c__api.html#ga61e5ac82b6481401c1b38c7cf0d96ed9

    此致、

    亚瑟

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

    明白了、谢谢你们的到来。 不过、即使我写入 SCTL、SSTAT 寄存器也会保持0。 请注意、这是 Nortos、因此我计划在具有引脚配置库的 TI-RTOS-7上试用它、以确保我对 I2C 引脚的初始化是正确的。 如果我无法解决问题、我将分享示波器快照。

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

    主器件需要大小为5的缓冲区。

    我已通过编辑主设备和从设备来尝试此操作:

    /* Buffer used for transmission */
    uint8_t aTxBuffer[] = "[MSG]";
    uint8_t bufSize = 5;
    
    void i2c_callback(void)
    {
        uint32_t status = I2CSlaveIntStatus(I2C0_BASE, true);
        I2CSlaveIntClear(I2C0_BASE, status);
    
        if(status & I2C_SLAVE_INT_DATA)
        {
    
            while( I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_TREQ)
            {
                for(int i  = bufSize; i>0; i--)
                {
                    I2CSlaveDataPut(I2C0_BASE, aTxBuffer[i]); // send stuff
                }
                GPIO_toggle(CONFIG_GPIO_LED_0);
            }
        }
    }

    以下是 SCL/SDA 线的示波器视图(SCL:蓝色):

    是否可以一次发送数据缓冲区? 我不确定这是否是问题所在。 主器件期望特定的缓冲区大小。 "[MSG]"字符串 buf 的确切大小。

    有时在调试模式下、当我暂停和取消暂停 LaunchPad 几次时、我看到 TREQ 位1、但仅此而已。 SDR 在3F、FC、F3等之间不断变化

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

    我观察到主机没有接收到任何中断。

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

    尊敬的 Yusuf:

    您能否确认主器件是 STM32?

    此致、

    亚瑟

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

    可以。 我也在 STM32从器件上测试了此设置。 它的从地址定义为0x3E。 它使用 HAL_I2C_Master_RECEIVE_IT 连续接收中断。

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

    /*
     *  ======== empty.c ========
     */
    
    /* For usleep() */
    #include <unistd.h>
    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/I2C.h>
    // #include <ti/drivers/SPI.h>
    // #include <ti/drivers/Watchdog.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    #include "D:/ccs/simplelink_cc13xx_cc26xx_sdk_6_41_00_17/source/ti/devices/cc13x2_cc26x2/driverlib/prcm.h"
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/i2c.h)
    #include DeviceFamily_constructPath(driverlib/ioc.h)
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    
    #define I2C0_SCL0         IOID_16
    #define I2C0_SDA0         IOID_17
    #define SLAVE_ADDR        0x3E
    #define I2C_SSTAT         0x004
    #define CONTROL_MASK_FBR  0b100
    #define CONTROL_MASK_TREQ 0b010
    #define CONTROL_MASK_RREQ 0b001
    void init_i2c(void);
    void i2c_callback(void);
    
    /* Buffer used for transmission */
    uint8_t aTxBuffer[] = "[MSG]";
    uint8_t bufSize = 5;
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        /* Configure the LED pin */
        GPIO_init();
        GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_ON);
        init_i2c();
    
        uint32_t transmission_status;
    
        transmission_status = HWREG(I2S0_BASE + I2C_SSTAT); // read the status
    
    
        while (1)
        {
    
            GPIO_toggle(CONFIG_GPIO_LED_1);
    
            // Compare status bits 2, 1 and 0.
            if((transmission_status & CONTROL_MASK_FBR) != 0)
            {
            // Do nothing
            }
    
            if((transmission_status & CONTROL_MASK_TREQ) != 0)
            {
                GPIO_toggle(CONFIG_GPIO_LED_0);
            }
    
            if((transmission_status & CONTROL_MASK_RREQ) != 0)
            {
                GPIO_toggle(CONFIG_GPIO_LED_1);
            }
        }
        return 0;
    }
    
    void i2c_callback(void)
    {
        uint32_t status = I2CSlaveIntStatus(I2C0_BASE, true);
        I2CSlaveIntClear(I2C0_BASE, status);
    
        if(status & I2C_SLAVE_INT_DATA)
        {
    
            while( I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_TREQ)
            {
                for(int i  = 0; i< bufSize; i++)
                {
                    I2CSlaveDataPut(I2C0_BASE, aTxBuffer[i]); // send stuff
                }
                GPIO_toggle(CONFIG_GPIO_LED_0);
            }
        }
    }
    
    void init_i2c(void)
    {
        PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    
        // Set Power dependecies & constraints
        Power_setDependency(PowerCC26XX_PERIPH_I2C0);
        Power_setDependency(PowerCC26XX_PERIPH_GPIO);
    
        // Set constraints for Standby, powerdown and idle mode
        Power_setConstraint(PowerCC26XX_SB_DISALLOW);
        Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
    
        PRCMLoadSet();
        PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0); // Enable I2C module
        PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO);
        PRCMLoadSet();
    
        // IOC configuration for I2C pins
        IOCPortConfigureSet(I2C0_SCL0, IOC_PORT_MCU_I2C_MSSCL,IOC_STD_INPUT);
        IOCPortConfigureSet(I2C0_SDA0, IOC_PORT_MCU_I2C_MSSDA,IOC_STD_INPUT);
    
    
        I2CSlaveInit(I2C0_BASE, SLAVE_ADDR);
        I2CIntRegister(I2C0_BASE, i2c_callback);
        I2CSlaveIntEnable(I2C0_BASE, I2C_SLAVE_INT_START | I2C_SLAVE_INT_STOP | I2C_SLAVE_INT_DATA);
    }
    

    ^^^这是我在 TI RTOS7上整体运行的代码。  

    当我尝试使用以下命令以开漏方式初始化 I2C 的 IOC 引脚时:   

        PIN_Config i2cPinTable[] = {
            I2C0_SDA0 | PIN_INPUT_EN | PIN_PULLUP | PIN_OPENDRAIN,
            I2C0_SCL0 | PIN_INPUT_EN | PIN_PULLUP | PIN_OPENDRAIN,
            PIN_TERMINATE
        };

    我无法使用引脚配置函数。 我无法在包含选项${COM_TI_SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR}/source/ti/devices/cc13x2_cc26x2/driverlib 上包含前面提到的路径

    我已经尝试使用预定义为 IOC_IOMODE_OPEN_DRAIN_NORMAL 的引脚配置、但这根本不起作用。 在 TREQ 位上仍然没有变化。 开漏模式导致 SDR 完全为零。

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

    尊敬的 Yusuf:

    简单来说、路径为 COM_TI_SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR

    这意味着您具有较早的 SDK。 较新的 SDK 没有 PIN 驱动程序、而是使用 GPIO 驱动程序。

    您正在使用哪个 SDK 版本?

    此致、

    亚瑟

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

    Arthur、您好!

    这就是我无法在包含的驱动程序中找到该函数的原因。 我的 SDK 软件包是

    SimpleLink CC13xx CC26xx SDK 7.10.00.98

    是否有必要进行开漏配置以使该从器件正常工作? 有什么建议吗?

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

    我意识到在调试模式下暂停时出现错误:

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

    尊敬的 Yusuf:

    我看到一个可能导致这个问题的错误。 在您发布的代码的第54行:

    transmission_status = HWREG(I2S0_BASE + I2C_SSTAT); // read the status

    可能是

    transmission_status = HWREG(I2C0_BASE + I2C_SSTAT); // read the status

    如果你使用你的当前代码单步执行你的代码(F5为 CCS)、除非修复、它很可能不会越过该行。

    此致、

    亚瑟

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

    哦、我现在看到了、好吧、抱歉。

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

    在主机端仍然没有收到中断。

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

    更新:我已经设法通过 SDA 线路发送了一些数据。 我已设置配置以确保上拉被禁用(输入模式)。

    • 在.syscnfg 文件中为 SCL 和 SDA 引脚设置拉电阻;设置了拉电阻
    • 我已将输入配置定义为:

     

    #define IOC_USER_INPUT          (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO |      \
                                IOC_NO_IOPULL | IOC_SLEW_DISABLE |              \
                                IOC_HYST_DISABLE | IOC_FALLING_EDGE |           \
                                IOC_INT_ENABLE | IOC_IOMODE_OPEN_DRAIN_NORMAL | \
                                IOC_NO_WAKE_UP | IOC_INPUT_ENABLE )
                                
    //*Initialized pins using: *//
        IOCPortConfigureSet(I2C0_SCL0, IOC_PORT_MCU_I2C_MSSCL,IOC_USER_INPUT );
        IOCPortConfigureSet(I2C0_SDA0, IOC_PORT_MCU_I2C_MSSDA,IOC_USER_INPUT );

    现在、我将尝试看看是什么导致此从器件在我关闭主器件时只发送一次数据。

    例如、当我将数据0x0B 放在 SDA 线上时、当主器件和从器件都打开时、我不断看到0x3F。

    当我关闭主器件并使从器件(CC1352)保持开启状态时、我看到0x17、这意味着它根据需要发送了 B。 它会在我切换主设备的电力线时重复。 仅当我将另一个从器件连接到 SDA SCL 引脚并且持续发送数据时、才会发生这种情况。

    我已尝试移除 STM32从器件、CC1352没有接收任何发送请求、因为 TREQ 始终为0、我看到3F、9F、E7、FC 等。 SDR 的高电平有效值。

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

    尊敬的 Yusuf:

    主器件是否可能以某种方式错误地拉取了 I2C 线路?

    您能否在 CC1352从设备和 CC1352主设备之间进行通信?

    此致、

    亚瑟

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

    Arthur、您好!

    我累了、两个 CC1352器件之间没有连接。 在调试模式下、主器件产生仲裁丢失错误。

    主机代码:

    //* I2C Pins *//
    #define I2C0_SCL0         IOID_16
    #define I2C0_SDA0         IOID_17
    
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
    
        /* Call driver init functions */
        GPIO_init();
        Init_m_i2c();
        // data buffer
        uint8_t bufSize = 4;
        char dataReceived[bufSize];
    
        for(;;)
        {
            master_I2C_read(SLAVE_ADDR, bufSize, dataReceived);
        }
    
    
        return(0);
    }
    
    void Init_m_i2c()
    {
        /*Power domain*/
        PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
    
        // Set Power dependecies & constraints
        Power_setDependency(PowerCC26XX_PERIPH_I2C0);
        Power_setDependency(PowerCC26XX_PERIPH_GPIO);
    
        // Set constraints for Standby, powerdown and idle mode
        Power_setConstraint(PowerCC26XX_SB_DISALLOW);
        Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
    
        PRCMLoadSet();
        PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0); // Enable I2C module
        PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO);
        PRCMLoadSet();
    
        /* LED Configuration */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
        GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_ON);
    
        /*Master I2C0 Configuration*/
        IOCPortConfigureSet(I2C0_SCL0, IOC_PORT_MCU_I2C_MSSCL,IOC_STD_INPUT );
        IOCPortConfigureSet(I2C0_SDA0, IOC_PORT_MCU_I2C_MSSDA,IOC_STD_INPUT );
    
        I2CMasterEnable(I2C0_BASE);
        I2CMasterIntEnable(I2C0_BASE);
    
    
    
    }
    
    void master_I2C_read(uint8_t slaveAddress, uint8_t length, char * rxData)
    {
    
        I2CMasterSlaveAddrSet(I2C0_BASE, slaveAddress, true); //true to read, false to write
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    
        while(I2CMasterBusy(I2C0_BASE))
        {
            // wait till available
        }
    
        for(int i = 0; i < length; i++)
        {
            rxData[i] = I2CMasterDataGet(I2C0_BASE);
        }
        // end of reception
    }
    
    void master_I2C_write(uint8_t slaveAddress, uint8_t length, char * txData)
    {
    
        I2CMasterSlaveAddrSet(I2C0_BASE, slaveAddress, true);
    
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    
        while(I2CMasterBusy(I2C0_BASE))
        {
            // wait till available
        }
    
        for(int i = 0; i < length; i++)
        {
            txData[i] = I2CMasterDataGet(I2C0_BASE);
        }
    }

    我不确定我的配置是否正确。 我遵循了数据表 I2C 通信流程图。

    这个主器件将不会响应任何器件。

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

    尊敬的 Yusuf:

    我认为对主控方使用 I2C 驱动程序(i2ctmp 示例中使用的驱动程序)会更容易、至少现在可以排除一个配置错误。

    这样、我们就可以排除时钟/引脚配置的任何问题。

    在您提供的此示例中,您只需将 Init_m_i2c ( )和 master_I2C_read 替换为 I2C_init ()、I2C_open 和 I2C_transfer ,如该示例所示(在 SysConfig 中添加了实例之后):

    // Import I2C Driver definitions
    #include <ti/drivers/I2C.h>
    
    // Define name for an index of an I2C bus
    #define SENSORS 0
    
    // Define the target address of device on the SENSORS bus
    #define OPT_ADDR 0x47
    
    // One-time init of I2C driver
    I2C_init();
    // initialize optional I2C bus parameters
    I2C_Params params;
    I2C_Params_init(&params);
    params.bitRate = I2C_400kHz;
    
    // Open I2C bus for usage
    I2C_Handle i2cHandle = I2C_open(SENSORS, &params);
    
    // Initialize target address of transaction
    I2C_Transaction transaction = {0};
    transaction.targetAddress = SLAVE_ADDR;
    
    // Read from I2C target device
    transaction.readBuf = data;
    transaction.readCount = sizeof(data);
    transaction.writeCount = 0;
    I2C_transfer(i2cHandle, &transaction);
    
    // Close I2C
    I2C_close(i2cHandle);

    (来自 https://dev.ti.com/tirex/explore/content/simplelink_cc13xx_cc26xx_sdk_7_10_00_98/docs/drivers/doxygen/html/_i2_c_8h.html)

    此致、

    亚瑟

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

    大家好、Arthur、我已经确保我的 CC1352器件在主模式下工作。我已经在 SCL 和 SDA 上启用上拉引脚、并且一个温度传感器按预期工作。 (我正在使用外部温度传感器、 传感器)

    /*
     *  ======== i2ctmp.c ========
     */
    #include <stdint.h>
    #include <stddef.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/I2C.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /*user includes*/
    #include "D:/ccs/simplelink_cc13xx_cc26xx_sdk_6_41_00_17/source/ti/devices/cc13x2_cc26x2/driverlib/prcm.h"
    #include <ti/drivers/power/PowerCC26XX.h>
    
    #define TASKSTACKSIZE 640
    
    /* I2C target addresses */
    #define SLAVE_ADDR    0x3E
    
    #define SENSORS 0    // sensor index
    
    
    
    /*
     *  ======== mainThread ========
     */
    float temperature;
    void *mainThread(void *arg0)
    {
        /*I2C Variable Declerations*/
        static I2C_Handle i2c;
        static I2C_Params i2cParams;
        static I2C_Transaction i2cTransaction;
    
        static uint8_t i2cRxBuffer[2];
        static uint8_t i2cTxBuffer[1];
        static uint8_t i2cTempSensorAddress = 0x40;
        static uint8_t i2cTempSensorTempRegister = 0xE3;
    
    
        /*I2C Initialization*/
        I2C_init();
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_100kHz;
        i2c = I2C_open(CONFIG_I2C_TMP, &i2cParams);
        /* Common I2C transaction setup */
        i2cTransaction.writeBuf      = i2cTxBuffer;
        i2cTransaction.writeCount    = 1;
        i2cTransaction.readBuf       = i2cRxBuffer;
        i2cTransaction.readCount     = 0;
        i2cTransaction.targetAddress = i2cTempSensorAddress;
        i2cTransaction.readCount     = 2;
        i2cTxBuffer[0]               = i2cTempSensorTempRegister;
    
        for(;;)
        {
    
            if (I2C_transfer(i2c, &i2cTransaction)){
                uint16_t temperatureRaw = (i2cRxBuffer[0] << 8) | i2cRxBuffer[1];
                temperature = ((float)temperatureRaw *0.00268127441f) - 46.85f;
            }
            for(int i = 0; i<= 1000000; i++){
    //            for(int i = 0; i<= 1000000; i++)
            }
        }
    
    
        return(0);
    }
    

     现在、我如何在此器件上构建简单的从站实现? 我想在主器件发出发送请求时使用这个从 CC1352来发送一些数据。

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

    您好、Arthur。 感谢您的帮助。

    我已经弄清楚如何作为从 CC1352P1器件发送和接收数据。 幸运的是、问题出在主器件(STM32)侧。

    STM32需要指定写入/读取位、 未自动完成 指定的位置。

    例如:从器件地址设置为0x3E、主器件应

    a)目标0x7D 以发出从器件发送请求。

    b) 目标0x7C、以发出从器件接收请求。 (我认为 HAL 函数会自动处理写入和读取位。。)

    以下是我实现的以便将11个字节从从从器件传输到主器件:

    /*slave mode I2C*/
    /*
     *  ======== i2ctmp.c ========
     */
    #include <stdint.h>
    #include <stddef.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/I2C.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    #define TASKSTACKSIZE 640
    #include <string.h>
    
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include "D:/ccs/simplelink_cc13xx_cc26xx_sdk_6_41_00_17/source/ti/devices/cc13x2_cc26x2/driverlib/prcm.h"
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/i2c.h)
    #include DeviceFamily_constructPath(driverlib/ioc.h)
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    
    #define Board_I2C_SCL0   14
    #define Board_I2C_SDA0   13
    
    #define I2C_SLAVE_ADDR   0x3E
    
    void i2c_callback(void);
    int counter;
    char i2cData[11] = "4CHARS_SENT";
    uint32_t status = 0;
    
    
    void *mainThread(void *arg0)
    {
        Power_setDependency(PowerCC26XX_PERIPH_I2C0);
        IOCPinTypeI2c(I2C0_BASE, Board_I2C_SDA0, Board_I2C_SCL0);
        I2CSlaveInit(I2C0_BASE, I2C_SLAVE_ADDR);
    
        I2CSlaveIntEnable(I2C0_BASE, I2C_SLAVE_INT_START | I2C_SLAVE_INT_STOP | I2C_SLAVE_INT_DATA);
        I2CIntRegister(I2C0_BASE, i2c_callback);
        while (1)
        {
            size_t index = 0;
            for (index = 0; index < 11; index++)
            {
                while (I2CSlaveStatus(I2C0_BASE) != I2C_SLAVE_ACT_TREQ);
                I2CSlaveDataPut(I2C0_BASE, i2cData[index]);
            }
            GPIO_toggle(CONFIG_GPIO_LED_0);
        }
    
        return NULL;
    }
    void i2c_callback(void)
    {
        uint32_t status = I2CSlaveIntStatus(I2C0_BASE, true);
        I2CSlaveIntClear(I2C0_BASE, status);
        counter++;
    }

    这解决了我的问题、但有一个小问题、即 FBR、TREQ 或 RREQ 在这些传输期间始终不变。

    尽管我经常在主器件上定期接收"4CHARS_SEND"、但这些位不会改变。

    SDR 寄存器值也被冻结(由于某种原因卡在 AA)。

    我尝试了放入断点、LED 切换、 I2CSlaveStatus (I2C0_BASE)= I2C_SLAVE_ACT_TREQ) 等等、根本没有触发任何中断。 这些位似乎不受影响。 这是一个错误吗?

    我已确认在主器件端没有任何与 I2C 传输相关的错误。

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

    尊敬的 Yusuf:

    很高兴您发现了这个问题、感谢您提供的示例。 这对其他客户也非常有用。

    关于 RREQ 问题、在您从 SDR 寄存器读取数据后该位似乎会自动被清除。 在这种情况下、看起来您不必自行清除中断。

    此致、

    亚瑟