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.

cc2541 i2c example



Hello everybody.

I have found a lot of usefull posts on this topic and have also included the hal_i2c files in my project.

but now i have some problems when i will send different values in the corresponding registers from my i2c slave.

i have a little radio receiver which should be work with my iphone program. i have already implemented that i can change the different settings (channel, volume etc) in my own btle profile. now i want to send this value to my radio module.

and here is my problem. how can i speak with the radio receiver when i have the given hal_i2c files? there are only 3 commands ( HalI2CInit(address, freq), HalI2CWrite(len, data) and HalI2CRead(len, data) )

when i will write a value i have an different address as when i will read data (write is 0x20, read is 0x21). so, if anybody can give a little example how i can send the correct address, than the data and so on i would be very happy...

many thanks in advance

Thierry

  • The I2C drivers already automatically control the Read/Write-Not bit, Bit 0, and they shift the 7-bit address up for you (like   I2CADDR = address << 1; )

    So you would just call init with address 0x10 and everything should work.

  • Thank you very much for your information.

    I tried to do this. but when I will do the first read operation, my programm can't pass the function I2C_STRT() which is called in the function i2cMstStrt(uint8 RD_WRn)

    he is allways blocked there. has anyone an idea?

    that's how I will read the registers of my radio receiver in my state machine.

    // Actions on-entry
            switch( state )
            {
                case INITIAL_STATE:
                  break;
                  
                case INIT:
                  HalI2CInit( I2C_ADDRESS, i2cClock_267KHZ );
                    break;
                    
                case IDLE:
                    break;
                    
                case VOLUME_CHANGE:
                    HalI2CRead( 32, _SI_Register );
                    _SI_Register[ 0x0b ] &= 0xF0;
                    _SI_Register[ 0x0b ] |= event.data.volume;
                    HalI2CWrite( 32, _SI_Register );
                    Multimediadevice_ControlRadio( defEvent );
                    break;

            }

    an here the program blocke all the times

    static uint8 i2cMstStrt(uint8 RD_WRn)
    {
      I2C_STRT(); <--

      if (I2CSTAT == mstStarted)
      {
        I2C_WRITE(i2cAddr | RD_WRn);
      }

      return I2CSTAT;
    }

    many thanks in advance

    Thierry

  • You'll have i2cMstStrt function for HalI2Cread as well as HalI2Cwrite. First find out where you are having problem, during reading or writing. If you have problem in HalI2Cread, your program is not able to generate start bit for I2C communication. Then you'll have to check physical I2C connection, maybe pull up resistors. Try less speed communication.

    Hope this helps.

    maharjanbk

  • Thanks for your response.

    My problem is in both function because the programm can't continue in the macro I2C_STRT()

      I2CCFG &= ~I2C_SI;                
      I2CCFG |= I2C_STA;                
      while ((I2CCFG & I2C_SI) == 0);   
      I2CCFG &= ~I2C_STA;

    that's the code for generate the start. and he can't continue because the while expression is always 0...

  • Did ever solve this problem?  I am running into the exact same issue.  Thanks. -Chris

  • Chris S said:

    Did ever solve this problem?  I am running into the exact same issue.  Thanks. -Chris



    I just solved this on my end.  When I initially start up my program, I call HalI2CInit(0x48, i2cClock_33KHZ) and perform some I2C writes, which all work fine.  Once I get into my primary interrupt driven state machine, under certain conditions, I needed to perform I2C writes.  These latter writes were the ones that were getting locked up.  But when I call HalI2CInit(0x48, i2cClock_33KHZ) again before any I2C command, everythings appears to work and I no longer get locked.  I am going to sleep in between interrupts so maybe some of these settings are not retained? 

  • Yes, the problem is due to sleep mode of the microcontroller. The I2C settings are lost when it wakes up.

    So, use HalI2CEnterSleep() before going to sleep and use HalI2CExitSleep function after exiting sleep.

    This should solve the problem.

    Hope this helps.

    Regards,
    maharjanbk

  • Hi there,

    I've been playing around with a SensorTag and I'm having this problem.  I tried the HalI2CIinit command immediately before the I2C_STRT() macro but I'm still getting stuck in the while loop of the macro.  Any ideas?  The normal SensorTag code works fine.  However, I'm trying to use the SensorTag's hal_acc driver in some of the other ble sample code and getting this problem.  I'm using project settings from the SensorTag project (just replacing the APP files in the project with those from another ble project).  Thanks for any help!

    -Mike

  • Hi there,

    i am trying to connect Gyroscope (L3GD20) with CC2541 through I2C communication. Im using TI Keyfob Sample program for the same but unfortunately i am not able to establish communication with the device.

     we tried to capture SCL and SDA( in while loop) from the ports on CC2541with out any slave connected(attaching the same for your reference). But with the slave connected, we are not able to recieve any acknowledgement from the slave after start condition.

    please refer to the I2C code that we have implemented for our slave Gyro and let me know if any corrections to be done for establishing basic I2C communication link.

    im also attaching the code for your reference

    #include<ioCC2541.h>

    #define BV(n) (1 << (n))

    typedef unsigned char u8_t;
    typedef unsigned short int u16_t;
    typedef short int i16_t;
    typedef signed char i8_t;

    #define I2C_ENS1 BV(6)
    #define I2C_STA BV(5)
    #define I2C_STO BV(4)
    #define I2C_SI BV(3)
    #define I2C_AA BV(2)

    #define RESET P0_6
    #define led1 P1_0
    #define led2 P1_1

    #define I2C_SR 0xE0 
    #define I2C_SP 0xD0 
    #define I2C_DO 0xC0

    #define CLKCON_OSC32K 0x80 // 32 kHz clock source select/status
    #define CLKCON_OSC 0x40 // system clock source select/status
    #define CLKCON_TICKSPD (0x07 << 3) // bit mask, global timer tick speed divider
    #define CLKCON_TICKSPD_32M (0x00 << 3)
    #define CLKCON_TICKSPD_16M (0x01 << 3)
    #define CLKCON_TICKSPD_8M (0x02 << 3)
    #define CLKCON_TICKSPD_4M (0x03 << 3)
    #define CLKCON_TICKSPD_2M (0x04 << 3)
    #define CLKCON_TICKSPD_1M (0x05 << 3)
    #define CLKCON_TICKSPD_500K (0x06 << 3)
    #define CLKCON_TICKSPD_250K (0x07 << 3)
    #define CLKCON_CLKSPD (0x07) // bit mask for the clock speed division
    #define CLKCON_CLKSPD_32M (0x00)
    #define CLKCON_CLKSPD_16M (0x01)
    #define CLKCON_CLKSPD_8M (0x02)
    #define CLKCON_CLKSPD_4M (0x03)
    #define CLKCON_CLKSPD_2M (0x04)
    #define CLKCON_CLKSPD_1M (0x05)
    #define CLKCON_CLKSPD_500K (0x06)
    #define CLKCON_CLKSPD_250K (0x07)

    #define L3G4200D_OUT_X_L 0x28
    #define L3G4200D_OUT_X_H 0x29
    #define L3G4200D_OUT_Y_L 0x2A
    #define L3G4200D_OUT_Y_H 0x2B
    #define L3G4200D_OUT_Z_L 0x2C
    #define L3G4200D_OUT_Z_H 0x2D

    typedef enum {
    X_AXIS =0x01,
    Y_AXIS =0x02,
    Z_AXIS=0x03
    } axis;

    void i2c_init();
    void gyro_start();
    void gyro_stop();
    void gyro_send(unsigned char x);
    void gyro_write(unsigned char reg,unsigned char dat);
    unsigned char gyro_receive(unsigned char reg);
    void gyro_init();
    void delay(unsigned char n);
    void timer_delay(unsigned char m);

    ******************************************************************************************

    #include<ioCC2541.h>
    #include<gyro.h>
    void gyro_start()
    {
    I2CCFG &=~I2C_SI;
    I2CCFG |=I2C_STA;
    while((I2CCFG&I2C_SI)==0);
    I2CCFG &=~I2C_STA;
    }
    void gyro_stop()
    {
    I2CCFG &=I2C_STO;
    I2CCFG |=~I2C_SI;
    while((I2CCFG&I2C_STO)!=0);
    }
    void gyro_send(unsigned char x)
    {
    I2CDATA = x; 
    I2CCFG &= ~I2C_SI; 
    while ((I2CCFG & I2C_SI) == 0);
    }

    unsigned char gyro_read()
    {
    I2CCFG &= ~I2C_SI; 
    while ((I2CCFG & I2C_SI) == 0); 
    return I2CDATA; 
    }

    void gyro_write(unsigned char reg,unsigned char dat)
    {
    I2CCFG=I2C_SR;

    I2CDATA=0xD4;
    I2CCFG=I2C_DO;

    I2CDATA=reg;
    I2CCFG=I2C_DO;

    I2CDATA=dat;
    I2CCFG=I2C_DO;

    I2CCFG=I2C_SP;

    }
    unsigned char gyro_receive(unsigned char reg)
    {
    I2CCFG=I2C_SR;

    I2CDATA=0xD4;
    I2CCFG=I2C_DO;

    I2CDATA=reg;
    I2CCFG=I2C_DO;

    I2CCFG=I2C_SR;

    I2CDATA=0xD5;
    I2CCFG=I2C_DO;

    I2CCFG=I2C_DO;

    I2CCFG=I2C_SP;

    return I2CDATA;
    }
    void i2c_init()


    //I2CCFG=0x45;
    I2CWC = 0x00;
    }
    void gyro_init()
    {
    gyro_write(0x20,0x0F);
    gyro_write(0x21,0x29);
    gyro_write(0x22,0x80);
    gyro_write(0x23,0x20);
    gyro_write(0x32,0x2C);
    gyro_write(0x33,0xA4);
    gyro_write(0x34,0x2C);
    gyro_write(0x35,0xA4);
    gyro_write(0x36,0x2C);
    gyro_write(0x37,0xA4);
    gyro_write(0x38,0x00);
    gyro_write(0x30,0x2A);
    }

    i16_t L3G4200D_GetAngRateRaw(axis a) 
    {
    u8_t valueL;
    u8_t valueH;
    u16_t value;
    switch (a)
    {
    case X_AXIS:
    valueL=gyro_receive(L3G4200D_OUT_X_L);


    valueH=gyro_receive(L3G4200D_OUT_X_H);


    value = (i16_t)( (valueH << 8) | valueL );
    break;
    case Y_AXIS:
    valueL=gyro_receive(L3G4200D_OUT_Y_L);

    valueH=gyro_receive(L3G4200D_OUT_Y_H);


    value = (i16_t)( (valueH << 8) | valueL );
    break;
    case Z_AXIS:
    valueL=gyro_receive(L3G4200D_OUT_Z_L);


    valueH=gyro_receive(L3G4200D_OUT_Z_H);


    value = (i16_t)( (valueH << 8) | valueL );
    break;
    }
    return value; 
    }

    i am also attaching the schematic for your reference

    4530.CC2541 Keyfob with GYRO.pdf

    A quick reply for this problem will be really helpful for us as we are running out of time

    Thanks in advance

    Regards,

    Krishna