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.

CC3200 I2C Slave模式无法进入中断

Other Parts Discussed in Thread: CC3200, CC2541

Hi,大家好

  我在调试CC3200的I2C Slave,使用的是lauchpad GCC + Eclipse开发,之前测试了一下CC3200 I2Cmaster模式,工作正常, 现在改为Slave模式发现无法进入中断,通过逻辑分析仪分析,我发现CC3200有被寻址到,也回复了应答信号,但是这些东西并不是我的中断程序做的。

下面是我的代码:

void main(void)

{

...

// Configure PIN_05 for I2C0 I2C_SCL
PinTypeI2C(PIN_05, PIN_MODE_5);

// Configure PIN_06 for I2C0 I2C_SDA
PinTypeI2C(PIN_06, PIN_MODE_5);

MAP_PRCMPeripheralClkEnable(PRCM_I2CA0, PRCM_RUN_MODE_CLK);

MAP_PRCMPeripheralReset(PRCM_I2CA0);

I2CSlaveInit(I2CA0_BASE, 127);

I2CSlaveFIFODisable(I2CA0_BASE);

MAP_I2CIntRegister(PRCM_I2CA0, I2C0_IRQHandler);

I2CSlaveIntEnableEx(I2CA0_BASE,
I2C_SLAVE_INT_START |
I2C_SLAVE_INT_STOP |
I2C_SLAVE_INT_DATA);

while(1) {  }

}

void I2C0_IRQHandler(void)
{
unsigned char rx_data;

GPIOPinWrite(GPIOA3_BASE, 0x01, 1);
MAP_UtilsDelay(1);
GPIOPinWrite(GPIOA3_BASE, 0x01, 0);

Message("I2C0 Inte! \r\n");

if(I2C0_SCSR & I2C_SCSR_DA) //Check RREQ = 1?
{
/* I2C Master Write */

//Receive data from data register
rx_data = I2C0_SDR;

//Send ACK signal
I2CSlaveACKValueSet(I2CA0_BASE, 1);
}
else if(I2C0_SCSR & I2C_SCSR_TREQ) //Check RREQ = 1?
{
I2C0_SDR = 0x37;
}
else
{
return;
}

}

