Reading 2 bytes from ADT7410 via I2C
I've been working for a few days to get a STM32F401 Discovery top talk to an external ADT7410 temperature sensor. I'm just about there. I'm able to read a byte at a time from the device. The last thing I'm having a hard time with is reading 16 bits at a time. The device has this capability, I just need to give it the address of the high byte and I can read the low byute right after the high byte. I don't think I quite understand what calls to use in the Standard Periph Library to do this. Here is the code to do this, I left out some of the beginning part to keep it short.
/* Send ADT7410 register address */ I2C_SendData(I2C1,addr); /* Test on I2C1 EV8 and clear it */ timeout = ADT7410_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) { return ERROR; } } /* Generate the Start Condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on I2C1 EV6 and clear it */ timeout = ADT7410_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) { return ERROR; } } I2C_Send7bitAddress(I2C1, ADT7410_ADDRESS, I2C_Direction_Receiver); /* Test on I2C1 EV6 and clear it */ timeout = ADT7410_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) { return ERROR; } }If I was only doing one byte I would use I2C_Acknowledge here as is shown commented out and that works.
Is this the right call to use? I think it is based on info from the Reference Manual and from commenst in stm32f4xx_i2c.c. I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Next); /* Prepare an NACK for the next data received */ // I2C_AcknowledgeConfig(I2C1, DISABLE); /* Test on I2C1 EV7 and clear it */ timeout = ADT7410_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) { return ERROR; } } /* Receive high byte of Data */ data_high = I2C_ReceiveData(I2C1); // Read low byte of Data /* Prepare an NACK for the next data received */
Do I need to call this again?
I2C_AcknowledgeConfig(I2C1, DISABLE); /* Test on I2C1 EV7 and clear it */ timeout = ADT7410_TIMEOUT_MAX; /* Initialize timeout value */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* If the timeout delay is exeeded, exit with error code */ if ((timeout--) == 0) { return ERROR; } } /* Receive the Data */ data_low = I2C_ReceiveData(I2C1); // Build 16 bit data word *read_data = (uint16_t) data_high; *read_data <<= 8; *read_data += (uint16_t) data_low; I2C_GenerateSTOP(I2C1, ENABLE); /* return the read data */ return SUCCESS; }Hopefully the comments I made in red and italicized will show up.I'd appreciate any comments on this.Thanks.Mike