#include <project.h>
#include "TemAndHum.h"
#define i2cAddWrite_8bit 0x88
#define i2cAddRead_8bit 0x89
/*CRC*/
#define POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001
/****************************************************************/
uint8 Tem_Value = 0;
uint8 RH_Value = 0;
uint8 buffer[6];
/************************* Inside io ****************************/
void SDA_H(void)
{
I2C_SDA_Write(1);
}
void SDA_L(void)
{
I2C_SDA_Write(0);
}
uint8 SDA_Read(void)
{
return I2C_SDA_Read();
}
void SCL_H(void)
{
I2C_SCL_Write(1);
}
void SCL_L(void)
{
I2C_SCL_Write(0);
}
/***************************************************************/
/***************************************************************/
void i2c_delay(void)
{
CyDelayUs(2);
}
uint8 i2c_star(void)
{
SDA_H();
SCL_H();
i2c_delay();
if (!SDA_Read())
return 1;
SDA_L();
i2c_delay();
if (SDA_Read())
return 1;
SDA_L();
SCL_L();
i2c_delay();
return 0;
}
void i2c_stop(void)
{
SCL_L();
i2c_delay();
SDA_L();
i2c_delay();
SCL_H();
i2c_delay();
SDA_H();
i2c_delay();
}
void i2c_ack(void)
{
SCL_L();
i2c_delay();
SDA_L();
i2c_delay();
SCL_H();
i2c_delay();
SCL_L();
i2c_delay();
}
void i2c_noAck(void)
{
SCL_L();
i2c_delay();
SDA_H();
i2c_delay();
SCL_H();
i2c_delay();
SCL_L();
i2c_delay();
}
uint8 i2c_waitAck(void)
{
uint8 t = 100;
SCL_L();
i2c_delay();
SDA_H();
i2c_delay();
SCL_H();
i2c_delay();
while( SDA_Read() )
{
t --;
if(t==0)
{
SCL_L();
return 1;
}
i2c_delay();
}
SCL_L();
i2c_delay();
return 0;
}
void i2c_sendByte( uint8 byte )
{
uint8 i = 8;
while (i--) {
SCL_L();
i2c_delay();
if (byte & 0x80)
SDA_H();
else
SDA_L();
byte <<= 1;
i2c_delay();
SCL_H();
i2c_delay();
}
SCL_L();
i2c_delay();
}
uint8 i2c_readByte(void)
{
uint8 i = 8;
uint8 byte = 0;
SDA_H();
while (i--)
{
byte <<= 1;
SCL_L();
i2c_delay();
SCL_H();
i2c_delay();
if (SDA_Read())
{
byte |= 0x01;
}
}
SCL_L();
i2c_delay();
return byte;
}
/******************************************************/
void SHT3X_WriteCMD(uint16 cmd)
{
i2c_star();
i2c_sendByte(i2cAddWrite_8bit);
i2c_waitAck();
i2c_sendByte(cmd>>8);
i2c_waitAck();
i2c_sendByte(cmd);
i2c_waitAck();
i2c_stop();
}
/********************************************************/
void SHT3X_SetPeriodicMeasurement()
{
SHT3X_WriteCMD(CMD_MEAS_PERI_2_H);
}
void SHT3X_ReadState(uint8 *temp)
{
i2c_star();
i2c_sendByte(i2cAddWrite_8bit);
i2c_waitAck();
i2c_sendByte(0xf3);
i2c_waitAck();
i2c_sendByte(0X2d);
i2c_waitAck();
i2c_star();
i2c_sendByte(i2cAddRead_8bit);
i2c_waitAck();
temp[0] = i2c_readByte();
i2c_ack();
temp[1] = i2c_readByte();
i2c_ack();
temp[2] = i2c_readByte();
i2c_noAck();
i2c_stop();
}
void SHX3X_ReadResults(uint16 cmd, uint8 *p)
{
i2c_star();
i2c_sendByte(i2cAddWrite_8bit);
i2c_waitAck();
i2c_sendByte(cmd>>8);
i2c_waitAck();
i2c_sendByte(cmd);
i2c_waitAck();
i2c_star();
i2c_sendByte(i2cAddRead_8bit);
i2c_waitAck();
p[0] = i2c_readByte();
i2c_ack();
p[1] = i2c_readByte();
i2c_ack();
p[2] = i2c_readByte();
i2c_ack();
p[3] = i2c_readByte();
i2c_ack();
p[4] = i2c_readByte();
i2c_ack();
p[5] = i2c_readByte();
i2c_noAck();
i2c_stop();
}
/********************************************************************************/
/********************************************************************************/
void SHT_Init(void)
{
CyDelay(250); /* Must add delay */
SHT3X_SetPeriodicMeasurement();
CyDelay(150); /* Must add delay */
}
uint8 SHT3X_CalcCrc(uint8_t *data, uint8_t nbrOfBytes)
{
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);
}
}
}
return crc;
}
uint8 SHT3X_CheckCrc(uint8_t *pdata, uint8_t nbrOfBytes, uint8_t checksum)
{
uint8_t crc;
crc = SHT3X_CalcCrc(pdata, nbrOfBytes);// calculates 8-Bit checksum
if(crc != checksum)
{
return 1;
}
return 0;
}
uint16 SHT3X_CalcTemperature(uint16_t rawValue)
{
// calculate temperature
uint16 temp;
temp = (175 * (float)rawValue / 65535 - 45) ; // T = -45 + 175 * rawValue / (2^16-1)
return temp;
}
uint8 SHT3X_CalcRH(uint16_t rawValue)
{
// calculate relative humidity [%RH]
uint8 temp1 = (100 * (float)rawValue / 65535) ; // RH = rawValue / (2^16-1) * 10
return temp1;
}
void SHT_GetValue(void)
{
uint8 temp = 0;
uint16 dat;
uint8 p[3];
SHX3X_ReadResults(CMD_FETCH_DATA, buffer);
/* check tem */
p[0] = buffer[0];
p[1] = buffer[1];
p[2] = buffer[2];
temp = SHT3X_CheckCrc(p,2,p[2]);
if( !temp ) /* value is ture */
{
dat = ((uint16)buffer[0] << 8) | buffer[1];
Tem_Value = SHT3X_CalcTemperature( dat );
}
/* check humidity */
p[0] = buffer[3];
p[1] = buffer[4];
p[2] = buffer[5];
temp = SHT3X_CheckCrc(p,2,p[2]);
if( !temp )
{
dat = ((uint16)p[0] << 8) | p[1];
RH_Value = SHT3X_CalcRH( dat );
}
}