/*
 * THIS FILE IS AUTOMATICALLY GENERATED
 *
 * Generator:     sensirion-driver-generator 0.40.0
 * Product:       sht4x
 * Model-Version: 2.1.1
 */
/*
 * Copyright (c) 2024, Sensirion AG
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of Sensirion AG nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "SensirionI2cSht4x.h"
#include <Arduino.h>

// make sure that we use the proper definition of NO_ERROR
#ifdef NO_ERROR
#undef NO_ERROR
#endif
#define NO_ERROR 0

static uint8_t communication_buffer[6] = {0};

SensirionI2cSht4x::SensirionI2cSht4x() {
}

float SensirionI2cSht4x::signalTemperature(uint16_t temperatureTicks) {
    float temperature = 0.0;
    temperature = (float)(temperatureTicks);
    temperature = ((temperature * 175.0) / 65535.0) - 45.0;
    return temperature;
}

float SensirionI2cSht4x::signalHumidity(uint16_t humidityTicks) {
    float humidity = 0.0;
    humidity = (float)(humidityTicks);
    humidity = ((humidity * 125.0) / 65535.0) - 6.0;
    return humidity;
}

int16_t SensirionI2cSht4x::measureHighPrecision(float& aTemperature,
                                                float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = measureHighPrecisionTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::measureMediumPrecision(float& aTemperature,
                                                  float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = measureMediumPrecisionTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::measureLowestPrecision(float& aTemperature,
                                                  float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = measureLowestPrecisionTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateHighestHeaterPowerLong(float& aTemperature,
                                                          float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = activateHighestHeaterPowerLongTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateHighestHeaterPowerShort(float& aTemperature,
                                                           float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = activateHighestHeaterPowerShortTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateMediumHeaterPowerLong(float& aTemperature,
                                                         float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = activateMediumHeaterPowerLongTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateMediumHeaterPowerShort(float& aTemperature,
                                                          float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = activateMediumHeaterPowerShortTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateLowestHeaterPowerLong(float& aTemperature,
                                                         float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = activateLowestHeaterPowerLongTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateLowestHeaterPowerShort(float& aTemperature,
                                                          float& aHumidity) {
    uint16_t tempTicks = 0;
    uint16_t humiTicks = 0;
    int16_t localError = 0;
    localError = activateLowestHeaterPowerShortTicks(tempTicks, humiTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    aTemperature = SensirionI2cSht4x::signalTemperature(tempTicks);
    aHumidity = SensirionI2cSht4x::signalHumidity(humiTicks);
    return localError;
}

int16_t SensirionI2cSht4x::measureHighPrecisionTicks(uint16_t& temperatureTicks,
                                                     uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0xfd, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(10);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t
SensirionI2cSht4x::measureMediumPrecisionTicks(uint16_t& temperatureTicks,
                                               uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0xf6, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(5);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t
SensirionI2cSht4x::measureLowestPrecisionTicks(uint16_t& temperatureTicks,
                                               uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0xe0, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(2);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateHighestHeaterPowerLongTicks(
    uint16_t& temperatureTicks, uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0x39, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(1100);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateHighestHeaterPowerShortTicks(
    uint16_t& temperatureTicks, uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0x32, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(110);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateMediumHeaterPowerLongTicks(
    uint16_t& temperatureTicks, uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0x2f, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(1100);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateMediumHeaterPowerShortTicks(
    uint16_t& temperatureTicks, uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0x24, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(110);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateLowestHeaterPowerLongTicks(
    uint16_t& temperatureTicks, uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0x1e, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(1100);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t SensirionI2cSht4x::activateLowestHeaterPowerShortTicks(
    uint16_t& temperatureTicks, uint16_t& humidityTicks) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0x15, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(110);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(temperatureTicks);
    localError |= rxFrame.getUInt16(humidityTicks);
    return localError;
}

int16_t SensirionI2cSht4x::serialNumber(uint32_t& serialNumber) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0x89, buffer_ptr, 6);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(10);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt32(serialNumber);
    return localError;
}

int16_t SensirionI2cSht4x::softReset() {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt8Command(0x94, buffer_ptr, 2);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(10);
    return localError;
}

void SensirionI2cSht4x::begin(TwoWire& i2cBus, uint8_t i2cAddress) {
    _i2cBus = &i2cBus;
    _i2cAddress = i2cAddress;
}
