Other Parts Discussed in Thread: TM4C129XNCZAD, TMP102
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++) {}
}
}


