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.

I2C as slave on motorware

Other Parts Discussed in Thread: BOOSTXL-DRV8301

Hi all, I'm trying to get i2c work as a slave (on GPIO 32 and 33) in lab_5b but it doesn't work.

I have a LaunchXL F28027F and a BoostXL-DRV8301

I use a atmel avr as a master, the i2c clock is at 100khz.Both sda and scl havea 4.7kohms pull up.

I use the i2c.c/h from maria
e2e.ti.com/.../1203642

When the MCU starts, there some signals on scl and sda pin (I don't know why)


and then the SDA and SCL line go low (If i am right they should be high)

What I have done :

in hal_obj.h I had
typedef struct _HAL_Obj_
{
...

I2C_Handle i2cAHandle; //!< the I2CA handle
I2C_Obj i2cA; //!< the I2CA object

} HAL_Obj;


in hal.c i added some code in existing functions :
in HAL_Handle HAL_init(void *pMemory,const size_t numBytes)
{
...
// initialize the I2C handle
obj->i2cAHandle = I2C_init((void *)I2CA_BASE_ADDR,sizeof(I2C_Obj));
...
}

void HAL_setParams(HAL_Handle handle,const USER_Params *pUserParams)
{
...
// setup the i2cA
HAL_setupI2cA(handle);
...
}


void HAL_setupGpios(HAL_Handle handle)
{
...
//I2C SDA
GPIO_setMode(obj->gpioHandle,GPIO_Number_32,GPIO_32_Mode_SDAA);
//I2C SCL
GPIO_setMode(obj->gpioHandle,GPIO_Number_33,GPIO_33_Mode_SCLA);
...
}


void HAL_setupPeripheralClks(HAL_Handle handle)
{
...
CLK_enableI2cClock(obj->clkHandle);
...
}

I added some function in hal.c/h
void HAL_setupI2cA(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *)handle;

I2C_resetAll(obj->i2cAHandle);
I2C_setupClock(obj->i2cAHandle,4,55,55); //I2C Clock module à 12MHz clock scl à 100khz
I2C_setSlave(obj->i2cAHandle); //Mode Slave
I2C_setSlaveAddress(obj->i2cAHandle,0x50);

I2C_enable(obj->i2cAHandle); //enable i2c

return;
} // end of HAL_setupI2cA() function

void HAL_enableI2cInt(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *)handle;

PIE_enableI2cInt(obj->pieHandle);

//I2C_enableInt(obj->i2cAHandle,I2C_IntEn_Arb_Lost);
//I2C_enableInt(obj->i2cAHandle,I2C_IntEn_NACK);
I2C_enableInt(obj->i2cAHandle,I2C_IntEn_Reg_Rdy);
I2C_enableInt(obj->i2cAHandle,I2C_IntEn_Rx_Rdy);
//I2C_enableInt(obj->i2cAHandle,I2C_IntEn_Tx_Rdy);
//I2C_enableInt(obj->i2cAHandle,I2C_IntEn_Stop);
//I2C_enableInt(obj->i2cAHandle,I2C_IntEn_Slave_Addr);

// enable the cpu interrupt for TINT8
CPU_enableInt(obj->cpuHandle,CPU_IntNumber_8);
return;
}

in hal.h i added

extern interrupt void i2cISR(void);

//! \brief Acknowledges an interrupt from i2c so that another i2c interrupt can
//! happen again.
//! \param[in] handle The hardware abstraction layer (HAL) handle
static inline void HAL_acqI2cInt(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *)handle;

//I2C_clearTxFifoInt(obj->i2cAHandle);
//I2C_clearRxFifoInt(obj->i2cAHandle);
I2C_clearRRDYflag(obj->i2cAHandle);
// Acknowledge interrupt from PIE group 8
PIE_clearInt(obj->pieHandle,PIE_GroupNumber_8);
return;

}

and I modified
static inline void HAL_initIntVectorTable(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *)handle;
PIE_Obj *pie = (PIE_Obj *)obj->pieHandle;


ENABLE_PROTECTED_REGISTER_WRITE_MODE;
//pie->I2CINT2A = &i2cISR; //I2C FIFO interrupt
pie->I2CINT1A = &i2cISR; //I2C interrupt

pie->ADCINT1 = &mainISR;

DISABLE_PROTECTED_REGISTER_WRITE_MODE;

return;
} // end of HAL_initIntVectorTable() function

in pie.c I added
void PIE_enableI2cInt(PIE_Handle pieHandle)
{
PIE_Obj *pie = (PIE_Obj *)pieHandle;

// set the value
pie->PIEIER_PIEIFR[7].IER |= PIE_IERx_INTx1_BITS;

return;
} // end of PIE_enableI2cInt() function

In the main, before the forever loop I put

//enable I2c interrupts
HAL_enableI2cInt(halHandle);

And my i2cisr does not do someting except

interrupt void i2cISR(void)
{
//Read the interrupt source
//acknoledge the I2C interrupt
HAL_acqI2cInt(halHandle);
// I2C_IntSource_e source;

HAL_toggleLed(halHandle,(GPIO_Number_e)HAL_Gpio_LED2);

I2cSource = HAL_getIntSourceI2c(halHandle);
I2cStatus = HAL_getStatusI2c(halHandle);
switch(I2cSource)
{
case I2C_IntSrc_None: //!< No Interrupt
case I2C_IntSrc_Arb_Lost : //!< Arbitration Lost
case I2C_IntSrc_NACK: //!< No-Acknowledge Detected
case I2C_IntSrc_Stop: //!< Stop Condition Detected
case I2C_IntSrc_Slave_Addr: //!< Addressed as Slave
case I2C_IntSrc_Reg_Rdy: //!< Register Ready for Access
break;
case I2C_IntSrc_Rx_Rdy: //!< Recieve Data Ready
break;
case I2C_IntSrc_Tx_Rdy: //!< Transmit Data Ready
break;
}
gLEDcnt++;
return;
}

