
//==============================================================================
//    E - R A D I O N I C A . C O M,  H.Kolomana 6/A, Djakovo 31400, Croatia
//==============================================================================
// Project   :  SHT21 Arduino Library (V1.0)
// File      :  SHT21.cpp
// Author    :  e-radionica.com 2017
// Licence   :  Open-source !
//==============================================================================
//==============================================================================
// Use with any SHT21 breakout. Check ours:
// https://e-radionica.com/en/sht21-humidity-and-temperature-sensor.html
// If any questions,
// just contact techsupport@e-radionica.com
//==============================================================================


// Modified for ChibiOS Mike James Feb 2020
#include "ch.h"
#include <SHT21.h>


//==============================================================================
// PUBLIC
//==============================================================================
float SHT21::getHumidity(void) {
	uint16_t result; 	// return variable

	result = readSensor_hm(TRIGGER_RH_MEASUREMENT_HM);

	return CalcRH(result);
}

float SHT21::getTemperature(void) {
	uint16_t result; 	// return variable

	result = readSensor_hm(TRIGGER_T_MEASUREMENT_HM);

	return CalcT(result);
}

void SHT21::reset() {


	const uint8_t buff = SOFT_RESET;
	msg_t err = i2cMasterTransmit(&I2CD2, I2C_ADD, buff, sizeof(buff), 0,0);
	    if(err != MSG_OK)


	chThdSleepMillisec(15);	// wait for SHT to reset
}

msg_t SHT21::getSerialNumber(uint8_t * serialNumber) {

	uint8_t serialNumber[8];

	// read memory location 1
	const uint8_t buff = { 0xFA,0xOF };

	uin8_r snRbuff[8];
	msg_t err = i2cMasterTransmit(&I2CD2, I2C_ADD, buff, sizeof(buff), &snRbuff, sizeof(snRbuff));
    if(err != MSG_OK)
    	return err;

	serialNumber[5] = snRbuff[0];	// read SNB_3
	            					// CRC SNB_3 not used
	serialNumber[4] = snrBuff[2];   // read SNB_2
	            					// CRC SNB_2 not used
	serialNumber[3] = snrBuff[4];	// read SNB_1
	    	            			// CRC SNB_1 not used
	serialNumber[2] = snrBuff[7];	// read SNB_0
	            					// CRC SNB_0 not used

	// read memory location 2
    const uint8_t buff2 = {0xFC,0xC9};

	err = i2cMasterTransmit(&I2CD2, I2C_ADD, buff2, sizeof(buff2), &snRbuff, 6);


	serialNumber[1] = snRbuff[0];	// read SNC_1
	serialNumber[0] = snRbuff[1];   // read SNC_0
	serialNumber[7] = snRbuff[3];	// read SNA_1
	serialNumber[6] = snRbuff[4];	// read SNA_0

	return serialNumber[return_sn];
}

//==============================================================================
// PRIVATE
//==============================================================================

uint16_t SHT21::readSensor_hm(uint8_t command) {
	uint8_t checksum;
	uint8_t data[2];
	uint16_t result;

	uint8_t rxBuff[3];
	err = i2cMasterTransmit(&I2CD2, I2C_ADD, &command, 1, &rxRbuff, 3);
	if (err != MSG_OK)

	data[0] = rxBuff[0]; 	// read data (MSB)
	data[1] = rxBuff[1]; 	// read data (LSB)
	checksum = rxBuff[2];	// read checksum

	result = (data[0] << 8);
	result += data[1];

	if(CRC_Checksum (data,2,checksum)) {
		reset();
		return 1;
	}

	else return result;
}

float SHT21::CalcRH(uint16_t rh) {

	rh &= ~0x0003;	// clean last two bits

  	return (-6.0 + 125.0/65536 * (float)rh); // return relative humidity
}

float SHT21::CalcT(uint16_t t) {

	t &= ~0x0003;	// clean last two bits

	return (-46.85 + 175.72/65536 * (float)t);
}

uint8_t SHT21::CRC_Checksum(uint8_t data[], uint8_t no_of_bytes, uint8_t checksum) {
	uint8_t crc = 0;
  	uint8_t byteCtr;

 	 //calculates 8-Bit checksum with given polynomial
  	for (byteCtr = 0; byteCtr < no_of_bytes; ++byteCtr)
 	 { crc ^= (data[byteCtr]);
 	   for (uint8_t bit = 8; bit > 0; --bit)
 	   { if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
 	     else crc = (crc << 1);
 	   }
 	 }
 	 if (crc != checksum) return 1;
 	 else return 0;
}


