Hi,
I have a Tiva TM4C129XNCZAD development board. I am attempting to communicate with a Honeywell HumidIcon HIH6030-021 humidity sensor via I2C. Here is the sensor I2C datasheet: http://sensing.honeywell.com/i2c%20comms%20humidicon%20tn_009061-2-en_final_07jun12.pdf
The sensor requires that I send the 7-bit address, a write bit, wait for an ACK, and then create a stop condition. Based on http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/320889.aspx - it seems this is not possible. To circumvent this, I simply send a dummy data byte.
After waiting at least 40 ms (or so), I need to read two bytes of data. The master must ACK the first byte, then NACK the second byte and create a stop condition. However, my current setup results in the master _sometimes_ not ACKing the first received byte. The second byte is then lost. Shown below are my logic analyzer outputs.
The first (zoomed out) shows the write cycle, a short delay, then the read cycle. Then, there is a longer delay between the read cycle and the next write cycle.
The second image below zooms in on a read cycle - this one behaves as required.
The third image below zooms in on a different read cycle - this is where I have problems.
My code is listed below. Any help would be appreciated. Thanks.
#define SENSINGTIME 40 // time needed (ms) for sensor to sense data #define SENSINGTASKPERIOD 500 // time between measurement requests in ms #define SENSORADDRESS 0x27 // I2C address of humidity sensor int main(void) { uint32_t ui32Clock; ui32Clock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // enable I2C8 peripheral SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C8); // using I2C8 on pins D2 and D3 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // configure PD2 and PD3 as I2C clock and data lines GPIOPinConfigure(GPIO_PD2_I2C8SCL); GPIOPinConfigure(GPIO_PD3_I2C8SDA); GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_2); GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_3); // set I2C8 as master; use 400 kbps data rate (last param false for 100 kbps) I2CMasterInitExpClk(I2C8_BASE, ui32Clock, true); uint32_t ui32SensingTime = SENSINGTIME; uint32_t ui32SensingPeriod = SENSINGTASKPERIOD; uint8_t ui8SensorAddr = SENSORADDRESS; uint8_t ui8DummyData = '0'; uint32_t ui32ErrStat; uint32_t ui32DataOne; uint32_t ui32DataTwo; while(1) { /* Send measurement request */ // set master to send to humidity sensor // this makes up the "measurement request" in the sensor datasheet terminology I2CMasterSlaveAddrSet(I2C8_BASE, ui8SensorAddr, false); // place dummy data byte to send to sensor I2CMasterDataPut(I2C8_BASE, ui8DummyData); // actually send data I2CMasterControl(I2C8_BASE, I2C_MASTER_CMD_SINGLE_SEND); // wait until Tx done, then wait for measurement to be done while (I2CMasterBusy(I2C8_BASE)) {} ui32ErrStat = I2CMasterErr(I2C8_BASE); if (I2C_MASTER_ERR_NONE == ui32ErrStat) ui32ErrStat = 0; else if (I2C_MASTER_ERR_ADDR_ACK == ui32ErrStat) ui32ErrStat = 1; else if (I2C_MASTER_ERR_DATA_ACK == ui32ErrStat) ui32ErrStat = 2; else if (I2C_MASTER_ERR_ARB_LOST == ui32ErrStat) ui32ErrStat = 3; int i = 0; for (i = 0; i <= 1000000; i++) {} // get two bytes from sensor I2CMasterSlaveAddrSet(I2C8_BASE, ui8SensorAddr, true); I2CMasterControl(I2C8_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); while (I2CMasterBusy(I2C8_BASE)); ui32DataOne = I2CMasterDataGet(I2C8_BASE); I2CMasterControl(I2C8_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); while (I2CMasterBusy(I2C8_BASE)); ui32DataTwo = I2CMasterDataGet(I2C8_BASE); // delay int j = 0; for (j = 0; j <= 2500000; j++) {} } }