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 Problem with Transaction for AM2320 sensor with CC1310?

Other Parts Discussed in Thread: CC1310, CC2650

Hi guys,

I'm new bie in Embedded System. I have a temperature and humdity sensor - AOSONG AM2320 which is comminication with my CC1310 via I2C. This sensor require receive a command to get data follow this structure: START + (I 2 C address + W) + function code (0x03) + start address + number of registers + STOP.

I'm using I2C_transfer to sent 3 bytes (function code, start address and number of register) to sensor but I2C_transfer is not OK. I read many time in datasheet and CC13xx Driver Library and TI-RTOS but I can't find how to get data from my sensor. Plz some body help me.

Here is my code but it's not work: 

Void taskFxn(UArg arg0, UArg arg1) {
	unsigned int i;
	uint16_t temperature;
	uint16_t humidity;
	uint8_t txBuffer[3];
	uint8_t rxBuffer[8];
	I2C_Handle i2c;
	I2C_Params i2cParams;
	I2C_Transaction i2cTransaction;

	/* Create I2C for usage */
	I2C_Params_init(&i2cParams);
	i2cParams.bitRate = I2C_100kHz;
	i2c = I2C_open(CC1310_LAUNCHXL_I2C0, &i2cParams);
	if (i2c == NULL) {
		System_abort("Error Initializing I2C\n");
	} else {
		System_printf("I2C Initialized!\n");
	}

	//Read data from AM2320 sensor
	txBuffer[0] = 0x03;
	txBuffer[1] = 0x00;
	txBuffer[2] = 0x04;
	i2cTransaction.slaveAddress = 0x5c;
	i2cTransaction.writeBuf = txBuffer;
	i2cTransaction.writeCount = 3;
	i2cTransaction.readBuf = rxBuffer;
	i2cTransaction.readCount = 8;
	if (I2C_transfer(i2c, &i2cTransaction)) {
		/* Extract degrees C from the received data */
		temperature = rxBuffer[2];
		temperature = (temperature << 8);
		temperature |= rxBuffer[3];
		System_printf("Temperature: %d (C)\n", temperature);

		/* Extract humidity RH from the received data */
		humidity = rxBuffer[4];
		humidity = (humidity << 8);
		humidity |= rxBuffer[5];
		System_printf("Humidity: %d (RH)\n", humidity);
	} else {
		System_printf("I2C Bus fault\n");
	}

	/* Deinitialized I2C */
	I2C_close( i2c);
	System_printf("I2C closed!\n");

	System_flush();
}

  • Try to refer to sunmaysky.blogspot.tw/.../basic-example-to-use-hdc1080-on-cc2650.html which shows you I2C example using CC2650 but it can also apply to CC1310.
  • Thanks for for your support, but I tried many times with many codes of TI's sensor, but it's not work.
  • Thanks for your support, But I tried many times with another codes of TI's sensors such as HDC, TMP, light which are not work with my sensor. Plz give me some suggestions.
    I'm try mapping with sensortag's code from https://github.com/contiki-os/contiki/blob/master/platform/srf06-cc26xx/sensortag/board-i2c.c.  And here is my code with driverlib/i2c. But It's also not work.

    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* TI-RTOS Header files */
    // #include <ti/drivers/I2C.h>
    #include <ti/drivers/PIN.h>
    // #include <ti/drivers/SPI.h>
    #include <ti/drivers/UART.h>
    #include <ti/drivers/i2c/I2CCC26XX.h>
    #include <ti/boards/CC1350_LAUNCHXL/Board.h>
    // #include <ti/drivers/Watchdog.h>
    
    /* Board Header files */
    #include "Board.h"
    #include "driverlib/i2c.h"
    #include "driverlib/uart.h"
    #include "driverlib/prcm.h"
    #include "driverlib/sys_ctrl.h"
    /* Display */
    #include <ti/mw/display/Display.h>
    
    
    #define TASKSTACKSIZE   512
    #define AM2320_ADDR 0x5C
    //Start measurement at 1lx resolution. Time typically 16ms.
    #define FUNCTION_CODE 0x03
    
    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];
    
    #define NO_INTERFACE 0xFF
    /*---------------------------------------------------------------------------*/
    static uint8_t slave_addr = 0x00;
    static uint8_t interface = NO_INTERFACE;
    /*---------------------------------------------------------------------------*/
    
    static bool
    accessible(void)
    {
      /* First, check the PD */
      if(PRCMPowerDomainStatus(PRCM_DOMAIN_SERIAL)
         != PRCM_DOMAIN_POWER_ON) {
        return false;
      }
    
      /* Then check the 'run mode' clock gate */
      if(!(HWREG(PRCM_BASE + PRCM_O_I2CCLKGR) & PRCM_I2CCLKGR_CLK_EN)) {
        return false;
      }
    
      return true;
    }
    /*---------------------------------------------------------------------------*/
    void
    board_i2c_wakeup()
    {
      /* First, make sure the SERIAL PD is on */
      PRCMPowerDomainOn(PRCM_DOMAIN_SERIAL);
      while((PRCMPowerDomainStatus(PRCM_DOMAIN_SERIAL)
            != PRCM_DOMAIN_POWER_ON));
    
      /* Enable the clock to I2C */
      PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0);
      PRCMLoadSet();
      while(!PRCMLoadGet());
    
      /* Enable and initialize the I2C master module */
      I2CMasterInitExpClk(I2C0_BASE, SysCtrlClockGet(),
                                     true);
    }
    /*---------------------------------------------------------------------------*/
    static bool
    i2c_status()
    {
      uint32_t status;
    
      status = I2CMasterErr(I2C0_BASE);
      if(status & (I2C_MSTAT_DATACK_N_M | I2C_MSTAT_ADRACK_N_M)) {
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
      }
    
      return status == I2C_MASTER_ERR_NONE;
    }
    /*---------------------------------------------------------------------------*/
    void
    board_i2c_shutdown()
    {
      interface = NO_INTERFACE;
    
      if(accessible()) {
        I2CMasterDisable(I2C0_BASE);
      }
    
      PRCMPeripheralRunDisable(PRCM_PERIPH_I2C0);
      PRCMLoadSet();
      while(!PRCMLoadGet());
    
    //  /*
    //   * Set all pins to GPIO Input and disable the output driver. Set internal
    //   * pull to match external pull
    //   *
    //   * SDA and SCL: external PU resistor
    //   * SDA HP and SCL HP: MPU PWR low
    //   */
    //  IOCPinTypeGpioInput(BOARD_IOID_SDA_HP);
    //  IOCIOPortPullSet(BOARD_IOID_SDA_HP, IOC_IOPULL_DOWN);
    //  IOCPinTypeGpioInput(BOARD_IOID_SCL_HP);
    //  IOCIOPortPullSet(BOARD_IOID_SCL_HP, IOC_IOPULL_DOWN);
    //
    //  IOCPinTypeGpioInput(BOARD_IOID_SDA);
    //  IOCIOPortPullSet(BOARD_IOID_SDA, IOC_IOPULL_UP);
    //  IOCPinTypeGpioInput(BOARD_IOID_SCL);
    //  IOCIOPortPullSet(BOARD_IOID_SCL, IOC_IOPULL_UP);
    }
    /*---------------------------------------------------------------------------*/
    bool
    board_i2c_write(uint8_t *data, uint8_t len)
    {
      uint32_t i;
      bool success;
    
      /* Write slave address */
      I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);
    
      /* Write first byte */
      I2CMasterDataPut(I2C0_BASE, data[0]);
    
      /* Check if another master has access */
      while(I2CMasterBusBusy(I2C0_BASE));
    
      /* Assert RUN + START */
      I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
      while(I2CMasterBusy(I2C0_BASE));
      success = i2c_status();
    
      for(i = 1; i < len && success; i++) {
        /* Write next byte */
        I2CMasterDataPut(I2C0_BASE, data[i]);
        if(i < len - 1) {
          /* Clear START */
          I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
          while(I2CMasterBusy(I2C0_BASE));
          success = i2c_status();
        }
      }
    
      /* Assert stop */
      if(success) {
        /* Assert STOP */
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
        while(I2CMasterBusy(I2C0_BASE));
        success = i2c_status();
        while(I2CMasterBusBusy(I2C0_BASE));
      }
    
      return success;
    }
    /*---------------------------------------------------------------------------*/
    void board_i2c_write_single(uint8_t i2c_device_addr, uint8_t funcCode, bool bitRate)
    {
    	/* Initialize the display and try to open both UART and LCD types of display. */
    	Display_Params dparams;
    	Display_Params_init(&dparams);
    	dparams.lineClearMode = DISPLAY_CLEAR_BOTH;
    	Display_Handle uartDisplayHandle = Display_open(Display_Type_UART,
    			&dparams);
    
    	/* Write slave address */
    	I2CMasterSlaveAddrSet(I2C0_BASE, i2c_device_addr, bitRate);
    
    	/* Write first byte */
    	I2CMasterDataPut(I2C0_BASE, funcCode);
    
    	/* Assert RUN + START + STOP */
    	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    	while(I2CMasterBusy(I2C0_BASE));
    	System_printf("Write Single Device Successful");
    	CPUdelay(16000000 / 3 / 40);
    
    }
    /*---------------------------------------------------------------------------*/
    uint32_t board_i2c_read(uint8_t i2c_device_addr, uint8_t bitRead) {
    	/* Initialize the display and try to open both UART and LCD types of display. */
    	Display_Params dparams;
    	Display_Params_init(&dparams);
    	dparams.lineClearMode = DISPLAY_CLEAR_BOTH;
    	Display_Handle uartDisplayHandle = Display_open(Display_Type_UART,
    			&dparams);
    	uint32_t ambLight;
    
    	/* Set slave address */
    	I2CMasterSlaveAddrSet(I2C0_BASE, i2c_device_addr, bitRead);
    
    	/* Assert RUN + START + ACK */
    	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
    
    	while (I2CMasterBusy(I2C0_BASE));
    	//High byte was pulled from the slave
    	ambLight = I2CMasterDataGet(I2C0_BASE);
    	ambLight <<= 8;
    	System_printf("Hight_Byte = %d; ", ambLight);
    	CPUdelay(16000000 / 10 / 40);
    	//send control byte and read data from slave
    	I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
    
    	//Low byte was pulled from the slave
    	uint32_t temp_Low = I2CMasterDataGet(I2C0_BASE);
    	ambLight |= temp_Low;
    	System_printf("Low_Byte = %d; ", temp_Low);
    
    	return ambLight;
    
    
    
    /*  i = 0;
      success = true;
      while(i < (len - 1) && success) {
        while(I2CMasterBusy(I2C0_BASE));
        success = i2c_status();
        if(success) {
          data[i] = I2CMasterDataGet(I2C0_BASE);
          I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
          i++;
        }
      }*/
    
     /* if(success) {
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
        while(I2CMasterBusy(I2C0_BASE));
        success = i2c_status();
        if(success) {
          data[len - 1] = I2CMasterDataGet(I2C0_BASE);
          while(I2CMasterBusBusy(I2C0_BASE));
        }
      }
      return success;*/
    }
    
    /*---------------------------------------------------------------------------*/
    bool
    board_i2c_write_read(uint8_t *wdata, uint8_t wlen, uint8_t *rdata, uint8_t rlen)
    {
      uint32_t i;
      bool success;
    
      /* Set slave address for write */
      I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);
    
      /* Write first byte */
      I2CMasterDataPut(I2C0_BASE, wdata[0]);
    
      /* Check if another master has access */
      while(I2CMasterBusBusy(I2C0_BASE));
    
      /* Assert RUN + START */
      I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
      while(I2CMasterBusy(I2C0_BASE));
      success = i2c_status();
    
      for(i = 1; i < wlen && success; i++) {
        /* Write next byte */
        I2CMasterDataPut(I2C0_BASE, wdata[i]);
        if(i < wlen - 1) {
          /* Clear START */
          I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
          while(I2CMasterBusy(I2C0_BASE));
          success = i2c_status();
        }
      }
      if(!success) {
        return false;
      }
    
      /* Set slave address for read */
      I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true);
    
      /* Assert ACK */
      I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
    
      i = 0;
      while(i < (rlen - 1) && success) {
        while(I2CMasterBusy(I2C0_BASE));
        success = i2c_status();
        if(success) {
          rdata[i] = I2CMasterDataGet(I2C0_BASE);
          I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
          i++;
        }
      }
    
      if(success) {
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
        while(I2CMasterBusy(I2C0_BASE));
        success = i2c_status();
        if(success) {
          rdata[rlen - 1] = I2CMasterDataGet(I2C0_BASE);
          while(I2CMasterBusBusy(I2C0_BASE));
        }
      }
    
      return success;
    }
    /*---------------------------------------------------------------------------*/
    void
    board_i2c_select(uint8_t new_interface, uint8_t address)
    {
      slave_addr = address;
    
      if(accessible() == false) {
        board_i2c_wakeup();
      }
    
      if(new_interface != interface) {
        interface = new_interface;
    
        I2CMasterDisable(I2C0_BASE);
    
        /* Enable and initialize the I2C master module */
        I2CMasterInitExpClk(I2C0_BASE, 16000000,
                                       true);
      }
    }
    /*---------------------------------------------------------------------------*/
    /** @} */
    
    // Get AM2320
    void getAM2320(UArg arg0, UArg arg1) {
    	/* Initialize the display and try to open both UART and LCD types of display. */
    	Display_Params dparams;
    	Display_Params_init(&dparams);
    	dparams.lineClearMode = DISPLAY_CLEAR_BOTH;
    	Display_Handle uartDisplayHandle = Display_open(Display_Type_UART,
    			&dparams);
    	board_i2c_wakeup();
    	uint32_t Temp= 0;
    	board_i2c_write_single(AM2320_ADDR,FUNCTION_CODE, I2C_100kHz);
    	while (1) {
    		Temp= board_i2c_read(AM2320_ADDR, true);
    		Display_print1(uartDisplayHandle, 0, 0, "%d; ", Temp);
    		System_printf("ambLigh1.2 = %d \r\n", Temp);
    	}
    }
    
    /*
     *  ======== main ========
     */
    int main(void) {
    	Task_Params taskParams;
    	/* Call board init functions */
    	Board_initGeneral();
    	// Board_initI2C();
    	// Board_initSPI();
    	// Board_initUART();
    	// Board_initWatchdog();
    
    	/* Construct heartBeat Task  thread */
    	Task_Params_init(&taskParams);
    	taskParams.arg0 = 1000000 / Clock_tickPeriod;
    	taskParams.stackSize = TASKSTACKSIZE;
    	taskParams.stack = &task0Stack;
    	Task_construct(&task0Struct, (Task_FuncPtr) getAM2320, &taskParams,
    			NULL);
    
        System_flush();
    
        /* Start BIOS */
        BIOS_start();
        return (0);
    
    }
    

  • When you test I2C, I suggest you using oscilloscope to check if you can see clock output on I2C SCL pin first.
  • Hi,

    I am facing similar issue. Did you ever get this to work?

    Thanks

    ankit