2022-03-14 13:12:12 +01:00

453 lines
14 KiB
C

/*
* THIS FILE IS AUTOMATICALLY GENERATED AND MUST NOT BE EDITED MANUALLY!
*
* I2C-Generator: 0.2.0
* Yaml Version: 0.1.0
* Template Version: 0.2.1
*/
/*
* Copyright (c) 2021, 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 "scd4x_i2c.h"
#include "sensirion_common.h"
#include "sensirion_i2c.h"
#include "sensirion_i2c_hal.h"
#define SCD4X_I2C_ADDRESS 98
int16_t scd4x_start_periodic_measurement() {
int16_t error;
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x21B1);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
return NO_ERROR;
}
int16_t scd4x_read_measurement_ticks(uint16_t* co2, uint16_t* temperature,
uint16_t* humidity) {
int16_t error;
uint8_t buffer[9];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0xEC05);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 6);
if (error) {
return error;
}
*co2 = sensirion_common_bytes_to_uint16_t(&buffer[0]);
*temperature = sensirion_common_bytes_to_uint16_t(&buffer[2]);
*humidity = sensirion_common_bytes_to_uint16_t(&buffer[4]);
return NO_ERROR;
}
int16_t scd4x_read_measurement(uint16_t* co2, int32_t* temperature_m_deg_c,
int32_t* humidity_m_percent_rh) {
int16_t error;
uint16_t temperature;
uint16_t humidity;
error = scd4x_read_measurement_ticks(co2, &temperature, &humidity);
if (error) {
return error;
}
*temperature_m_deg_c = ((21875 * (int32_t)temperature) >> 13) - 45000;
*humidity_m_percent_rh = ((12500 * (int32_t)humidity) >> 13);
return NO_ERROR;
}
int16_t scd4x_stop_periodic_measurement() {
int16_t error;
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x3F86);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(500000);
return NO_ERROR;
}
int16_t scd4x_get_temperature_offset_ticks(uint16_t* t_offset) {
int16_t error;
uint8_t buffer[3];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x2318);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2);
if (error) {
return error;
}
*t_offset = sensirion_common_bytes_to_uint16_t(&buffer[0]);
return NO_ERROR;
}
int16_t scd4x_get_temperature_offset(int32_t* t_offset_m_deg_c) {
int16_t error;
uint16_t t_offset;
error = scd4x_get_temperature_offset_ticks(&t_offset);
if (error) {
return error;
}
*t_offset_m_deg_c = ((21875 * (int32_t)t_offset) >> 13);
return NO_ERROR;
}
int16_t scd4x_set_temperature_offset_ticks(uint16_t t_offset) {
int16_t error;
uint8_t buffer[5];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x241D);
offset = sensirion_i2c_add_uint16_t_to_buffer(&buffer[0], offset, t_offset);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
return NO_ERROR;
}
int16_t scd4x_set_temperature_offset(int32_t t_offset_m_deg_c) {
uint16_t t_offset = (uint16_t)((t_offset_m_deg_c * 12271) >> 15);
return scd4x_set_temperature_offset_ticks(t_offset);
}
int16_t scd4x_get_sensor_altitude(uint16_t* sensor_altitude) {
int16_t error;
uint8_t buffer[3];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x2322);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2);
if (error) {
return error;
}
*sensor_altitude = sensirion_common_bytes_to_uint16_t(&buffer[0]);
return NO_ERROR;
}
int16_t scd4x_set_sensor_altitude(uint16_t sensor_altitude) {
int16_t error;
uint8_t buffer[5];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x2427);
offset = sensirion_i2c_add_uint16_t_to_buffer(&buffer[0], offset,
sensor_altitude);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
return NO_ERROR;
}
int16_t scd4x_set_ambient_pressure(uint16_t ambient_pressure) {
int16_t error;
uint8_t buffer[5];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0xE000);
offset = sensirion_i2c_add_uint16_t_to_buffer(&buffer[0], offset,
ambient_pressure);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
return NO_ERROR;
}
int16_t scd4x_perform_forced_recalibration(uint16_t target_co2_concentration,
uint16_t* frc_correction) {
int16_t error;
uint8_t buffer[5];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x362F);
offset = sensirion_i2c_add_uint16_t_to_buffer(&buffer[0], offset,
target_co2_concentration);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(400000);
error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2);
if (error) {
return error;
}
*frc_correction = sensirion_common_bytes_to_uint16_t(&buffer[0]);
return NO_ERROR;
}
int16_t scd4x_get_automatic_self_calibration(uint16_t* asc_enabled) {
int16_t error;
uint8_t buffer[3];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x2313);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2);
if (error) {
return error;
}
*asc_enabled = sensirion_common_bytes_to_uint16_t(&buffer[0]);
return NO_ERROR;
}
int16_t scd4x_set_automatic_self_calibration(uint16_t asc_enabled) {
int16_t error;
uint8_t buffer[5];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x2416);
offset =
sensirion_i2c_add_uint16_t_to_buffer(&buffer[0], offset, asc_enabled);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
return NO_ERROR;
}
int16_t scd4x_start_low_power_periodic_measurement() {
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x21AC);
return sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
}
int16_t scd4x_get_data_ready_status(uint16_t* data_ready) {
int16_t error;
uint8_t buffer[3];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0xE4B8);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2);
if (error) {
return error;
}
*data_ready = sensirion_common_bytes_to_uint16_t(&buffer[0]);
return NO_ERROR;
}
int16_t scd4x_persist_settings() {
int16_t error;
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x3615);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(800000);
return NO_ERROR;
}
int16_t scd4x_get_serial_number(uint16_t* serial_0, uint16_t* serial_1,
uint16_t* serial_2) {
int16_t error;
uint8_t buffer[9];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x3682);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 6);
if (error) {
return error;
}
*serial_0 = sensirion_common_bytes_to_uint16_t(&buffer[0]);
*serial_1 = sensirion_common_bytes_to_uint16_t(&buffer[2]);
*serial_2 = sensirion_common_bytes_to_uint16_t(&buffer[4]);
return NO_ERROR;
}
int16_t scd4x_perform_self_test(uint16_t* sensor_status) {
int16_t error;
uint8_t buffer[3];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x3639);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(10000000);
error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2);
if (error) {
return error;
}
*sensor_status = sensirion_common_bytes_to_uint16_t(&buffer[0]);
return NO_ERROR;
}
int16_t scd4x_perform_factory_reset() {
int16_t error;
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x3632);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(800000);
return NO_ERROR;
}
int16_t scd4x_reinit() {
int16_t error;
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x3646);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(20000);
return NO_ERROR;
}
int16_t scd4x_measure_single_shot() {
int16_t error;
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x219D);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(5000000);
return NO_ERROR;
}
int16_t scd4x_measure_single_shot_rht_only() {
int16_t error;
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x2196);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(50000);
return NO_ERROR;
}
int16_t scd4x_power_down() {
int16_t error;
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x36E0);
error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
if (error) {
return error;
}
sensirion_i2c_hal_sleep_usec(1000);
return NO_ERROR;
}
int16_t scd4x_wake_up() {
uint8_t buffer[2];
uint16_t offset = 0;
offset = sensirion_i2c_add_command_to_buffer(&buffer[0], offset, 0x36F6);
// Sensor does not acknowledge the wake-up call, error is ignored
(void)sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset);
sensirion_i2c_hal_sleep_usec(20000);
return NO_ERROR;
}