/*
 * THIS FILE IS AUTOMATICALLY GENERATED
 *
 * Generator:     sensirion-driver-generator 0.36.0
 * Product:       sgp43
 * Model-Version: 2.1.0
 */
/*
 * Copyright (c) 2023, 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 "SensirionI2cSgp43.h"
#include <Arduino.h>

static uint8_t communication_buffer[32] = {0};

SensirionI2cSgp43::SensirionI2cSgp43() {
}

uint16_t SensirionI2cSgp43::signalSraw(uint16_t measurement) {
    uint16_t sraw = 0;
    sraw = measurement;
    return sraw;
}

int16_t SensirionI2cSgp43::measureSetMultipixelTemperature(uint16_t tempPixel,
                                                           uint16_t& aSraw,
                                                           uint16_t& aSraw1,
                                                           uint16_t& aSraw2,
                                                           uint16_t& aSraw3) {
    uint16_t spix1 = 0;
    uint16_t spix2 = 0;
    uint16_t spix3 = 0;
    uint16_t spix4 = 0;
    int16_t localError = 0;
    localError = measureSetMultipixelTicks(32768, 26214, tempPixel, tempPixel,
                                           tempPixel, tempPixel, 0, 0, 0, 0,
                                           spix1, spix2, spix3, spix4);
    if (localError != NO_ERROR) {
        return localError;
    }
    aSraw = signalSraw(spix1);
    aSraw1 = signalSraw(spix2);
    aSraw2 = signalSraw(spix3);
    aSraw3 = signalSraw(spix4);
    return localError;
}

int16_t SensirionI2cSgp43::executeConditioning(uint16_t compensationRhTicks,
                                               uint16_t compensationTTicks,
                                               uint16_t& srawVoc) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt16Command(0x2612, buffer_ptr, 8);
    localError |= txFrame.addUInt16(compensationRhTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(compensationTTicks);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(50);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 8);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 3,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(srawVoc);
    return localError;
}

int16_t SensirionI2cSgp43::measureSetMultipixelTicks(
    uint16_t relativeHumidity, uint16_t temperature, uint16_t temperaturePix1,
    uint16_t temperaturePix2, uint16_t temperaturePix3,
    uint16_t temperaturePix4, uint16_t conditionPix1, uint16_t conditionPix2,
    uint16_t conditionPix3, uint16_t conditionPix4, uint16_t& rawSignalPix1,
    uint16_t& rawSignalPix2, uint16_t& rawSignalPix3, uint16_t& rawSignalPix4) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt16Command(0x263e, buffer_ptr, 32);
    localError |= txFrame.addUInt16(relativeHumidity);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(temperature);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(temperaturePix1);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(temperaturePix2);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(temperaturePix3);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(temperaturePix4);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(conditionPix1);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(conditionPix2);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(conditionPix3);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(conditionPix4);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(90);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 32);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 12,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(rawSignalPix1);
    localError |= rxFrame.getUInt16(rawSignalPix2);
    localError |= rxFrame.getUInt16(rawSignalPix3);
    localError |= rxFrame.getUInt16(rawSignalPix4);
    return localError;
}

int16_t SensirionI2cSgp43::measureRawSignals(uint16_t relativeHumidity,
                                             uint16_t temperature,
                                             uint16_t& srawVoc,
                                             uint16_t& srawNox) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt16Command(0x2619, buffer_ptr, 8);
    localError |= txFrame.addUInt16(relativeHumidity);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= txFrame.addUInt16(temperature);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(50);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 8);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(srawVoc);
    localError |= rxFrame.getUInt16(srawNox);
    return localError;
}

int16_t SensirionI2cSgp43::executeSelfTest(uint16_t& testResult) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt16Command(0x280e, buffer_ptr, 3);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(320);
    SensirionI2CRxFrame rxFrame(buffer_ptr, 3);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 3,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getUInt16(testResult);
    return localError;
}

int16_t SensirionI2cSgp43::turnHeaterOff() {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt16Command(0x3615, buffer_ptr, 2);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    delay(1);
    return localError;
}

int16_t SensirionI2cSgp43::getSerialNumber(uint8_t serialNumber[],
                                           uint16_t serialNumberSize) {
    int16_t localError = NO_ERROR;
    uint8_t* buffer_ptr = communication_buffer;
    SensirionI2CTxFrame txFrame =
        SensirionI2CTxFrame::createWithUInt16Command(0x3682, buffer_ptr, 9);
    localError =
        SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    SensirionI2CRxFrame rxFrame(buffer_ptr, 9);
    localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 9,
                                                         rxFrame, *_i2cBus);
    if (localError != NO_ERROR) {
        return localError;
    }
    localError |= rxFrame.getBytes((uint8_t*)serialNumber, serialNumberSize);
    return localError;
}

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