When i start the MCU, The I2C registers are I think correct (set as setup in  HAL_setupI2cA(handle);

The odd thing is I got some signals in i2c pin even if nothing is plugged on i2c pins.
The gLEDcnt variable is 1, so it enter in the i2cisr  and then the i2c pins are both low.

so no communication is possible.

I tried to put the HAL_enableI2cInt(halHandle) in the forever lopp after the while(!(gMotorVars.Flag_enableSys));

It is the same behavior expt that the gLEDcnt is still a t 0 but i2c pins are low.

The signals in i2c pinsat startup are there even if i didn't do a HAL_setupI2c.

What's wrong ? where is the mistake ?

Thank you

  • Renaud,

    I'm looking into this. I'm not seeing any issues with your code at the moment. At what point do the pins go low? Do you see them go high like you would expect at any point before they go low or is it only just the toggling that you showed in your oscilloscope capture?

    Thanks,
    Whitney
  • Hello Whitney,

    The pins go low just after the toggling, and i don't know what is causing of the toggling.
    They are high before I play start, then toglling and they stay low.
    The scl pin can go high if I set the register I2CMDR (with jtag emulator) to 0 (it is currently 0x0020 -> Reset or disabled state). And I can see the clock of the master when a request is sent. But the sda pin never went high.

    If someone has an idea it will be relly helpful

    Renaud,

  • Renaud,

    Since you're using the BoostXL-DRV8301, does that mean GPIO16 and GPIO17 are being used for SPI? The pins for GPIOs 16 and 17 are connected to the pins for GPIOs 32 and 33 on the Launchpad for compatibility reasons. If you have not broken the shorts on the board as is described in the link below, perhaps that's contributing to some of the toggling you're seeing?

    e2e.ti.com/.../241893

    Can you confirm that the pins aren't connected on your board?

    Thanks,
    Whitney

  • Hoo i'm stupid,
    You're right.
    I just broke the shorts, and my I2c is responding,
    now i have to complete my isr.

    Really thank you
  • I have now some probleme with a reading command on I2c,writting register is working great.
    But when i try to read i got some strange behavior.

    First I enabled RRDY, XRDY and SCD interruption.
    I want to try to read 3 register starting to the reg 1
    My board has an i2c adresse of 0x50
    The buffer i wan to read is
    uint16_t buffer_out_i2c[10] = {0,1,2,243,244,5,6,7,8,9};
    So the value i should get from i2c is 1, 2 and 243

    So i write to register 0 the value 0x01 in order to pint to the register 0x01.
    START-A0-01-STOP It is workig my reference is set to 1 good.
    Then I send to the i2c bus the read command and i get :
    START-A1-01-02-F3-STOP. Great it is good

    But i saw that i got 5 I2C_IntSrc_Tx_Rdy interrupt instead of 3 ....
    I try to read again the same register and i got
    START-A1-05-01-02-STOP -> 05 is the value of the fifth register (and it is quite normal because i got 5 interruption before)
    and i got 4 TRDY interruption instead of 3.

    Again I read the same register and i got
    START-A1-F4-01-02-STOP -> F4 is the value of the 4th register and again 4 interruption so next time i'll get F4-01-02

    Why I have this strange behaviour. here is my i2cISR :

    interrupt void i2cISR(void)
    {
    //Read the interrupt source
    // I2C_IntSource_e source;

    I2cSource = HAL_getIntSourceI2c(halHandle);
    I2cStatus = HAL_getStatusI2c(halHandle);
    switch(I2cSource)
    {
    case I2C_IntSrc_None: //!< No Interrupt
    case I2C_IntSrc_Arb_Lost : //!< Arbitration Lost
    case I2C_IntSrc_NACK: //!< No-Acknowledge Detected

    case I2C_IntSrc_Slave_Addr: //!< Addressed as Slave
    case I2C_IntSrc_Reg_Rdy: //!< Register Ready for Access
    break;
    case I2C_IntSrc_Stop: //!< Stop Condition Detected
    I2cIndex=0;
    I2cIndexTx=0;
    break;
    case I2C_IntSrc_Rx_Rdy: //!< Recieve Data Ready
    I2cIndexTx=0;
    inData[I2cIndex] = HAL_getDataI2c(halHandle);
    I2cReference = inData[0];
    temoin_rx=0;
    if(I2cIndex>0)
    {
    buffer_in_i2c[I2cReference+I2cIndex-1] = inData[I2cIndex];
    }
    I2cIndex++;
    break;
    case I2C_IntSrc_Tx_Rdy: //!< Transmit Data Ready
    TxData = buffer_out_i2c[I2cReference + I2cIndexTx];
    temoin_tx_3[I2cIndexTx]=TxData;
    HAL_putDataI2c(halHandle,TxData);
    I2cIndexTx++;
    temoin_rx++;
    break;
    }
    gLEDcnt++;

    //acknoledge the I2C interrupt
    HAL_acqI2cInt(halHandle);
    return;
    }
  • No one got an idea ?

    Maybe i'm doing something wrong in the isr for the READ instruction, 
    Does someone has an code as i2c slave ?

    Thank you