#include "device.h" #include "PinNames.h" #include "basic_types.h" #include "diag.h" #include "osdep_api.h" #include "i2c_api.h" #include "pinmap.h" #include "rtl_lib.h" #define NO_ERROR 0x00 #define ACK_ERROR 0x01 #define CHECKSUM_ERROR 0x02 #define NULL_ERROR 0x03 #define MBED_I2C_MTR_SDA PD_4 #define MBED_I2C_MTR_SCL PD_5 #define MBED_I2C_SLAVE_ADDR0 0x70 #define POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001 #define MBED_I2C_BUS_CLK 100000 //hz #define I2C_DATA_MAX_LENGTH 16 uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH]; uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH]; int i2cdata_read_pos; volatile i2c_t i2cmaster; // Sensor Commands #define READ_ID 0xEFC8 // command: read ID register #define SOFT_RESET 0x805D // soft resetSample Code for SHTC1 #define MEAS_T_RH_POLLING 0x7866 // meas. read T first, clock stretching disabled #define MEAS_T_RH_CLOCKSTR 0x7CA2 // meas. read T first, clock stretching enabled #define MEAS_RH_T_POLLING 0x58E0 // meas. read RH first, clock stretching disabled #define MEAS_RH_T_CLOCKSTR 0x5C24 // meas. read RH first, clock stretching enabled static int SHTC1_GetID(uint16_t *id); static void SHTC1_WriteCommand(uint16_t cmd); static int SHTC1_Read2BytesAndCrc(uint16_t *data); static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum); static float SHTC1_CalcTemperature(uint16_t rawValue); static float SHTC1_CalcHumidity(uint16_t rawValue); int SHTC1_Init(uint16_t *pID) { int error = NO_ERROR; DiagPrintf("SHTC1_Init \r\n"); i2c_init((i2c_t*)&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); i2c_frequency((i2c_t*)&i2cmaster,MBED_I2C_BUS_CLK); if (pID == NULL ) return NULL_ERROR; error = SHTC1_GetID(pID); return error; } static int SHTC1_GetID(uint16_t *id) { int error = NO_ERROR; uint8_t bytes[2]; uint8_t checksum; SHTC1_WriteCommand(READ_ID); i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 3, 1); i2cdata_read_pos = 0; error = SHTC1_Read2BytesAndCrc(id); return error; } static int SHTC1_Read2BytesAndCrc(uint16_t *data) { int error; int readed; uint8_t bytes[2]; uint8_t checksum; bytes[0] = i2cdata_read[i2cdata_read_pos++]; bytes[1] = i2cdata_read[i2cdata_read_pos++]; checksum = i2cdata_read[i2cdata_read_pos++]; error = SHTC1_CheckCrc(bytes, 2, checksum); *data = (bytes[0] << 8) | bytes[1]; return error; } static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum) { uint8_t bit; // bit mask uint8_t crc = 0xFF; // calculated checksum uint8_t byteCtr; // byte counter // calculates 8-Bit checksum with given polynomial for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++) { crc ^= (data[byteCtr]); for(bit = 8; bit > 0; --bit) { if(crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL; else crc = (crc << 1); } } // verify checksum if(crc != checksum) return CHECKSUM_ERROR; else return NO_ERROR; } static void SHTC1_WriteCommand(uint16_t cmd) { int writebytes; i2cdata_write[0] = (uint8_t)(cmd >>8); i2cdata_write[1] = (uint8_t)(cmd&0xFF); i2c_write((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1); } static float SHTC1_CalcTemperature(uint16_t rawValue) { return 175.0 * (float)rawValue / 65536.0 - 45.0; } static float SHTC1_CalcHumidity(uint16_t rawValue) { return 100.0 * (float)rawValue / 65536.0; } int SHTC1_GetTempAndHumi(float *temp, float *humi) { int error; uint16_t rawValueTemp; uint16_t rawValueHumi; SHTC1_WriteCommand(MEAS_T_RH_CLOCKSTR); //Wire1.requestFrom(I2C_ADR_SHTC1, 6); i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 6, 1); i2cdata_read_pos = 0; error = NO_ERROR; error |= SHTC1_Read2BytesAndCrc(&rawValueTemp); error |= SHTC1_Read2BytesAndCrc(&rawValueHumi); //diag_printf("raw temp=0x%x, raw humidity=0x%x, error=%d\n", // rawValueTemp, rawValueHumi, error); if ( error == NO_ERROR ) { *temp = SHTC1_CalcTemperature(rawValueTemp); *humi = SHTC1_CalcHumidity(rawValueHumi); } return error; } void main(void) { gpio_t gpio_led; int led_status; int i2clocalcnt; int error; uint16_t shtc1_id; float temperature = 1.123f; float humidity = 2.456f; DBG_8195A("sleep 10 sec. to wait for UART console\n"); RtlMsleepOS(10000); DBG_8195A("start i2c example - SHTC1\n"); error = SHTC1_Init(&shtc1_id); if ( error == NO_ERROR ) { DiagPrintf("SHTC1 init ok, id=0x%x\r\n", shtc1_id); } else { DiagPrintf("SHTC1 init FAILED! \r\n"); for(;;); } while(1){ error = SHTC1_GetTempAndHumi(&temperature, &humidity); rtl_printf("temp=%f, humidity=%f, error=%d\n", temperature, humidity, error); RtlMsleepOS(1000); } }