谢谢.

  • 你好,我最近也在做i2c slave 中断,但是对初始化不大清晰,想问下Eugene这方面调通了吗?帮忙指点下,拜托

  • 调通了,如果有需要可以给我发邮件 yuting0501@gmail.com

  • 如果可以,能否把你的工程附件在这里,本着分享的精神, :-)

  • 配置没有问题,是之前的SDK没有支持GCC,中断向量表没有重映射,导致无法进入中断。

  • 您好!

    我也遇到一样的问题。代码和您给出的差不多,I2C Slave地址0x24,用 PIN01 和 PIN02,LaunchPad 的 J2 J3 已经取下。

    CC2541作为 I2C Master,用 123k 或 256k 时钟都试过(CC2541 I2C 不支持100k或400k时钟,不知道问题是否出在这里)。CC2541 的 I2C 处理程序已经在其它地方验证过,没有问题。

    现象:

    1. CC3200 作为 I2C Slave 没有进入中断处理;

    2. CC2541 作为 I2C Master 没有收到 Addr ACK,无法发送数据。

    3. 使用 IAR,Debug 发现 Memory I2CA0 在初始化过程中没有任何变化,不解。

    您能否将调试通过的代码发给我:378648860@qq.com,非常感谢!

  • 补充一下我的测试代码:

    void main()
    {
      long lRetVal = -1;

      // Initialize Board configurations
      BoardInit();

      // Pinmux for UART
      PinMuxConfig();

      // Configuring UART
      InitTerm();

      // Initialize I2C as salve
      i2cs_Init();
     
      UART_PRINT("\r\n**I2C intialized as slave, ready to receive data...\r\n");
     
      while(1)
      {    
      }    
    }

    void i2cs_Init(void)
    {
      //Enable I2C Peripheral
      MAP_PRCMPeripheralClkEnable(PRCM_I2CA0, PRCM_RUN_MODE_CLK);
      MAP_PRCMPeripheralReset(PRCM_I2CA0);

      //Init Slave Mode, Set Slave Address
      I2CSlaveInit(I2CA0_BASE, I2C_SLAVE_ADDR);

      I2CSlaveFIFODisable(I2CA0_BASE);

      //Enable Slave Interrupt
      I2CSlaveIntEnableEx(I2CA0_BASE, I2C_SLAVE_INT_START|I2C_SLAVE_INT_STOP|I2C_SLAVE_INT_DATA);

      //Register I2C Interrupt
      I2CIntRegister(I2CA0_BASE, i2cs_IrqIntHandler);
      
      I2CSlaveDataGet(I2CA0_BASE);

      //Enable Processor
      IntEnable(INT_I2CA0);
    }

    void i2cs_IrqIntHandler(void)
    {
      uint32_t uiStatus;
      uint32_t data;
      //char str[10];
     
      UART_PRINT("I2C IRQ: "); 
       
      uiStatus = I2CSlaveStatus(I2CA0_BASE);
      I2CSlaveIntClearEx(I2CA0_BASE, I2C_SLAVE_INT_DATA);
     
      if(uiStatus & I2C_SCSR_DA)
      {
        data = I2CSlaveDataGet(I2CA0_BASE);
       
        //memcpy(str, &data, 4);
        UART_PRINT("0x%X ", data);
      }
      else if(uiStatus & I2C_SLAVE_ACT_TREQ)
      {
        I2CSlaveDataPut(I2CA0_BASE, 0x01);
      } 
    }

    void PinMuxConfig(void)
    {
      // Enable Peripheral Clocks
      MAP_PRCMPeripheralClkEnable(PRCM_UARTA0, PRCM_RUN_MODE_CLK);
      MAP_PRCMPeripheralClkEnable(PRCM_GPIOA1, PRCM_RUN_MODE_CLK);

      // Configure PIN_55 for UART0 UART0_TX
      MAP_PinTypeUART(PIN_55, PIN_MODE_3);

      // Configure PIN_57 for UART0 UART0_RX
      MAP_PinTypeUART(PIN_57, PIN_MODE_3);

      // Configure PIN_03 for I2C0 I2C_SCL
      MAP_PinTypeI2C(PIN_01, PIN_MODE_0);

      // Configure PIN_04 for I2C0 I2C_SDA
      MAP_PinTypeI2C(PIN_02, PIN_MODE_0); 
    }

  • Hi calvin,

    和I2C相关的代码我已经都发到我的问题中。CC3200的中断向量表是需要重映射的,你是否定义了IAR编译器的宏?你可以试着打印一下中断向量表,观察一下I2C中断的函数地址,是否和其他默认的中断函数地址相同,如果相同则说明你未重映射中断向量表。

  • 谢谢您的飞速回复!您说的中断向量表设置是不是这一段,工程定义了 ewarm 编译选项,并且执行了 MAP_IntVTableBaseSet

    void BoardInit(void)
    {
    /* In case of TI-RTOS vector table is initialize by OS itself */
    #ifndef USE_TIRTOS
      // Set vector table base
      #if defined(ccs)
      MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]);
      #endif
      #if defined(ewarm)
      MAP_IntVTableBaseSet((unsigned long)&__vector_table);
      #endif
    #endif
      // Enable Processor
      MAP_IntMasterEnable();
      MAP_IntEnable(FAULT_SYSTICK);

      PRCMCC3200MCUInit();
    }

  • 我明白您说的意思了,IAR 的中断向量表定义在 startup_ewarm.c 中,其中 I2C0 的入口还是 IntDefaultHandler,所以工作不正常。

    我马上改了试试

  • 我遇到的问题和您遇到的不一样,我的 vector table 是正确初始化了的,在 IntRegister() 也正确地将中断处理函数写到了 vector table。

    我的程序已经调通,问题有两个:

    1. PIN_01 和 PIN_02 配置错了,应该是 PIN_MODE_1,我写成  PIN_MODE_0 了。该问题导致引脚配置成通用 GPIO;

    2. 开发板的 J2 和 J3 不应该取下,取下后导致 SCL 和 SDA 没有上拉,数据传输不稳定,很容易断开。

    希望对后面的童鞋们有帮助。

  • 您好,请问CC3200能触发起始信号和停止信号的中断,但是收不到数据中断,请问这有可能是什么原因导致的呢?

  • 您好,请问CC3200能触发起始信号和停止信号的中断,但是收不到数据中断,请问这有可能是什么原因导致的呢?