63 enum ENS210_REG : uint8_t {
64 ENS210_REG_PART_ID = 0x00,
65 ENS210_REG_UID = 0x04,
66 ENS210_REG_SYS_CTRL = 0x10,
67 ENS210_REG_SYS_STAT = 0x11,
68 ENS210_REG_SENS_RUN = 0x21,
69 ENS210_REG_SENS_START = 0x22,
70 ENS210_REG_SENS_STOP = 0x23,
71 ENS210_REG_SENS_STAT = 0x24,
72 ENS210_REG_T_VAL = 0x30,
73 ENS210_REG_H_VAL = 0x33,
75 static const uint8_t ENS210_I2C_SlaveAddressShifted = 0x43 << 1u;
76 static const int ENS210_PartID = 0x0210;
77 static const int ENS210_Boot_Time_MS = 2;
78 static const int ENS210_THConv_Single_MS = 130;
79 static const int ENS210_THConv_Continuous_MS = 238;
81 static const uint8_t ENS210_reset[] =
82 { ENS210_I2C_SlaveAddressShifted, ENS210_REG_SYS_CTRL, 0x80};
83 static const uint8_t ENS210_setActive[] =
84 { ENS210_I2C_SlaveAddressShifted, ENS210_REG_SYS_CTRL, 0x00};
85 static const uint8_t ENS210_setContinuousAndStart[] =
86 { ENS210_I2C_SlaveAddressShifted, ENS210_REG_SENS_RUN, 0x03, 0x03};
89 void ENS210_T::writeRegisters(
const uint8_t *dataStream,
int len) {
95 int ENS210_T::readRegisters(uint8_t firstRegister,
int len) {
97 uint8_t setCAR[2] = { ENS210_I2C_SlaveAddressShifted, firstRegister };
104 static const unsigned char ENS210_read[] =
105 { ENS210_I2C_SlaveAddressShifted | 0x01 };
114 bool ENS210_T::Init() {
118 int OneWireInitError = OneWire_Init();
119 assert(OneWireInitError==0);
120 if(OneWireInitError)
break;
124 int SPUerror = OneWire_Enable_SPU(
true);
130 assert (ds28e18_init_OK);
131 if(!ds28e18_init_OK)
break;
147 assert(configured_GPIO_OK);
148 if(!configured_GPIO_OK)
break;
157 assert(configured_I2C_OK);
158 if(!configured_I2C_OK)
break;
166 assert(writeAndRun_PowerUp_OK);
167 if(!writeAndRun_PowerUp_OK)
break;
171 writeRegisters(ENS210_reset,
sizeof(ENS210_reset));
175 writeRegisters(ENS210_setActive,
sizeof(ENS210_setActive));
179 uint8_t SYS_STAT_idx = readRegisters(ENS210_REG_SYS_STAT, 1);
180 uint8_t PART_ID_idx = readRegisters(ENS210_REG_PART_ID, 2+2+8);
183 assert(writeAndRun_StatusAndPartID_OK);
184 if(!writeAndRun_StatusAndPartID_OK)
break;
189 assert(initSequencerReadOK);
190 if(!initSequencerReadOK)
break;
191 SYS_STAT = sequencer_memory[SYS_STAT_idx];
192 PART_ID = sequencer_memory[PART_ID_idx+1]<<8 | sequencer_memory[PART_ID_idx];
193 printf(
"ENS210::Init read SYS_STAT=x%02X, PARTID=x%04X\n", SYS_STAT, PART_ID);
194 assert(SYS_STAT_Valid());
195 assert(PART_ID_Valid());
196 if( !(SYS_STAT_Valid() && PART_ID_Valid()) )
break;
197 uint8_t DIE_REV_idx = PART_ID_idx+2;
198 dieRevision = sequencer_memory[DIE_REV_idx+1]<<8 | sequencer_memory[DIE_REV_idx];
199 uint8_t UID_idx = DIE_REV_idx+2;
201 (uint64_t)sequencer_memory[UID_idx+7]<<56 |
202 (uint64_t)sequencer_memory[UID_idx+6]<<48 |
203 (uint64_t)sequencer_memory[UID_idx+5]<<40 |
204 (uint64_t)sequencer_memory[UID_idx+4]<<32 |
205 (uint64_t)sequencer_memory[UID_idx+3]<<24 |
206 (uint64_t)sequencer_memory[UID_idx+2]<<16 |
207 (uint64_t)sequencer_memory[UID_idx+1]<< 8 |
208 (uint64_t)sequencer_memory[UID_idx+0]<< 0 ;
209 printf(
"ENS210::Init read dieRevision=x%02X, uniqueDeviceID=x%016llX\n", dieRevision, uniqueDeviceID);
213 writeRegisters(ENS210_setContinuousAndStart,
sizeof(ENS210_setContinuousAndStart));
218 if(!started_OK)
break;
237 bool readTemperatureAndHumidty_OK;
239 static bool DS28E18_SequenceLoaded =
false;
240 static uint8_t T_VAL_idx;
241 static unsigned short TH_readSequenceLength;
242 if(!DS28E18_SequenceLoaded) {
246 T_VAL_idx = readRegisters(ENS210_REG_T_VAL, 6);
250 DS28E18_SequenceLoaded =
true;
255 assert(readTemperatureAndHumidty_OK);
256 if(!readTemperatureAndHumidty_OK) {
264 if(!sequencerReadOK) {
272 auto GetVal = [
this](uint8_t *p, uint32_t &val,
bool &OK,
bool &validCRC) {
274 val = p[1]<<8 | p[0];
276 uint8_t recdCRC = (p[2]>>1)&0x7F;
277 uint32_t payload = (((uint32_t)OK)<<16) | val;
278 uint32_t calcdCRC = crc7(payload);
279 validCRC = (recdCRC == calcdCRC);
284 GetVal(&readback2[T_VAL_idx], T_val, T_OK, T_validCRC);
288 GetVal(&readback2[T_VAL_idx+3], H_val, H_OK, H_validCRC);
290 if(!T_validCRC || !H_validCRC) {
295 if(!(T_OK && H_OK)) {
309 unsigned long ENS210_T::QwikTest() {
311 unsigned long startTimeMS = xTaskGetTickCount() * portTICK_PERIOD_MS;
313 unsigned long elapsedMS = (xTaskGetTickCount() * portTICK_PERIOD_MS) - startTimeMS;
315 static bool initSummaryPrinted;
316 if(!initSummaryPrinted && initOK) {
317 printf(
"ENS210::Init read SYS_STAT=x%02X, PARTID=x%04X\n", SYS_STAT, PART_ID);
318 printf(
"ENS210::Init read dieRevision=x%02X, uniqueDeviceID=x%016llX\n", dieRevision, uniqueDeviceID);
319 initSummaryPrinted =
true;
330 #define CRC7WIDTH 7 // A 7 bits CRC has polynomial of 7th order, which has 8 terms 331 #define CRC7POLY 0x89 // The 8 coefficients of the polynomial 332 #define CRC7IVEC 0x7F // Initial vector has all 7 bits high 334 #define DATA7WIDTH 17 335 #define DATA7MASK ((1UL<<DATA7WIDTH)-1) // 0b 0 1111 1111 1111 1111 336 #define DATA7MSB (1UL<<(DATA7WIDTH-1)) // 0b 1 0000 0000 0000 0000 337 uint32_t ENS210_T::crc7( uint32_t val )
340 uint32_t pol= CRC7POLY;
342 pol = pol << (DATA7WIDTH-CRC7WIDTH-1);
344 uint32_t bit = DATA7MSB;
346 val = val << CRC7WIDTH;
347 bit = bit << CRC7WIDTH;
348 pol = pol << CRC7WIDTH;
352 while( bit & (DATA7MASK<<CRC7WIDTH) ) {
353 if( bit & val ) val ^= pol;
bool DS28E18_WriteGpioConfiguration(DS28E18_target_configuration_register_T CFG_REG_TARGET, uint8_t GPIO_HI, uint8_t GPIO_LO)
Measurement result from ENS210.
uint16_t rawHumidity
relative humidity in 1/512RH (ie a value of 51200 means 100% relative humidity)
int DS28E18_BuildPacket_GetSequencerPacketSize()
Get length of locally constructed command sequencer packet.
OneWire_ROM_ID_T current_DS28E18_ROM_ID
DS28E18 device addressed for current operations (may be one of many on 1-Wire bus) ...
void DS28E18_BuildPacket_ClearSequencerPacket()
Reset local command sequencer packet under construction.
void DS28E18_BuildPacket_Utility_Delay(DS28E18_utility_delay_T delayTimeInMsExponent)
The value was read, the CRC matches, and data is valid.
bool DS28E18_BuildPacket_WriteAndRun()
void DS28E18_BuildPacket_I2C_WriteData(const uint8_t *i2cData, uint8_t i2cDataSize)
unsigned short DS28E18_BuildPacket_I2C_ReadDataWithNackEnd(int readBytes)
void DS28E18_BuildPacket_Utility_SensVddOn()
Driver for a DS28E18 slave on a 1-Wire bus.
There was an I2C communication error attempting to read the value.
unsigned short DS28E18_GetLastSequenceLength()
Retrieve length of constructed sequence, for use in DS28E18_RerunLastSequence(length) ...
bool DS28E18_WriteConfiguration(DS28E18_protocol_speed_T SPD, DS28E18_ignore_nack_T INACK, DS28E18_protocol_T PROT, DS28E18_spi_mode_T SPI_MODE)
The value was read, the CRC matches, but the data is invalid (e.g. the measurement was not yet finish...
uint16_t rawTemperature
temperature in 1/64 Kelvin, corrected for solder offset
Public C++ interface for the ENS210 temperature and humidity sensor driver.
void DS28E18_BuildPacket_I2C_Start()
void DS28E18_BuildPacket_I2C_Stop()
bool DS28E18_ReadSequencer(unsigned short nineBitStartingAddress, uint8_t *rxData, unsigned short readLength)
The value was read, but the CRC over the payload (valid and data) does not match. ...
bool DS28E18_RerunLastSequence(unsigned int length)
General 1-Wire API using the DS2485 1-Wire master.