From 59c3e1cd29ad038bd9fc0b6aa9c7a8657bba6e94 Mon Sep 17 00:00:00 2001 From: "Christian L. V. Madsen" Date: Sun, 4 May 2025 20:59:55 +0200 Subject: [PATCH] working but needs verifi --- sht30_driver.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++- sht30_driver.h | 35 ++++++++++++- 2 files changed, 171 insertions(+), 3 deletions(-) diff --git a/sht30_driver.c b/sht30_driver.c index 9f3f191..1f59c03 100644 --- a/sht30_driver.c +++ b/sht30_driver.c @@ -2,7 +2,144 @@ * sht30_driver.c * * Created on: 30. apr. 2025 - * Author: Chris + * Author: Christian L. V. Madsen (OZ1CM) */ + #include "sht30_driver.h" + +#define REV16_A(X) (((X) << 8) | ((X)>>8)) +#define REV8_A(X) (((X) << 4) | ((X)>>4)) + +static int isStructOk(SHT30_Struct_Type *inst){ + + if(inst == NULL)return 0; + if(inst->i2c_transfer_inst == NULL)return 0; + if(inst->i2c_transfer_evt == NULL)return 0; + + return 1; +} + +uint8_t crc8_i2c_u16(uint16_t input) { + uint8_t crc = 0xFF; + uint8_t poly = 0x31; + + // Process MSB first (big endian) + for (int i = 1; i >= 0; i--) { + uint8_t byte = (input >> (8 * i)) & 0xFF; + crc ^= byte; + + for (uint8_t j = 0; j < 8; j++) { + if (crc & 0x80) + crc = (crc << 1) ^ poly; + else + crc <<= 1; + } + } + + return crc; // Final XOR is 0x00, so this is the final CRC + +} +static int readRegister(SHT30_Struct_Type *inst, uint8_t *data_addr, uint8_t *data, uint32_t len){ + + // Write what kind of addr we would like to read from: + int ret = inst->i2c_transfer_evt(inst->i2c_transfer_inst,data_addr,2, SHT30_I2C_SET); + + // Read data: + ret += inst->i2c_transfer_evt(inst->i2c_transfer_inst,data,len, SHT30_I2C_GET); + + return ret; +} + +static int writeRegister(SHT30_Struct_Type *inst, uint16_t data_addr, uint8_t *data, uint32_t len){ + + // Write what kind of addr we would like to read from: + inst->i2c_transfer_evt(inst->i2c_transfer_inst,(uint8_t *)&data_addr,2, SHT30_I2C_SET); + + // Write data: + inst->i2c_transfer_evt(inst->i2c_transfer_inst,data,len, SHT30_I2C_SET); + + return 0; +} + +int sht30_writeCmd(SHT30_Struct_Type *inst, uint16_t command){ + + if(!isStructOk(inst))return 1; + + int ret; + uint8_t buffer[2] = {0}; + buffer[0] = (command >> 8) & 0xff; + buffer[1] = (command & 0xff); + ret = inst->i2c_transfer_evt(inst->i2c_transfer_inst,buffer,sizeof(buffer), SHT30_I2C_SET); + + + return ret; + +} + +static int SHT30_resetConnection(SHT30_Struct_Type *inst){ + + if(!isStructOk(inst))return 1; + + for(int i = 0; i< 3; i++){ + int ret = 0; + + ret = sht30_writeCmd(inst,0x30A2); // Soft reset device + ret = sht30_writeCmd(inst,0x272A); // Measurement Command for Periodic Data Acquisition Mode + if(ret == 0){ + return 0; + } + + } + + return 1; + +} + +void SHT30_calcRawData(SHT30_Struct_Type *p){ + p->Message.RawTemp = REV16_A(p->Message.RawTemp); + p->Message.RawHumidity = REV16_A(p->Message.RawHumidity); + + if(crc8_i2c_u16(p->Message.RawTemp) != p->Message.CRC_Temp) return; + if(crc8_i2c_u16(p->Message.RawHumidity) != p->Message.CRC_Humidity) return; + + // Calc Temperature + p->Temperature_mC = p->Message.RawTemp * 17500; + p->Temperature_mC = p->Temperature_mC >> 16; + p->Temperature_mC -= 4500; + + // Calc Humidity + p->Humidity = p->Message.RawHumidity * 100; + p->Humidity = p->Humidity >> 16; + +} + + void sht30_ReadData(SHT30_Struct_Type *inst){ + int ret; + uint8_t reg[2] = {0xe0,0x00}; + ret = readRegister(inst, reg, (void*)&inst->Message, sizeof(SHT30_Message_Type)); + + if(ret != 0){ + SHT30_resetConnection(inst); + + }else{ + SHT30_calcRawData(inst); + } + + + +} + +int sht30_init(SHT30_Struct_Type *inst, void *i2c_transfer_inst, setGet_I2C_Event_fpt i2c_transfer_evt){ + if(inst == NULL)return -1; + if(i2c_transfer_inst == NULL)return -1; + if(i2c_transfer_evt == NULL)return -1; + + inst->i2c_transfer_inst = i2c_transfer_inst; + inst->i2c_transfer_evt = i2c_transfer_evt; + + //SHT30_resetConnection(inst); + + return 0; + +} \ No newline at end of file diff --git a/sht30_driver.h b/sht30_driver.h index 07874de..c26393c 100644 --- a/sht30_driver.h +++ b/sht30_driver.h @@ -7,11 +7,42 @@ #ifndef MAIN_SHT30_DRIVER_SHT30_DRIVER_H_ #define MAIN_SHT30_DRIVER_SHT30_DRIVER_H_ +#include "stdio.h" +#include -typedef struct { +enum{ + SHT30_I2C_GET = 0, + SHT30_I2C_SET = 1, + +}; + +typedef int (*setGet_I2C_Event_fpt)(void *inst, uint8_t *data, uint32_t len, uint8_t set_get); + +typedef struct SHT30_Message{ + uint16_t RawTemp; + uint8_t CRC_Temp; + uint16_t RawHumidity; + uint8_t CRC_Humidity; +}__attribute__((packed)) SHT30_Message_Type; -}sht30_registers_t; +typedef struct SHT30_Struct +{ + // I2C interface + void *i2c_transfer_inst; + setGet_I2C_Event_fpt i2c_transfer_evt; + + // Data + SHT30_Message_Type Message; + int32_t Temperature_mC; + uint32_t Humidity; + +} __attribute__((packed)) SHT30_Struct_Type; + + +int sht30_init(SHT30_Struct_Type *inst, void *i2c_transfer_inst, setGet_I2C_Event_fpt i2c_transfer_evt); +void sht30_ReadData(SHT30_Struct_Type *p); +uint8_t crc8_i2c_u16(uint16_t input); #endif /* MAIN_SHT30_DRIVER_SHT30_DRIVER_H_ */