From 490c4417b3ca3c7b93eaf2462759c5bb379c675e Mon Sep 17 00:00:00 2001 From: Driver Generator 2 Date: Wed, 29 Jan 2025 12:04:32 +0000 Subject: [PATCH] Generate SCD4x driver from SCD4x model version 2.0 --- .github/workflows/embedded_quality_check.yml | 13 +- .gitignore | 5 +- CHANGELOG.md | 32 +- LICENSE | 2 +- README.md | 186 ++-- example-usage/Makefile | 23 + example-usage/scd4x_i2c_example_usage.c | 142 +++ images/SCD41.png | Bin 0 -> 174793 bytes images/SCD41_pinout.png | Bin 0 -> 10295 bytes metadata.yml | 7 + .../Atmel_SAMD2_series/sensirion_i2c_hal.c | 4 +- .../GPIO_bit_banging/sensirion_i2c_hal.c | 4 +- .../Nordic_nRF5_series/sensirion_i2c_hal.c | 9 +- .../STM32F1_series/sensirion_i2c_hal.c | 4 +- .../esp32/sensirion_i2c_esp32_config.h | 60 ++ .../esp32/sensirion_i2c_hal.c | 194 ++++ .../linux_user_space/sensirion_i2c_hal.c | 4 +- .../mbed/sensirion_i2c_hal.cpp | 4 +- .../zephyr_user_space/sensirion_i2c_hal.c | 4 +- scd4x_i2c.c | 838 +++++++++++------- scd4x_i2c.h | 757 ++++++++++++---- sensirion_common.c | 43 +- sensirion_common.h | 16 + sensirion_i2c.c | 15 +- sensirion_i2c.h | 36 +- sensirion_i2c_hal.c | 4 +- sensirion_i2c_hal.h | 4 +- tests/Makefile | 50 +- tests/scd4x_i2c_test.cpp | 448 +++++----- tests/sensirion_test_setup.cpp | 18 +- 30 files changed, 2039 insertions(+), 887 deletions(-) create mode 100644 example-usage/Makefile create mode 100644 example-usage/scd4x_i2c_example_usage.c create mode 100644 images/SCD41.png create mode 100644 images/SCD41_pinout.png create mode 100644 metadata.yml create mode 100644 sample-implementations/esp32/sensirion_i2c_esp32_config.h create mode 100644 sample-implementations/esp32/sensirion_i2c_hal.c diff --git a/.github/workflows/embedded_quality_check.yml b/.github/workflows/embedded_quality_check.yml index b229e50..34a264b 100644 --- a/.github/workflows/embedded_quality_check.yml +++ b/.github/workflows/embedded_quality_check.yml @@ -1,16 +1,13 @@ name: Quality check on: - pull_request: - branches: - - master push: + pull_request: branches: - - master - + - main jobs: driver-quality: uses: sensirion/.github/.github/workflows/driver.c.check.yml@main - with: - examples: '["."]' - run-environment: "ubuntu-20.04" + + code-generation-check: + uses: sensirion/.github/.github/workflows/driver.generated.metadata_check.yml@main diff --git a/.gitignore b/.gitignore index 051cadf..781a364 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -/scd4x_i2c_example_usage -.idea +/example-usage/scd4x_i2c_example_usage +/tests/scd4x_test_hw_i2c +/tests/scd4x_test_sw_i2c diff --git a/CHANGELOG.md b/CHANGELOG.md index 860b34e..cffad92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,32 +1,22 @@ -# Changelog - -All notable changes to this project will be documented in this file. +# CHANGELOG The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] -## [0.2.1] - 2021-04-30 - -### Changed - -* Increase timing for single shot from 1350ms to 5000ms -* Increase timing for self test from 5500ms to 10000ms - - -## [0.2.0] - 2021-03-01 +## [1.0.0] - 2025-1-30 ### Added -- Convenience interfaces taking care of unit conversion to and from ticks. - -### Fixed -- wake-up interface handles missing ACK from sensor on wake up. +- All commands according to data sheet +## [0.1.0] - 2021-2-1 -## [0.1.0] - 2021-01-28 +### Added -Initial release +- Initial version +- Check latest 0.x.x version for changelog prior to version 1.0.0 -[0.2.1]: https://github.com/Sensirion/embedded-i2c-scd4x/compare/0.2.0...0.2.1 -[0.2.0]: https://github.com/Sensirion/embedded-i2c-scd4x/compare/0.1.0...0.2.0 -[0.1.0]: https://github.com/Sensirion/embedded-i2c-scd4x/releases/tag/0.1.0 +[Unreleased]: https://github.com/Sensirion/embedded-i2c-scd4x/compare/1.0.0...HEAD +[1.0.0]: https://github.com/Sensirion/embedded-i2c-scd4x/compare/0.1.0...1.0.0 +[0.1.0]: https://github.com/Sensirion/embedded-i2c-scd4x/releases/tag/0.1.0 \ No newline at end of file diff --git a/LICENSE b/LICENSE index ff20c41..2062766 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2021, Sensirion AG +Copyright (c) 2025, Sensirion AG All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index 6586695..8a94531 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,61 @@ -# Sensirion Embedded I2C SCD4x Driver +# Sensirion I2C SCD4X embedded Library -This is a generic embedded driver for the [Sensirion SCD4x Carbon Dioxide Sensor](https://www.sensirion.com/scd4x/). -It enables developers to communicate with the SCD4x sensor on different hardware platforms by only adapting the I2C communication related source files. +This document explains how to set up a sensor of the SCD4X family to run on an embedded device using the I²C interface. -[
](https://sensirion.com/my-scd-ek) + -# Getting started +Click [here](https://sensirion.com/products/catalog/SEK-SCD41) to learn more about the Sensirion SCD4X sensor family. -## Implement the I2C Interface -So we need to adjust two files according to your platform. +Not all sensors of this driver family support all measurements. +In case a measurement is not supported by all sensors, the products that +support it are listed in the API description. + + + +## Supported sensor types + +| Sensor name | I²C Addresses | +| ------------- | -------------- | +|[SCD40](https://sensirion.com/products/catalog/SCD40)| **0x62**| +|[SCD41](https://sensirion.com/products/catalog/SCD41)| **0x62**| + +The following instructions and examples use a *SCD41*. + + + +## Setup Guide + +### Connect the Sensor + +Your sensor has 4 pins that need to be connected to your board: SCL, GND, VDD, SDA. +Use the following description to connect your SCD4X: + + + +| *Pin* | *Cable Color* | *Name* | *Description* | *Comments* | +|-------|---------------|:------:|----------------|------------| +| 1 | yellow | SCL | I2C: Serial clock input | +| 2 | black | GND | Ground | +| 3 | red | VDD | Supply Voltage | 2.4V to 5.5V +| 4 | green | SDA | I2C: Serial data input / output | + + + +The recommended voltage is 3.3V. + +### Configure the code + +In order to use the provided code we need to adjust two files according to your platform. ### Edit `sensirion_i2c_hal.c` -This file contains the implementation of the sensor communication -(how to send requests to the sensor). Therefore, how this is done depends on your -hardware platform. Therefore we can only provide function stubs in which you -can implement the logic yourself. -There are sample implementations available for some platforms: [`sample-implementations`](sample-implementations). -If you are using a Linux based platform like Raspberry Pi -you can just replace the unimplemented HAL template with the provided +This file contains the implementation of the sensor communication, which +depends on your hardware platform. We provide function stubs for your +hardware's own implementation. +Sample implementations are available for some platforms: +[`sample-implementations`](sample-implementations). For Linux based platforms +like Raspberry Pi you can just replace the unimplemented HAL template with the implementation in `sample-implementations/linux_user_space/`: ``` @@ -28,17 +64,16 @@ cp sample-implementations/linux_user_space/sensirion_i2c_hal.c ./ ### Edit `sensirion_config.h` -If you are on a Linux based platform you can skip this part since -everything is already correctly setup for you. +Skip this part for Linux based platforms since everything is already setup for +this case. -Otherwise you need to check if the libraries `` and -`` are provided by your toolchain, compiler or system. -If you have no idea on how to do that you can skip this -step for now and come back when you get errors related to these names when -compiling the driver. -The features we use out of those libraries are standard integer sizes -from `` and `NULL` from ``. If they are not available -you need to specify the following integer types yourself: +Otherwise you need to check if the libraries `` and `` are +provided by your toolchain, compiler or system. If you have no idea on how to +do that you can skip this step for now and come back when you get errors +related to these names when compiling the driver. +The features we use from those libraries are type definitions for integer sizes +from `` and `NULL` from ``. If they are not available you +need to specify the following integer types yourself: * `int64_t` = signed 64bit integer * `uint64_t` = unsigned 64bit integer @@ -49,26 +84,47 @@ you need to specify the following integer types yourself: * `int8_t` = signed 8bit integer * `uint8_t` = unsigned 8bit integer -In addition to that you will need to specify `NULL`. -For both we have a detailed template where you just need to fill in -your system specific values. +In addition to that you will need to specify `NULL`. For both we have a +detailed template where you just need to fill in your system specific values. + +## Choose the i2c address to use with your product + +The provided example is working with a SCD41, I²C address 0x62. +In order to use the code with another product or I²C address you need to change it in the call scd4x_init(ADDRESS) in +`scd4x_i2c_example_usage.c`. The list of supported I²C-addresses is found in the header +`scd4x_i2c.h`. + Now we are ready to compile and run the example usage for your sensor. ## Compile and Run -Take the `.c` and `.h` files directly in this folder pass them to your -favorite C compiler and run the resulting binary. -This step may vary, depending on your platform. Here we demonstrate the -procedure for Linux based platforms: +Pass the source `.c` and header `.h` files in this folder into your C compiler +and run the resulting binary. This step may vary, depending on your platform. +Here we demonstrate the procedure for Linux based platforms: 1. Open up a terminal. 2. Navigate to the directory where this README is located. -3. Run `make` (this compiles all the code here to one binary). -4. Run `./scd4x_i2c_example_usage` (This will run your newly compiled binary). -5. Now you should see the first measurement values appear in your terminal. - As a next step you can adjust the example usage file or write your own - main function to use the sensor. +3. Navigate to the subdirectory example-usage. +4. Run `make` (this compiles the example code into one executable binary). +5. Run the compiled executable with `./scd4x_i2c_example_usage` +6. Now you should see the first measurement values appear in your terminal. As + a next step you can adjust the example usage file or write your own main + function to use the sensor. + +## Compile and Run Tests + +The testframekwork used is CppUTest. Pass the source `.cpp`, `.c` and header `.h` +files from the tests and top level folder into your CPP compiler and run the +resulting binary. This step may vary, depending on your platform. +Here we demonstrate the procedure for Linux based platforms: + +1. Open up a terminal. +2. Install CppUTest framework `apt install cpputest`. +3. Navigate to the directory `tests`. +4. Run `make` (this compiles the test code into one executable binary). +5. Run the compiled executable with `./scd4x_test_hw_i2c`. +6. Now you should see the test output on your console. # Background @@ -76,29 +132,53 @@ procedure for Linux based platforms: ### sensirion\_i2c.[ch] -In these files you can find the implementation of the I2C protocol used by Sensirion -sensors. The functions in these files are used by the embedded driver to build the -correct frame out of data to be sent to the sensor or receive a frame of data from -the sensor and convert it back to data readable by your machine. The functions in -here calculate and check CRCs, reorder bytes for different byte orders and build the -correct formatted frame for your sensor. +In these files you can find the implementation of the I2C protocol used by +Sensirion sensors. The functions in these files are used by the embedded driver +to build the correct frame out of data to be sent to the sensor or receive a +frame of data from the sensor and convert it back to data readable by your +machine. The functions in here calculate and check CRCs, reorder bytes for +different byte orders and build the correct formatted frame for your sensor. ### sensirion\_i2c\_hal.[ch] -In these files you can find the implementation of the hardware abstraction layer used -by Sensirion's I2C embedded drivers. This part of the code is specific to the underlying -hardware platform. This is an unimplemented template for the user to implement. -In the `sample-implementations/` folder we provide implementations for the most common -platforms. +These files contain the implementation of the hardware abstraction layer used +by Sensirion's I2C embedded drivers. This part of the code is specific to the +underlying hardware platform. This is an unimplemented template for the user to +implement. In the `sample-implementations/` folder we provide implementations +for the most common platforms. ### sensirion\_config.h -In this file we keep all the included libraries for our drivers and global defines. -Next to `sensirion_i2c_hal.c` *it's the only file you should need to edit to get your -driver working.* +In this file we keep all the included libraries for our drivers and global +defines. Next to `sensirion_i2c_hal.c` *it's the only file you should need to +edit to get your driver working.* ### sensirion\_common.[ch] -In these files you can find some helper functions used by Sensirion's embedded drivers. -It mostly contains byte order conversions for different variable types. These functions -are also used by the UART embedded drivers therefore they are kept in their own file. +In these files you can find some helper functions used by Sensirion's embedded +drivers. It mostly contains byte order conversions for different variable +types. These functions are also used by the UART embedded drivers therefore +they are kept in their own file. + +## Contributing + +**Contributions are welcome!** + +This Sensirion library uses +[`clang-format`](https://releases.llvm.org/download.html) to standardize the +formatting of all our `.c` and `.h` files. Make sure your contributions are +formatted accordingly: + +The `-i` flag will apply the format changes to the files listed. + +```bash +clang-format -i *.c *.h +``` + +Note that differences from this formatting will result in a failed build until +they are fixed. + + +# License + +See [LICENSE](LICENSE). \ No newline at end of file diff --git a/example-usage/Makefile b/example-usage/Makefile new file mode 100644 index 0000000..37ae2c2 --- /dev/null +++ b/example-usage/Makefile @@ -0,0 +1,23 @@ +src_dir = .. +common_sources = ${src_dir}/sensirion_config.h ${src_dir}/sensirion_common.h ${src_dir}/sensirion_common.c +i2c_sources = ${src_dir}/sensirion_i2c_hal.h ${src_dir}/sensirion_i2c.h ${src_dir}/sensirion_i2c.c +driver_sources = ${src_dir}/scd4x_i2c.h ${src_dir}/scd4x_i2c.c + +i2c_implementation ?= ${src_dir}/sensirion_i2c_hal.c + +CFLAGS = -Os -Wall -fstrict-aliasing -Wstrict-aliasing=1 -Wsign-conversion -fPIC -I${src_dir} -I. + +ifdef CI + CFLAGS += -Werror +endif + +.PHONY: all clean + +all: scd4x_i2c_example_usage + +scd4x_i2c_example_usage: clean + $(CC) $(CFLAGS) -o $@ ${driver_sources} ${i2c_sources} \ + ${i2c_implementation} ${common_sources} scd4x_i2c_example_usage.c + +clean: + $(RM) scd4x_i2c_example_usage \ No newline at end of file diff --git a/example-usage/scd4x_i2c_example_usage.c b/example-usage/scd4x_i2c_example_usage.c new file mode 100644 index 0000000..a3a657b --- /dev/null +++ b/example-usage/scd4x_i2c_example_usage.c @@ -0,0 +1,142 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED + * + * Generator: sensirion-driver-generator 1.1.2 + * Product: scd4x + * Model-Version: 2.0 + */ +/* + * Copyright (c) 2025, 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_hal.h" +#include // PRIx64 +#include // printf + +#define sensirion_hal_sleep_us sensirion_i2c_hal_sleep_usec + +void print_ushort_array(uint16_t* array, uint16_t len) { + uint16_t i = 0; + printf("0x"); + for (; i < len; i++) { + printf("%04x", array[i]); + } +} + +int main(void) { + int16_t error = NO_ERROR; + sensirion_i2c_hal_init(); + scd4x_init(SCD41_I2C_ADDR_62); + + uint16_t serial_number[3] = {0}; + sensirion_hal_sleep_us(30000); + // Ensure sensor is in clean state + error = scd4x_wake_up(); + if (error != NO_ERROR) { + printf("error executing wake_up(): %i\n", error); + return error; + } + error = scd4x_stop_periodic_measurement(); + if (error != NO_ERROR) { + printf("error executing stop_periodic_measurement(): %i\n", error); + return error; + } + error = scd4x_reinit(); + if (error != NO_ERROR) { + printf("error executing reinit(): %i\n", error); + return error; + } + // Read out information about the sensor + error = scd4x_get_serial_number(serial_number, 3); + if (error != NO_ERROR) { + printf("error executing get_serial_number(): %i\n", error); + return error; + } + printf("serial number: "); + print_ushort_array(serial_number, 3); + printf("\n"); + // + // If temperature offset and/or sensor altitude compensation + // is required, you should call the respective functions here. + // Check out the header file for the function definitions. + // Start periodic measurements (5sec interval) + error = scd4x_start_periodic_measurement(); + if (error != NO_ERROR) { + printf("error executing start_periodic_measurement(): %i\n", error); + return error; + } + // + // If low-power mode is required, switch to the low power + // measurement function instead of the standard measurement + // function above. Check out the header file for the definition. + // + bool data_ready = false; + uint16_t co2_concentration = 0; + uint16_t temperature = 0; + uint16_t relative_humidity = 0; + uint16_t repetition = 0; + for (repetition = 0; repetition < 50; repetition++) { + // + // Slow down the sampling to 0.2Hz. + // + sensirion_hal_sleep_us(5000000); + // + // If ambient pressure compensation during measurement + // is required, you should call the respective functions here. + // Check out the header file for the function definition. + error = scd4x_get_data_ready_status(&data_ready); + if (error != NO_ERROR) { + printf("error executing get_data_ready_status(): %i\n", error); + continue; + } + while (!data_ready) { + sensirion_hal_sleep_us(100000); + error = scd4x_get_data_ready_status(&data_ready); + if (error != NO_ERROR) { + printf("error executing get_data_ready_status(): %i\n", error); + continue; + } + } + error = scd4x_read_measurement_raw(&co2_concentration, &temperature, + &relative_humidity); + if (error != NO_ERROR) { + printf("error executing read_measurement_raw(): %i\n", error); + continue; + } + // + // Print results in physical units. + printf("CO2 concentration [ppm]: %u\n", co2_concentration); + printf("Temperature ticks: %u\n", temperature); + printf("Humidity ticks: %u\n", relative_humidity); + } + + return NO_ERROR; +} diff --git a/images/SCD41.png b/images/SCD41.png new file mode 100644 index 0000000000000000000000000000000000000000..d6f6c9c9877dd8663c8a1a649693ce8af9bd8faf GIT binary patch literal 174793 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%0Arvm*llf^-TTVXW1FDXXk%h>3W`?ni=VxPAHV+J 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 literal 0 HcmV?d00001 diff --git a/images/SCD41_pinout.png b/images/SCD41_pinout.png new file mode 100644 index 0000000000000000000000000000000000000000..bc336797ff6bbdcd028c5a0b3c412966642fc585 GIT binary patch literal 10295 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 M1$FsqS&Oj$0fQFja{vGU literal 0 HcmV?d00001 diff --git a/metadata.yml b/metadata.yml new file mode 100644 index 0000000..b53c9f0 --- /dev/null +++ b/metadata.yml @@ -0,0 +1,7 @@ +# driver generation metadata +generator_version: 1.1.2 +model_version: '2.0' +dg_status: released +is_manually_modified: false +first_generated: '2021-01-15 10:54' +last_generated: '2025-01-29 12:04' diff --git a/sample-implementations/Atmel_SAMD2_series/sensirion_i2c_hal.c b/sample-implementations/Atmel_SAMD2_series/sensirion_i2c_hal.c index 18e8863..30ea666 100644 --- a/sample-implementations/Atmel_SAMD2_series/sensirion_i2c_hal.c +++ b/sample-implementations/Atmel_SAMD2_series/sensirion_i2c_hal.c @@ -57,7 +57,7 @@ void sensirion_i2c_hal_init(void) { void sensirion_i2c_hal_free(void) { } -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) { struct i2c_master_packet packet = { .address = address, .data_length = count, @@ -69,7 +69,7 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { } int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count) { + uint8_t count) { struct i2c_master_packet packet = { .address = address, .data_length = count, diff --git a/sample-implementations/GPIO_bit_banging/sensirion_i2c_hal.c b/sample-implementations/GPIO_bit_banging/sensirion_i2c_hal.c index a946e17..3d2f6d0 100644 --- a/sample-implementations/GPIO_bit_banging/sensirion_i2c_hal.c +++ b/sample-implementations/GPIO_bit_banging/sensirion_i2c_hal.c @@ -88,7 +88,7 @@ void sensirion_i2c_hal_free(void) { * @param count number of bytes to read from I2C and store in the buffer * @returns 0 on success, error code otherwise */ -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) { int8_t ret; uint8_t send_ack; uint16_t i; @@ -123,7 +123,7 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { * @returns 0 on success, error code otherwise */ int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count) { + uint8_t count) { int8_t ret; uint16_t i; diff --git a/sample-implementations/Nordic_nRF5_series/sensirion_i2c_hal.c b/sample-implementations/Nordic_nRF5_series/sensirion_i2c_hal.c index c251f0f..e26ba9c 100644 --- a/sample-implementations/Nordic_nRF5_series/sensirion_i2c_hal.c +++ b/sample-implementations/Nordic_nRF5_series/sensirion_i2c_hal.c @@ -92,8 +92,8 @@ void sensirion_i2c_hal_free(void) { * error codes: 3 -> error detected by hardware (internal error) * 17 -> driver not ready for new transfer (busy) */ -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { - int8_t err = nrf_drv_twi_rx(&i2c_instance, address, data, (uint8_t)count); +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) { + int8_t err = nrf_drv_twi_rx(&i2c_instance, address, data, count); return err; } @@ -112,9 +112,8 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { * 17 -> driver not ready for new transfer (busy) */ int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count) { - int8_t err = - nrf_drv_twi_tx(&i2c_instance, address, data, (uint8_t)count, false); + uint8_t count) { + int8_t err = nrf_drv_twi_tx(&i2c_instance, address, data, count, false); return err; } diff --git a/sample-implementations/STM32F1_series/sensirion_i2c_hal.c b/sample-implementations/STM32F1_series/sensirion_i2c_hal.c index 424b2e1..83db176 100644 --- a/sample-implementations/STM32F1_series/sensirion_i2c_hal.c +++ b/sample-implementations/STM32F1_series/sensirion_i2c_hal.c @@ -79,7 +79,7 @@ void sensirion_i2c_hal_free(void) { * @param count number of bytes to read from I2C and store in the buffer * @returns 0 on success, error code otherwise */ -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) { return (int8_t)HAL_I2C_Master_Receive(&hi2c1, (uint16_t)(address << 1), data, count, 100); } @@ -96,7 +96,7 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { * @returns 0 on success, error code otherwise */ int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count) { + uint8_t count) { return (int8_t)HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)(address << 1), (uint8_t*)data, count, 100); } diff --git a/sample-implementations/esp32/sensirion_i2c_esp32_config.h b/sample-implementations/esp32/sensirion_i2c_esp32_config.h new file mode 100644 index 0000000..a7e4d15 --- /dev/null +++ b/sample-implementations/esp32/sensirion_i2c_esp32_config.h @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#ifndef SENSIRION_I2C_ESP32_CONFIG_H +#define SENSIRION_I2C_ESP32_CONFIG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int esp_err_t; + +struct esp32_i2c_config { + uint32_t freq; + uint8_t addr; + i2c_port_t port; + gpio_num_t sda; + gpio_num_t scl; + bool sda_pullup; + bool scl_pullup; +}; + +extern esp_err_t sensirion_i2c_config_esp32(struct esp32_i2c_config* cfg); +extern esp_err_t sensirion_i2c_esp32_ok(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SENSIRION_I2C_ESP32_CONFIG_H */ diff --git a/sample-implementations/esp32/sensirion_i2c_hal.c b/sample-implementations/esp32/sensirion_i2c_hal.c new file mode 100644 index 0000000..b6c89dc --- /dev/null +++ b/sample-implementations/esp32/sensirion_i2c_hal.c @@ -0,0 +1,194 @@ +/* + * 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 "sensirion_i2c_hal.h" +#include "sensirion_common.h" +#include "sensirion_config.h" + +#include +#include +#include +#include + +#include "sensirion_i2c_esp32_config.h" + +static const char* TAG = "sensirion_i2c_hal"; + +#define SLEEP_MS(x) \ + vTaskDelay(((x) + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS) +#define CHECK(x) \ + do { \ + esp_err_t __; \ + if ((__ = x) != ESP_OK) \ + return __; \ + } while (0) +#define CHECK_ARG(VAL) \ + do { \ + if (!(VAL)) \ + return ESP_ERR_INVALID_ARG; \ + } while (0) +#define UNUSED_PARAM(x) (void)x + +static i2c_dev_t dev = {0}; +static struct esp32_i2c_config i2c_cfg = {0}; +static esp_err_t i2c_ok = ESP_OK; + +/* + * INSTRUCTIONS + * ============ + * + * Implement all functions where they are marked as IMPLEMENT. + * Follow the function specification in the comments. + */ + +/** + * Select the current i2c bus by index. + * All following i2c operations will be directed at that bus. + * + * THE IMPLEMENTATION IS OPTIONAL ON SINGLE-BUS SETUPS (all sensors on the same + * bus) + * + * @param bus_idx Bus index to select + * @returns 0 on success, an error code otherwise + */ +int16_t sensirion_i2c_hal_select_bus(uint8_t bus_idx) { + /* TODO:IMPLEMENT or leave empty if all sensors are located on one single + * bus + */ + return NOT_IMPLEMENTED_ERROR; +} + +esp_err_t sensirion_i2c_config_esp32(struct esp32_i2c_config* cfg) { + if (cfg != NULL) { + memcpy(&i2c_cfg, cfg, sizeof(*cfg)); + return ESP_OK; + } else { + return ESP_FAIL; + } +} + +esp_err_t sensirion_i2c_esp32_ok(void) { + return i2c_ok; +} + +/** + * Initialize all hard- and software components that are needed for the I2C + * communication. + */ +void sensirion_i2c_hal_init(void) { + memset(&dev, 0, sizeof(i2c_dev_t)); + // dev.addr = addr; + dev.port = i2c_cfg.port; + dev.cfg.mode = I2C_MODE_MASTER; + dev.cfg.sda_io_num = i2c_cfg.sda; + dev.cfg.scl_io_num = i2c_cfg.scl; + dev.cfg.sda_pullup_en = i2c_cfg.sda_pullup; + dev.cfg.scl_pullup_en = i2c_cfg.scl_pullup; +#if HELPER_TARGET_IS_ESP32 + dev.cfg.master.clk_speed = i2c_cfg.freq; +#endif + + esp_err_t err = i2c_dev_create_mutex(&dev); + if (err == ESP_OK) { + ESP_LOGI( + TAG, + "Sensirion I2C initialized. Address: 0x%x Port: %d SDA: %d SCL: %d", + i2c_cfg.addr, i2c_cfg.port, i2c_cfg.sda, i2c_cfg.scl); + } else { + ESP_LOGE(TAG, + "Error initializing Sensirion I2C! Address: 0x%x Port: %d " + "SDA: %d SCL: %d", + i2c_cfg.addr, i2c_cfg.port, i2c_cfg.sda, i2c_cfg.scl); + } + + i2c_ok = err; +} + +/** + * Release all resources initialized by sensirion_i2c_hal_init(). + */ +void sensirion_i2c_hal_free(void) { +} + +/** + * Execute one read transaction on the I2C bus, reading a given number of bytes. + * If the device does not acknowledge the read command, an error shall be + * returned. + * + * @param address 7-bit I2C address to read from + * @param data pointer to the buffer where the data is to be stored + * @param count number of bytes to read from I2C and store in the buffer + * @returns 0 on success, error code otherwise + */ +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { + ESP_LOGI(TAG, "sensirion_i2c_hal_read: len: %d", count); + dev.addr = address; + I2C_DEV_TAKE_MUTEX(&dev); + I2C_DEV_CHECK(&dev, i2c_dev_read(&dev, NULL, 0, data, count)); + I2C_DEV_GIVE_MUTEX(&dev); + ESP_LOGI(TAG, "READ OK"); + return (int8_t)ESP_OK; +} + +/** + * Execute one write transaction on the I2C bus, sending a given number of + * bytes. The bytes in the supplied buffer must be sent to the given address. If + * the slave device does not acknowledge any of the bytes, an error shall be + * returned. + * + * @param address 7-bit I2C address to write to + * @param data pointer to the buffer containing the data to write + * @param count number of bytes to read from the buffer and send over I2C + * @returns 0 on success, error code otherwise + */ +int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, + uint16_t count) { + ESP_LOGI(TAG, "sensirion_i2c_hal_write: len: %d", count); + dev.addr = address; + I2C_DEV_TAKE_MUTEX(&dev); + I2C_DEV_CHECK(&dev, i2c_dev_write(&dev, NULL, 0, data, count)); + I2C_DEV_GIVE_MUTEX(&dev); + ESP_LOGI(TAG, "WRITE OK"); + return (int8_t)ESP_OK; +} + +/** + * Sleep for a given number of microseconds. The function should delay the + * execution for at least the given time, but may also sleep longer. + * + * Despite the unit, a <10 millisecond precision is sufficient. + * + * @param useconds the sleep time in microseconds + */ +void sensirion_i2c_hal_sleep_usec(uint32_t useconds) { + ESP_LOGI(TAG, "sensirion_i2c_hal_sleep: %d usec", useconds); + SLEEP_MS(useconds / 1000); +} diff --git a/sample-implementations/linux_user_space/sensirion_i2c_hal.c b/sample-implementations/linux_user_space/sensirion_i2c_hal.c index d55ecc8..74a7f57 100644 --- a/sample-implementations/linux_user_space/sensirion_i2c_hal.c +++ b/sample-implementations/linux_user_space/sensirion_i2c_hal.c @@ -89,7 +89,7 @@ void sensirion_i2c_hal_free(void) { * @param count number of bytes to read from I2C and store in the buffer * @returns 0 on success, error code otherwise */ -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) { if (i2c_address != address) { ioctl(i2c_device, I2C_SLAVE, address); i2c_address = address; @@ -113,7 +113,7 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { * @returns 0 on success, error code otherwise */ int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count) { + uint8_t count) { if (i2c_address != address) { ioctl(i2c_device, I2C_SLAVE, address); i2c_address = address; diff --git a/sample-implementations/mbed/sensirion_i2c_hal.cpp b/sample-implementations/mbed/sensirion_i2c_hal.cpp index 9b3b841..ce846a1 100644 --- a/sample-implementations/mbed/sensirion_i2c_hal.cpp +++ b/sample-implementations/mbed/sensirion_i2c_hal.cpp @@ -63,7 +63,7 @@ void sensirion_i2c_hal_free(void) { * @param count number of bytes to read from I2C and store in the buffer * @returns 0 on success, error code otherwise */ -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) { if (i2c_connection.read(address << 1, (char*)data, count) != 0) return E_MBED_I2C_READ_FAILED; return 0; @@ -81,7 +81,7 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { * @returns 0 on success, error code otherwise */ int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count) { + uint8_t count) { if (i2c_connection.write(address << 1, (char*)data, count) != 0) return E_MBED_I2C_WRITE_FAILED; return 0; diff --git a/sample-implementations/zephyr_user_space/sensirion_i2c_hal.c b/sample-implementations/zephyr_user_space/sensirion_i2c_hal.c index fc96443..a0dd0d4 100644 --- a/sample-implementations/zephyr_user_space/sensirion_i2c_hal.c +++ b/sample-implementations/zephyr_user_space/sensirion_i2c_hal.c @@ -91,7 +91,7 @@ void sensirion_i2c_hal_free(void) { * @param count number of bytes to read from I2C and store in the buffer * @returns 0 on success, error code otherwise */ -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) { return i2c_read(i2c_dev, data, count, address); } @@ -107,7 +107,7 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { * @returns 0 on success, error code otherwise */ int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count) { + uint8_t count) { return i2c_write(i2c_dev, data, count, address); } diff --git a/scd4x_i2c.c b/scd4x_i2c.c index 47b54de..7712af7 100644 --- a/scd4x_i2c.c +++ b/scd4x_i2c.c @@ -1,12 +1,12 @@ /* - * THIS FILE IS AUTOMATICALLY GENERATED AND MUST NOT BE EDITED MANUALLY! + * THIS FILE IS AUTOMATICALLY GENERATED * - * I2C-Generator: 0.2.0 - * Yaml Version: 0.1.0 - * Template Version: 0.2.1 + * Generator: sensirion-driver-generator 1.1.2 + * Product: scd4x + * Model-Version: 2.0 */ /* - * Copyright (c) 2021, Sensirion AG + * Copyright (c) 2025, Sensirion AG * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,414 +41,618 @@ #include "sensirion_i2c.h" #include "sensirion_i2c_hal.h" -#define SCD4X_I2C_ADDRESS 98 +#define sensirion_hal_sleep_us sensirion_i2c_hal_sleep_usec -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); +#define ROUND(x) ((int32_t)((x) + 0.5)) - error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset); - if (error) { - return error; - } +static uint8_t communication_buffer[9] = {0}; - sensirion_i2c_hal_sleep_usec(1000); +static uint8_t _i2c_address; - 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; +void scd4x_init(uint8_t i2c_address) { + _i2c_address = i2c_address; } -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; +uint16_t scd4x_signal_co2_concentration(uint16_t raw_co2_concentration) { + uint16_t co2_concentration = 0; + co2_concentration = raw_co2_concentration; + return co2_concentration; } -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); +uint32_t scd4x_signal_ambient_pressure(uint16_t raw_ambient_pressure) { + uint32_t ambient_pressure = 0; + ambient_pressure = (uint32_t)raw_ambient_pressure * 100; + return ambient_pressure; +} - error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset); - if (error) { - return error; +int16_t scd4x_set_ambient_pressure(uint32_t ambient_pressure) { + int16_t local_error = 0; + uint16_t raw_ambient_pressure = (uint16_t)ROUND(ambient_pressure / 100.0); + local_error = scd4x_set_ambient_pressure_raw(raw_ambient_pressure); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(500000); - return NO_ERROR; + return local_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; +int16_t scd4x_get_ambient_pressure(uint32_t* a_ambient_pressure) { + uint16_t raw_ambient_pressure = 0; + int16_t local_error = 0; + local_error = scd4x_get_ambient_pressure_raw(&raw_ambient_pressure); + if (local_error != NO_ERROR) { + return local_error; } + *a_ambient_pressure = scd4x_signal_ambient_pressure(raw_ambient_pressure); - sensirion_i2c_hal_sleep_usec(1000); + return local_error; +} - error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2); - if (error) { - return error; +int16_t scd4x_get_data_ready_status(bool* arg_0) { + uint16_t data_ready_status = 0; + int16_t local_error = 0; + local_error = scd4x_get_data_ready_status_raw(&data_ready_status); + if (local_error != NO_ERROR) { + return local_error; } - *t_offset = sensirion_common_bytes_to_uint16_t(&buffer[0]); - return NO_ERROR; + *arg_0 = (data_ready_status & 2047) != 0; + ; + return local_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; +int16_t scd4x_get_sensor_variant(scd4x_sensor_variant* a_sensor_variant) { + uint16_t raw_sensor_variant = 0; + int16_t local_error = 0; + local_error = scd4x_get_sensor_variant_raw(&raw_sensor_variant); + if (local_error != NO_ERROR) { + return local_error; } - *t_offset_m_deg_c = ((21875 * (int32_t)t_offset) >> 13); - return NO_ERROR; + uint16_t variant = (uint16_t)(raw_sensor_variant & 4); + if (variant == 0) { + *a_sensor_variant = SCD4X_SENSOR_VARIANT_SCD40; + ; + return local_error; + } else if (variant == 1) { + *a_sensor_variant = SCD4X_SENSOR_VARIANT_SCD41; + ; + return local_error; + } + *a_sensor_variant = SCD4X_SENSOR_VARIANT_UNKNOWN; + ; + return local_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; +int16_t scd4x_start_periodic_measurement() { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x21b1); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(1000); - return NO_ERROR; + return local_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_read_measurement_raw(uint16_t* co2_concentration, + uint16_t* temperature, + uint16_t* relative_humidity) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0xec05); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 6); + if (local_error != NO_ERROR) { + return local_error; + } + *co2_concentration = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + *temperature = sensirion_common_bytes_to_uint16_t(&buffer_ptr[2]); + *relative_humidity = sensirion_common_bytes_to_uint16_t(&buffer_ptr[4]); + return local_error; } -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; +int16_t scd4x_stop_periodic_measurement() { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x3f86); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } + sensirion_i2c_hal_sleep_usec(500 * 1000); + return local_error; +} - sensirion_i2c_hal_sleep_usec(1000); +int16_t scd4x_set_temperature_offset_raw(uint16_t offset_temperature) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x241d); + local_offset = sensirion_i2c_add_uint16_t_to_buffer( + buffer_ptr, local_offset, offset_temperature); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + return local_error; +} - error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2); - if (error) { - return error; +int16_t scd4x_get_temperature_offset_raw(uint16_t* offset_temperature) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x2318); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - *sensor_altitude = sensirion_common_bytes_to_uint16_t(&buffer[0]); - return NO_ERROR; + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; + } + *offset_temperature = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x2427); + local_offset = sensirion_i2c_add_uint16_t_to_buffer( + buffer_ptr, local_offset, sensor_altitude); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(1000); - return NO_ERROR; + sensirion_i2c_hal_sleep_usec(1 * 1000); + return local_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); +int16_t scd4x_get_sensor_altitude(uint16_t* sensor_altitude) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x2322); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; + } + *sensor_altitude = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_error; +} - offset = sensirion_i2c_add_uint16_t_to_buffer(&buffer[0], offset, - ambient_pressure); +int16_t scd4x_set_ambient_pressure_raw(uint16_t ambient_pressure) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0xe000); + local_offset = sensirion_i2c_add_uint16_t_to_buffer( + buffer_ptr, local_offset, ambient_pressure); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + return local_error; +} - error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset); - if (error) { - return error; +int16_t scd4x_get_ambient_pressure_raw(uint16_t* ambient_pressure) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0xe000); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(1000); - return NO_ERROR; + *ambient_pressure = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x362f); + local_offset = sensirion_i2c_add_uint16_t_to_buffer( + buffer_ptr, local_offset, target_co2_concentration); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - - sensirion_i2c_hal_sleep_usec(400000); - - error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2); - if (error) { - return error; + sensirion_i2c_hal_sleep_usec(400 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; } - *frc_correction = sensirion_common_bytes_to_uint16_t(&buffer[0]); - return NO_ERROR; + *frc_correction = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_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; +int16_t scd4x_set_automatic_self_calibration_enabled(uint16_t asc_enabled) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x2416); + local_offset = sensirion_i2c_add_uint16_t_to_buffer( + buffer_ptr, local_offset, asc_enabled); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } + sensirion_i2c_hal_sleep_usec(1 * 1000); + return local_error; +} - sensirion_i2c_hal_sleep_usec(1000); - - error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2); - if (error) { - return error; +int16_t scd4x_get_automatic_self_calibration_enabled(uint16_t* asc_enabled) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x2313); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; } - *asc_enabled = sensirion_common_bytes_to_uint16_t(&buffer[0]); - return NO_ERROR; + *asc_enabled = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_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); +int16_t scd4x_set_automatic_self_calibration_target(uint16_t asc_target) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x243a); + local_offset = sensirion_i2c_add_uint16_t_to_buffer( + buffer_ptr, local_offset, asc_target); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + return local_error; +} - error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset); - if (error) { - return error; +int16_t scd4x_get_automatic_self_calibration_target(uint16_t* asc_target) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x233f); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(1000); - return NO_ERROR; + *asc_target = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_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 local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x21ac); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + return local_error; } -int16_t scd4x_get_data_ready_flag(bool* data_ready_flag) { - int16_t error; - uint8_t buffer[3]; - uint16_t offset = 0; - uint16_t local_data_ready = 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; +int16_t scd4x_get_data_ready_status_raw(uint16_t* data_ready_status) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0xe4b8); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - - sensirion_i2c_hal_sleep_usec(1000); - - error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2); - if (error) { - return error; + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; } - local_data_ready = sensirion_common_bytes_to_uint16_t(&buffer[0]); - *data_ready_flag = (local_data_ready & 0x07FF) != 0; - return NO_ERROR; + *data_ready_status = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x3615); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(800000); - return NO_ERROR; + sensirion_i2c_hal_sleep_usec(800 * 1000); + return local_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; +int16_t scd4x_get_serial_number(uint16_t* serial_number, + uint16_t serial_number_size) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x3682); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - - sensirion_i2c_hal_sleep_usec(1000); - - error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 6); - if (error) { - return error; + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 6); + if (local_error != NO_ERROR) { + return local_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; + sensirion_common_copy_bytes(&buffer_ptr[0], (uint8_t*)serial_number, + (serial_number_size * 2)); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x3639); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - - sensirion_i2c_hal_sleep_usec(10000000); - - error = sensirion_i2c_read_data_inplace(SCD4X_I2C_ADDRESS, &buffer[0], 2); - if (error) { - return error; + sensirion_i2c_hal_sleep_usec(10000 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; } - *sensor_status = sensirion_common_bytes_to_uint16_t(&buffer[0]); - return NO_ERROR; + *sensor_status = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x3632); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(800000); - return NO_ERROR; + sensirion_i2c_hal_sleep_usec(1200 * 1000); + return local_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); + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x3646); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(30 * 1000); + return local_error; +} - error = sensirion_i2c_write_data(SCD4X_I2C_ADDRESS, &buffer[0], offset); - if (error) { - return error; +int16_t scd4x_get_sensor_variant_raw(uint16_t* sensor_variant) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x202f); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(20000); - return NO_ERROR; + *sensor_variant = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x219d); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(5000000); - return NO_ERROR; + sensirion_i2c_hal_sleep_usec(5000 * 1000); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x2196); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(50000); - return NO_ERROR; + sensirion_i2c_hal_sleep_usec(50 * 1000); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x36e0); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; } - sensirion_i2c_hal_sleep_usec(1000); - return NO_ERROR; + sensirion_i2c_hal_sleep_usec(1 * 1000); + return local_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; + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x36f6); + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + sensirion_i2c_hal_sleep_usec(30 * 1000); + return local_error; +} + +int16_t scd4x_set_automatic_self_calibration_initial_period( + uint16_t asc_initial_period) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x2445); + local_offset = sensirion_i2c_add_uint16_t_to_buffer( + buffer_ptr, local_offset, asc_initial_period); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + return local_error; +} + +int16_t scd4x_get_automatic_self_calibration_initial_period( + uint16_t* asc_initial_period) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x2340); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; + } + *asc_initial_period = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_error; +} + +int16_t scd4x_set_automatic_self_calibration_standard_period( + uint16_t asc_standard_period) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x244e); + local_offset = sensirion_i2c_add_uint16_t_to_buffer( + buffer_ptr, local_offset, asc_standard_period); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + return local_error; +} + +int16_t scd4x_get_automatic_self_calibration_standard_period( + uint16_t* asc_standard_period) { + int16_t local_error = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + uint16_t local_offset = 0; + local_offset = + sensirion_i2c_add_command16_to_buffer(buffer_ptr, local_offset, 0x234b); + local_error = + sensirion_i2c_write_data(_i2c_address, buffer_ptr, local_offset); + if (local_error != NO_ERROR) { + return local_error; + } + sensirion_i2c_hal_sleep_usec(1 * 1000); + local_error = sensirion_i2c_read_data_inplace(_i2c_address, buffer_ptr, 2); + if (local_error != NO_ERROR) { + return local_error; + } + *asc_standard_period = sensirion_common_bytes_to_uint16_t(&buffer_ptr[0]); + return local_error; } diff --git a/scd4x_i2c.h b/scd4x_i2c.h index b5ee44d..9375b14 100644 --- a/scd4x_i2c.h +++ b/scd4x_i2c.h @@ -1,12 +1,12 @@ /* - * THIS FILE IS AUTOMATICALLY GENERATED AND MUST NOT BE EDITED MANUALLY! + * THIS FILE IS AUTOMATICALLY GENERATED * - * I2C-Generator: 0.2.0 - * Yaml Version: 0.1.0 - * Template Version: 0.2.1 + * Generator: sensirion-driver-generator 1.1.2 + * Product: scd4x + * Model-Version: 2.0 */ /* - * Copyright (c) 2021, Sensirion AG + * Copyright (c) 2025, Sensirion AG * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,335 +44,714 @@ extern "C" { #endif #include "sensirion_config.h" +#define SCD40_I2C_ADDR_62 0x62 +#define SCD41_I2C_ADDR_62 0x62 + +typedef enum { + SCD4X_START_PERIODIC_MEASUREMENT_CMD_ID = 0x21b1, + SCD4X_READ_MEASUREMENT_RAW_CMD_ID = 0xec05, + SCD4X_STOP_PERIODIC_MEASUREMENT_CMD_ID = 0x3f86, + SCD4X_SET_TEMPERATURE_OFFSET_RAW_CMD_ID = 0x241d, + SCD4X_GET_TEMPERATURE_OFFSET_RAW_CMD_ID = 0x2318, + SCD4X_SET_SENSOR_ALTITUDE_CMD_ID = 0x2427, + SCD4X_GET_SENSOR_ALTITUDE_CMD_ID = 0x2322, + SCD4X_SET_AMBIENT_PRESSURE_RAW_CMD_ID = 0xe000, + SCD4X_GET_AMBIENT_PRESSURE_RAW_CMD_ID = 0xe000, + SCD4X_PERFORM_FORCED_RECALIBRATION_CMD_ID = 0x362f, + SCD4X_SET_AUTOMATIC_SELF_CALIBRATION_ENABLED_CMD_ID = 0x2416, + SCD4X_GET_AUTOMATIC_SELF_CALIBRATION_ENABLED_CMD_ID = 0x2313, + SCD4X_SET_AUTOMATIC_SELF_CALIBRATION_TARGET_CMD_ID = 0x243a, + SCD4X_GET_AUTOMATIC_SELF_CALIBRATION_TARGET_CMD_ID = 0x233f, + SCD4X_START_LOW_POWER_PERIODIC_MEASUREMENT_CMD_ID = 0x21ac, + SCD4X_GET_DATA_READY_STATUS_RAW_CMD_ID = 0xe4b8, + SCD4X_PERSIST_SETTINGS_CMD_ID = 0x3615, + SCD4X_GET_SERIAL_NUMBER_CMD_ID = 0x3682, + SCD4X_PERFORM_SELF_TEST_CMD_ID = 0x3639, + SCD4X_PERFORM_FACTORY_RESET_CMD_ID = 0x3632, + SCD4X_REINIT_CMD_ID = 0x3646, + SCD4X_GET_SENSOR_VARIANT_RAW_CMD_ID = 0x202f, + SCD4X_MEASURE_SINGLE_SHOT_CMD_ID = 0x219d, + SCD4X_MEASURE_SINGLE_SHOT_RHT_ONLY_CMD_ID = 0x2196, + SCD4X_POWER_DOWN_CMD_ID = 0x36e0, + SCD4X_WAKE_UP_CMD_ID = 0x36f6, + SCD4X_SET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD_CMD_ID = 0x2445, + SCD4X_GET_AUTOMATIC_SELF_CALIBRATION_INITIAL_PERIOD_CMD_ID = 0x2340, + SCD4X_SET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD_CMD_ID = 0x244e, + SCD4X_GET_AUTOMATIC_SELF_CALIBRATION_STANDARD_PERIOD_CMD_ID = 0x234b, +} SCD4X_CMD_ID; + +typedef enum { + SCD4X_SENSOR_VARIANT_UNKNOWN = 0, + SCD4X_SENSOR_VARIANT_SCD40 = 1, + SCD4X_SENSOR_VARIANT_SCD41 = 2, +} scd4x_sensor_variant; /** - * scd4x_start_periodic_measurement() - start periodic measurement, signal - * update interval is 5 seconds. + * @brief Initialize i2c address of driver * - * @note This command is only available in idle mode. + * @param[in] i2c_address Used i2c address * - * @return 0 on success, an error code otherwise */ -int16_t scd4x_start_periodic_measurement(void); +void scd4x_init(uint8_t i2c_address); /** - * scd4x_read_measurement_ticks() - read sensor output. The measurement data can - * only be read out once per signal update interval as the buffer is emptied - * upon read-out. If no data is available in the buffer, the sensor returns a - * NACK. To avoid a NACK response the get_data_ready_flag can be issued to - * check data status. The I2C master can abort the read transfer with a NACK - * followed by a STOP condition after any data byte if the user is not - * interested in subsequent data. + * @brief scd4x_signal_co2_concentration * - * @note This command is only available in measurement mode. The firmware - * updates the measurement values depending on the measurement mode. + * @param[in] raw_co2_concentration * - * @param co2 CO₂ concentration in ppm - * - * @param temperature Convert value to °C by: -45 °C + 175 °C * value/2^16 + * @return CO₂ concentration in ppm + */ +uint16_t scd4x_signal_co2_concentration(uint16_t raw_co2_concentration); + +/** + * @brief scd4x_signal_ambient_pressure * - * @param humidity Convert value to %RH by: 100%RH * value/2^16 + * @param[in] raw_ambient_pressure * - * @return 0 on success, an error code otherwise + * @return Pressure in Pa */ -int16_t scd4x_read_measurement_ticks(uint16_t* co2, uint16_t* temperature, - uint16_t* humidity); +uint32_t scd4x_signal_ambient_pressure(uint16_t raw_ambient_pressure); /** - * scd4x_read_measurement() - read sensor output and convert. - * See @ref scd4x_read_measurement_ticks() for more details. + * @brief Set the ambient pressure around the sensor. * - * @note This command is only available in measurement mode. The firmware - * updates the measurement values depending on the measurement mode. + * The set_ambient_pressure command can be sent during periodic measurements to + * enable continuous pressure compensation. Note that setting an ambient + * pressure overrides any pressure compensation based on a previously set sensor + * altitude. Use of this command is highly recommended for applications + * experiencing significant ambient pressure changes to ensure sensor accuracy. + * Valid input values are between 70000 - 120000 Pa. The default value is 101300 + * Pa. * - * @param co2 CO₂ concentration in ppm + * @param[in] ambient_pressure Ambient pressure around the sensor in Pa * - * @param temperature_m_deg_c Temperature in milli degrees celsius (°C * 1000) + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_set_ambient_pressure(uint32_t ambient_pressure); + +/** + * @brief Get the ambient pressure around the sensor. * - * @param humidity_m_percent_rh Relative humidity in milli percent RH - * (%RH * 1000) + * @param[out] a_ambient_pressure Pressure in Pa * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_read_measurement(uint16_t* co2, int32_t* temperature_m_deg_c, - int32_t* humidity_m_percent_rh); +int16_t scd4x_get_ambient_pressure(uint32_t* a_ambient_pressure); /** - * scd4x_stop_periodic_measurement() - Stop periodic measurement and return to - * idle mode for sensor configuration or to safe energy. + * @brief Read if data is ready. + * + * Polls the sensor for whether data from a periodic or single shot measurement + * is ready to be read out. * - * @note This command is only available in measurement mode. + * @param[out] arg_0 * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_stop_periodic_measurement(void); +int16_t scd4x_get_data_ready_status(bool* arg_0); /** - * scd4x_get_temperature_offset_ticks() - The temperature offset represents the - * difference between the measured temperature by the SCD4x and the actual - * ambient temperature. Per default, the temperature offset is set to 4°C. + * @brief Reads out the SCD4x sensor variant. * - * @note Only available in idle mode. + * @param[out] a_sensor_variant * - * @param t_offset Temperature offset. Convert value to °C by: 175 * value / - * 2^16 + * @note This command is only available in idle mode. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_get_temperature_offset_ticks(uint16_t* t_offset); +int16_t scd4x_get_sensor_variant(scd4x_sensor_variant* a_sensor_variant); /** - * scd4x_get_temperature_offset() - The temperature offset represents the - * difference between the measured temperature by the SCD4x and the actual - * ambient temperature. Per default, the temperature offset is set to 4°C. + * @brief Start periodic measurement mode. * - * @note Only available in idle mode. + * Starts the periodic measurement mode. The signal update interval is 5 + * seconds. * - * @param t_offset_m_deg_c Temperature offset in milli degrees Celsius. + * @note This command is only available in idle mode. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_get_temperature_offset(int32_t* t_offset_m_deg_c); +int16_t scd4x_start_periodic_measurement(); /** - * scd4x_set_temperature_offset_ticks() - Setting the temperature offset of the - * SCD4x inside the customer device correctly allows the user to leverage the RH - * and T output signal. Note that the temperature offset can depend on various - * factors such as the SCD4x measurement mode, self-heating of close components, - * the ambient temperature and air flow. Thus, the SCD4x temperature offset - * should be determined inside the customer device under its typical operation - * and in thermal equilibrium. - * - * @note Only available in idle mode. + * @brief Read CO₂, temperature, and humidity measurements raw values. + * + * Reads the sensor output. The measurement data can only be read out once per + * signal update interval as the buffer is emptied upon read-out. If no data is + * available in the buffer, the sensor returns a NACK. To avoid a NACK response, + * the get_data_ready_status can be issued to check data status. The I2C master + * can abort the read transfer with a NACK followed by a STOP condition after + * any data byte if the user is not interested in subsequent data. + * + * @param[out] co2_concentration CO₂ concentration in ppm + * @param[out] temperature Convert to degrees celsius by (175 * value / 65535) - + * 45 + * @param[out] relative_humidity Convert to relative humidity in % by (100 * + * value / 65535) + * + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_read_measurement_raw(uint16_t* co2_concentration, + uint16_t* temperature, + uint16_t* relative_humidity); + +/** + * @brief Stop periodic measurement to change the sensor configuration or to + * save power. * - * @param t_offset Temperature offset. Convert °C to value by: T * 2^16 / 175. + * Command returns a sensor running in periodic measurement mode or low power + * periodic measurement mode back to the idle state, e.g. to then allow changing + * the sensor configuration or to save power. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_set_temperature_offset_ticks(uint16_t t_offset); +int16_t scd4x_stop_periodic_measurement(); /** - * scd4x_set_temperature_offset() - Setting the temperature offset of the SCD4x - * inside the customer device correctly allows the user to leverage the RH and T - * output signal. Note that the temperature offset can depend on various factors - * such as the SCD4x measurement mode, self-heating of close components, the - * ambient temperature and air flow. Thus, the SCD4x temperature offset should - * be determined inside the customer device under its typical operation and in - * thermal equilibrium. + * @brief Set the temperature compensation offset (raw value). + * + * Setting the temperature offset of the SCD4x inside the customer device allows + * the user to optimize the RH and T output signal. The temperature offset can + * depend on several factors such as the SCD4x measurement mode, self-heating of + * close components, the ambient temperature and air flow. Thus, the SCD4x + * temperature offset should be determined after integration into the final + * device and under its typical operating conditions (including the operation + * mode to be used in the application) in thermal equilibrium. By default, the + * temperature offset is set to 4 °C. To save the setting to the EEPROM, the + * persist_settings command may be issued. Equation (1) details how the + * characteristic temperature offset can be calculated using the current + * temperature output of the sensor (TSCD4x), a reference temperature value + * (TReference), and the previous temperature offset (Toffset_pervious) obtained + * using the get_temperature_offset_raw command: + * + * Toffset_actual = TSCD4x - TReference + Toffset_pervious. + * + * Recommended temperature offset values are between 0 °C and 20 °C. The + * temperature offset does not impact the accuracy of the CO2 output. + * + * @param[in] offset_temperature Temperature offset. Convert Toffset in °C to + * value by: (Toffset * 65535 / 175) * - * @note Only available in idle mode. + * @note This command is only available in idle mode. * - * @param t_offset_m_deg_c Temperature offset in milli degrees Celsius. + * @return error_code 0 on success, an error code otherwise. + * + * Example: + * -------- + * + * @code{.c} + * + * int16_t local_error = 0; + * local_error = scd4x_set_temperature_offset_raw(1498); + * if (local_error != NO_ERROR) { + * return local_error; + * } + * + * @endcode * - * @return 0 on success, an error code otherwise */ -int16_t scd4x_set_temperature_offset(int32_t t_offset_m_deg_c); +int16_t scd4x_set_temperature_offset_raw(uint16_t offset_temperature); /** - * scd4x_get_sensor_altitude() - Get configured sensor altitude in meters above - * sea level. Per default, the sensor altitude is set to 0 meter above - * sea-level. + * @brief Get the raw temperature compensation offset used by the sensor. * - * @note Only available in idle mode. + * @param[out] offset_temperature Convert to °C by (175 * value / 65535) * - * @param sensor_altitude Sensor altitude in meters. + * @note This command is only available in idle mode. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_get_sensor_altitude(uint16_t* sensor_altitude); +int16_t scd4x_get_temperature_offset_raw(uint16_t* offset_temperature); /** - * scd4x_set_sensor_altitude() - Set sensor altitude in meters above sea level. - * Note that setting a sensor altitude to the sensor overrides any pressure - * compensation based on a previously set ambient pressure. + * @brief Set the altitude of the sensor (in meters above sea level). + * + * Typically, the sensor altitude is set once after device installation. To save + * the setting to the EEPROM, the persist_settings command must be issued. The + * default sensor altitude value is set to 0 meters above sea level. Note that + * setting a sensor altitude to the sensor overrides any pressure compensation + * based on a previously set ambient pressure. * - * @note Only available in idle mode. + * @param[in] sensor_altitude Sensor altitude in meters above sea level. Valid + * input values are between 0 - 3000 m. + * + * @note This command is only available in idle mode. * - * @param sensor_altitude Sensor altitude in meters. + * @return error_code 0 on success, an error code otherwise. + * + * Example: + * -------- + * + * @code{.c} + * + * int16_t local_error = 0; + * local_error = scd4x_set_sensor_altitude(0); + * if (local_error != NO_ERROR) { + * return local_error; + * } + * + * @endcode * - * @return 0 on success, an error code otherwise */ int16_t scd4x_set_sensor_altitude(uint16_t sensor_altitude); /** - * scd4x_set_ambient_pressure() - The set_ambient_pressure command can be sent - * during periodic measurements to enable continuous pressure compensation. Note - * that setting an ambient pressure to the sensor overrides any pressure - * compensation based on a previously set sensor altitude. + * @brief Get the sensor altitude used by the sensor. + * + * @param[out] sensor_altitude Sensor altitude used by the sensor in meters + * above sea level. + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_get_sensor_altitude(uint16_t* sensor_altitude); + +/** + * @brief Set the raw ambient pressure value. + * + * The set_ambient_pressure command can be sent during periodic measurements to + * enable continuous pressure compensation. Note that setting an ambient + * pressure overrides any pressure compensation based on a previously set sensor + * altitude. Use of this command is highly recommended for applications + * experiencing significant ambient pressure changes to ensure sensor accuracy. + * Valid input values are between 70000 - 120000 Pa. The default value is 101300 + * Pa. + * + * @param[in] ambient_pressure Convert ambient_pressure in hPa to Pa by + * ambient_pressure / 100. * * @note Available during measurements. * - * @param ambient_pressure Ambient pressure in hPa. Convert value to Pa by: - * value * 100. + * @return error_code 0 on success, an error code otherwise. + * + * Example: + * -------- + * + * @code{.c} + * + * int16_t local_error = 0; + * local_error = scd4x_set_ambient_pressure_raw(1013); + * if (local_error != NO_ERROR) { + * return local_error; + * } + * + * @endcode * - * @return 0 on success, an error code otherwise */ -int16_t scd4x_set_ambient_pressure(uint16_t ambient_pressure); +int16_t scd4x_set_ambient_pressure_raw(uint16_t ambient_pressure); /** - * scd4x_perform_forced_recalibration() - To successfully conduct an accurate -forced recalibration, the following steps need to be carried out: -1. Operate the SCD4x in a periodic measurement mode for > 3 minutes in an -environment with homogenous and constant CO₂ concentration. -2. Stop periodic measurement. Wait 500 ms. -3. Subsequently issue the perform_forced_recalibration command and optionally -read out the baseline correction. A return value of 0xffff indicates that the -forced recalibration failed. + * @brief Get the ambient pressure around the sensor. + * + * @param[out] ambient_pressure Convert to Pa by value = ambient_pressure * 100. * - * @param target_co2_concentration Target CO₂ concentration in ppm. + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_get_ambient_pressure_raw(uint16_t* ambient_pressure); + +/** + * @brief Perform a forced recalibration (FRC) of the CO₂ concentration. * - * @param frc_correction FRC correction value in CO₂ ppm or 0xFFFF if the -command failed. Convert value to CO₂ ppm with: value - 0x8000 + * To successfully conduct an accurate FRC, the following steps need to be + * carried out: * - * @return 0 on success, an error code otherwise + * 1. Operate the SCD4x in the operation mode later used for normal sensor + * operation (e.g. periodic measurement) for at least 3 minutes in an + * environment with a homogenous and constant CO2 concentration. The sensor must + * be operated at the voltage desired for the application when performing the + * FRC sequence. 2. Issue the stop_periodic_measurement command. 3. Issue the + * perform_forced_recalibration command. + * + * A return value of 0xffff indicates that the FRC has failed because the sensor + * was not operated before sending the command. + * + * @param[in] target_co2_concentration Target CO₂ concentration in ppm CO₂. + * @param[out] frc_correction Convert to FRC correction in ppm CO₂ by + * frc_correction - 0x8000. A return value of 0xFFFF indicates that the FRC has + * failed because the sensor was not operated before sending the command. + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. */ int16_t scd4x_perform_forced_recalibration(uint16_t target_co2_concentration, uint16_t* frc_correction); /** - * scd4x_get_automatic_self_calibration() - By default, the ASC is enabled. + * @brief Enable or disable automatic self calibration (ASC). + * + * Sets the current state (enabled / disabled) of the ASC. By default, ASC is + * enabled. To save the setting to the EEPROM, the persist_settings command must + * be issued. The ASC enables excellent long-term stability of SCD4x without the + * need for regular user intervention. The algorithm leverages the sensor's + * measurement history and the assumption of exposure of the sensor to a known + * minimum background CO₂ concentration at least once over a period of + * cumulative operation. By default, the ASC algorithm assumes that the sensor + * is exposed to outdoor fresh air at 400 ppm CO₂ concentration at least once + * per week of accumulated operation using one of the following measurement + * modes for at least 4 hours without interruption at a time: periodic + * measurement mode, low power periodic measurement mode or single shot mode + * with a measurement interval of 5 minutes (SCD41 only). + * + * @param[in] asc_enabled 1 enables ASC, 0 disables ASC. + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + * + * Example: + * -------- * - * @param asc_enabled 1 if ASC is enabled, 0 if ASC is disabled + * @code{.c} + * + * int16_t local_error = 0; + * local_error = scd4x_set_automatic_self_calibration_enabled(1); + * if (local_error != NO_ERROR) { + * return local_error; + * } + * + * @endcode * - * @return 0 on success, an error code otherwise */ -int16_t scd4x_get_automatic_self_calibration(uint16_t* asc_enabled); +int16_t scd4x_set_automatic_self_calibration_enabled(uint16_t asc_enabled); /** - * scd4x_set_automatic_self_calibration() - By default, the ASC is enabled. + * @brief Check if automatic self calibration (ASC) is enabled. + * + * @param[out] asc_enabled 1 if ASC is enabled, 0 if ASC is disabled. + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_get_automatic_self_calibration_enabled(uint16_t* asc_enabled); + +/** + * @brief Set the value of ASC baseline target in ppm. + * + * Sets the value of the ASC baseline target, i.e. the CO₂ concentration in ppm + * which the ASC algorithm will assume as lower-bound background to which the + * SCD4x is exposed to regularly within one ASC period of operation. To save the + * setting to the EEPROM, the persist_settings command must be issued + * subsequently. The factory default value is 400 ppm. + * + * @param[in] asc_target ASC baseline value in ppm CO₂ + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + * + * Example: + * -------- + * + * @code{.c} + * + * int16_t local_error = 0; + * local_error = scd4x_set_automatic_self_calibration_target(400); + * if (local_error != NO_ERROR) { + * return local_error; + * } * - * @param asc_enabled 1 to enable ASC, 0 to disable ASC + * @endcode * - * @return 0 on success, an error code otherwise */ -int16_t scd4x_set_automatic_self_calibration(uint16_t asc_enabled); +int16_t scd4x_set_automatic_self_calibration_target(uint16_t asc_target); /** - * scd4x_start_low_power_periodic_measurement() - Start low power periodic - * measurement, signal update interval is 30 seconds. + * @brief Reads out the ASC baseline target concentration parameter. + * + * @param[out] asc_target ASC baseline target concentration parameter in ppm + * CO₂. * * @note This command is only available in idle mode. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_get_automatic_self_calibration_target(uint16_t* asc_target); + +/** + * @brief Start a low-power periodic measurement (interval 30 s). + * + * To enable use-cases with a constrained power budget, the SCD4x features a low + * power periodic measurement mode with a signal update interval of + * approximately 30 seconds. The low power periodic measurement mode is + * initiated using the start_low_power_periodic_measurement command and read-out + * in a similar manner as the periodic measurement mode using the + * read_measurement command. To periodically check whether a new measurement + * result is available for read out, the get_data_ready_status command can be + * used to synchronize to the sensor's internal measurement interval as an + * alternative to relying on the ACK/NACK status of the + * read_measurement_command. + * + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_start_low_power_periodic_measurement(void); +int16_t scd4x_start_low_power_periodic_measurement(); /** - * scd4x_get_data_ready_flag() - Check whether new measurement data is - * available for read-out. + * @brief Read if data is ready. * - * @param data_ready_flag True if data available, otherwise false. + * Polls the sensor for whether data from a periodic or single shot measurement + * is ready to be read out. * - * @return 0 on success, an error code otherwise + * @param[out] data_ready_status If one or more of the 11 least significant bits + * are 1, then the data is ready. + * + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_get_data_ready_flag(bool* data_ready_flag); +int16_t scd4x_get_data_ready_status_raw(uint16_t* data_ready_status); /** - * scd4x_persist_settings() - Configuration settings such as the temperature - * offset, sensor altitude and the ASC enabled/disabled parameter are by default - * stored in the volatile memory (RAM) only and will be lost after a - * power-cycle. The persist_settings command stores the current configuration in - * the EEPROM of the SCD4x, making them resistant to power-cycling. To avoid - * unnecessary wear of the EEPROM, the persist_settings command should only be - * sent when persistence is required and if actual changes to the configuration - * have been made. Note that field calibration history (i.e. FRC and ASC) is - * stored in the EEPROM automatically. + * @brief Store volatile sensor settings in the EEPROM. + * + * Configuration settings such as the temperature offset, sensor altitude and + * the ASC enabled/disabled parameters are by default stored in the volatile + * memory (RAM) only. The persist_settings command stores the current + * configuration in the EEPROM of the SCD4x, ensuring the current settings + * persist after power-cycling. To avoid unnecessary wear of the EEPROM, the + * persist_settings command should only be sent following configuration changes + * whose persistence is required. The EEPROM is guaranteed to withstand at least + * 2000 write cycles. Note that field calibration history (i.e. FRC and ASC) is + * automatically stored in a separate EEPROM dimensioned for the specified + * sensor lifetime when operated continuously in either periodic measurement + * mode, low power periodic measurement mode or single shot mode with 5 minute + * measurement interval (SCD41 only). * - * @note + * @note This command is only available in idle mode. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_persist_settings(void); +int16_t scd4x_persist_settings(); /** - * scd4x_get_serial_number() - Reading out the serial number can be used to - * identify the chip and to verify the presence of the sensor. The get serial - * number command returns 3 words. Together, the 3 words constitute a unique - * serial number with a length of 48 bits (big endian format). + * @brief Read the sensor's unique serial number. * - * @param serial_0 First word of the 48 bit serial number + * Reading out the serial number can be used to identify the chip and to verify + * the presence of the sensor. The get_serial_number command returns 3 words, + * and every word is followed by an 8-bit CRC checksum. Together, the 3 words + * constitute a unique serial number with a length of 48 bits (in big endian + * format). * - * @param serial_1 Second word of the 48 bit serial number + * @param[out] serial_number 48-bit unique serial number of the sensor. * - * @param serial_2 Third word of the 48 bit serial number + * @note This command is only available in idle mode. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_get_serial_number(uint16_t* serial_0, uint16_t* serial_1, - uint16_t* serial_2); +int16_t scd4x_get_serial_number(uint16_t* serial_number, + uint16_t serial_number_size); /** - * scd4x_perform_self_test() - The perform_self_test feature can be used as an - * end-of-line test to confirm sensor functionality. + * @brief Perform self test to assess sensor functionality and power supply. * - * @param sensor_status 0 means no malfunction detected + * Can be used as an end-of-line test to check the sensor functionality. * - * @return 0 on success, an error code otherwise + * @param[out] sensor_status If sensor status is equal to 0, no malfunction has + * been detected. + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. */ int16_t scd4x_perform_self_test(uint16_t* sensor_status); /** - * scd4x_perform_factory_reset() - Initiates the reset of all configurations - * stored in the EEPROM and erases the FRC and ASC algorithm history. + * @brief Perform factory reset to erase the settings stored in the EEPROM. + * + * The perform_factory_reset command resets all configuration settings stored in + * the EEPROM and erases the FRC and ASC algorithm history. + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_perform_factory_reset(); + +/** + * @brief Reinitialize the sensor by reloading the settings from the EEPROM. + * + * The reinit command reinitialize the sensor by reloading user settings from + * EEPROM. The sensor must be in the idle state before sending the reinit + * command. If the reinit command does not trigger the desired + * re-initialization, a power-cycle should be applied to the SCD4x. + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_reinit(); + +/** + * @brief Reads out the SCD4x sensor variant. + * + * @param[out] sensor_variant Bits[15…12] = 0000 → SCD40 Bits[15…12] = 0001 → + * SCD41 + * + * @note This command is only available in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_get_sensor_variant_raw(uint16_t* sensor_variant); + +/** + * @brief On-demand measurement of the CO₂ concentration, temperature, and + * humidity. + * + * The sensor output is read out by using the read_measurement command. The + * fastest possible sampling interval for single shot measurements is 5 seconds. + * The ASC is enabled by default in single shot operation and optimized for + * single shot measurements performed every 5 minutes. For more details about + * single shot measurements and optimization of power consumption please refer + * to the datasheet. + * + * @note This command is only available for SCD41. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_perform_factory_reset(void); +int16_t scd4x_measure_single_shot(); /** - * scd4x_reinit() - The reinit command reinitializes the sensor by reloading - * user settings from EEPROM. Before sending the reinit command, the stop - * measurement command must be issued. If reinit command does not trigger the - * desired re-initialization, a power-cycle should be applied to the SCD4x. + * @brief On-demand measurement of the temperature and humidity only. * - * @note Only available in idle mode. + * For more details about single shot measurements and optimization of power + * consumption please refer to the datasheet. * - * @return 0 on success, an error code otherwise + * @note This command is only available for SCD41. + * + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_reinit(void); +int16_t scd4x_measure_single_shot_rht_only(); /** - * scd4x_measure_single_shot() - On-demand measurement of CO₂ concentration, - * relative humidity and temperature. The sensor output is read with the - * read_measurement command. + * @brief Put the sensor into sleep mode from idle mode. + * + * Put the sensor from idle to sleep to reduce power consumption. Can be used to + * power down when operating the sensor in power-cycled single shot mode. * - * @note Only available in idle mode. + * @note This command is only available in idle mode. Only for SCD41. * - * @return 0 on success, an error code otherwise + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_measure_single_shot(void); +int16_t scd4x_power_down(); /** - * scd4x_measure_single_shot_rht_only() - On-demand measurement of relative - * humidity and temperature only. + * @brief Wake up sensor from sleep mode to idle mode. * - * @note Only available in idle mode. + * Wake up the sensor from sleep mode into idle mode. Note that the SCD4x does + * not acknowledge the wake_up command. The sensor's idle state after wake up + * can be verified by reading out the serial number. * - * @return 0 on success, an error code otherwise + * @note This command is only available for SCD41. + * + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_measure_single_shot_rht_only(void); +int16_t scd4x_wake_up(); /** - * scd4x_power_down() - Put the sensor from idle to sleep mode to reduce current - * consumption. + * @brief Sets the initial period for ASC correction + * + * Sets the duration of the initial period for ASC correction (in hours). By + * default, the initial period for ASC correction is 44 hours. Allowed values + * are integer multiples of 4 hours. A value of 0 results in an immediate + * correction. To save the setting to the EEPROM, the persist_settings command + * must be issued. + * + * For single shot operation, this parameter always assumes a measurement + * interval of 5 minutes, counting the number of single shots to calculate + * elapsed time. If single shot measurements are taken more / less frequently + * than once every 5 minutes, this parameter must be scaled accordingly to + * achieve the intended period in hours (e.g. for a 10-minute measurement + * interval, the scaled parameter value is obtained by multiplying the intended + * period in hours by 0.5). + * + * @param[in] asc_initial_period ASC initial period in hours * - * @note Only available in idle mode. + * @note This command is available for SCD41 and only in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + * + * Example: + * -------- + * + * @code{.c} + * + * int16_t local_error = 0; + * local_error = scd4x_set_automatic_self_calibration_initial_period(44); + * if (local_error != NO_ERROR) { + * return local_error; + * } + * + * @endcode * - * @return 0 on success, an error code otherwise */ -int16_t scd4x_power_down(void); +int16_t scd4x_set_automatic_self_calibration_initial_period( + uint16_t asc_initial_period); /** - * scd4x_wake_up() - Wake up sensor from sleep mode to idle mode. + * @brief Read out the initial period for ASC correction * - * @note Only available in sleep mode. + * @param[out] asc_initial_period ASC initial period in hours * - * @return 0 on success, an error code otherwise + * @note This command is only available for SCD41 and only in idle mode. + * + * @return error_code 0 on success, an error code otherwise. */ -int16_t scd4x_wake_up(void); +int16_t scd4x_get_automatic_self_calibration_initial_period( + uint16_t* asc_initial_period); + +/** + * @brief Sets the standard period for ASC correction. + * + * Sets the standard period for ASC correction (in hours). By default, the + * standard period for ASC correction is 156 hours. Allowed values are integer + * multiples of 4 hours. Note: a value of 0 results in an immediate correction. + * To save the setting to the EEPROM, the persist_settings (see Section 3.10.1) + * command must be issued. + * + * For single shot operation, this parameter always assumes a measurement + * interval of 5 minutes, counting the number of single shots to calculate + * elapsed time. If single shot measurements are taken more / less frequently + * than once every 5 minutes, this parameter must be scaled accordingly to + * achieve the intended period in hours (e.g. for a 10-minute measurement + * interval, the scaled parameter value is obtained by multiplying the intended + * period in hours by 0.5). + * + * @param[in] asc_standard_period ASC standard period in hours + * + * @note This command is only available for SCD41 and only in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + * + * Example: + * -------- + * + * @code{.c} + * + * int16_t local_error = 0; + * local_error = scd4x_set_automatic_self_calibration_standard_period(156); + * if (local_error != NO_ERROR) { + * return local_error; + * } + * + * @endcode + * + */ +int16_t scd4x_set_automatic_self_calibration_standard_period( + uint16_t asc_standard_period); + +/** + * @brief Get the standard period for ASC correction. + * + * @param[out] asc_standard_period ASC standard period in hours + * + * @note This command is only available for SCD41 and only in idle mode. + * + * @return error_code 0 on success, an error code otherwise. + */ +int16_t scd4x_get_automatic_self_calibration_standard_period( + uint16_t* asc_standard_period); #ifdef __cplusplus } #endif - -#endif /* SCD4X_I2C_H */ +#endif // SCD4X_I2C_H diff --git a/sensirion_common.c b/sensirion_common.c index 4ee7a96..3cab3c1 100644 --- a/sensirion_common.c +++ b/sensirion_common.c @@ -60,27 +60,27 @@ float sensirion_common_bytes_to_float(const uint8_t* bytes) { } void sensirion_common_uint32_t_to_bytes(const uint32_t value, uint8_t* bytes) { - bytes[0] = value >> 24; - bytes[1] = value >> 16; - bytes[2] = value >> 8; - bytes[3] = value; + bytes[0] = (uint8_t)(value >> 24); + bytes[1] = (uint8_t)(value >> 16); + bytes[2] = (uint8_t)(value >> 8); + bytes[3] = (uint8_t)(value); } void sensirion_common_uint16_t_to_bytes(const uint16_t value, uint8_t* bytes) { - bytes[0] = value >> 8; - bytes[1] = value; + bytes[0] = (uint8_t)(value >> 8); + bytes[1] = (uint8_t)value; } void sensirion_common_int32_t_to_bytes(const int32_t value, uint8_t* bytes) { - bytes[0] = value >> 24; - bytes[1] = value >> 16; - bytes[2] = value >> 8; - bytes[3] = value; + bytes[0] = (uint8_t)(value >> 24); + bytes[1] = (uint8_t)(value >> 16); + bytes[2] = (uint8_t)(value >> 8); + bytes[3] = (uint8_t)value; } void sensirion_common_int16_t_to_bytes(const int16_t value, uint8_t* bytes) { - bytes[0] = value >> 8; - bytes[1] = value; + bytes[0] = (uint8_t)(value >> 8); + bytes[1] = (uint8_t)value; } void sensirion_common_float_to_bytes(const float value, uint8_t* bytes) { @@ -99,3 +99,22 @@ void sensirion_common_copy_bytes(const uint8_t* source, uint8_t* destination, destination[i] = source[i]; } } + +void sensirion_common_to_integer(const uint8_t* source, uint8_t* destination, + INT_TYPE int_type, uint8_t data_length) { + + if (data_length > int_type) { + data_length = 0; // we do not read at all if data_length is bigger than + // the provided integer! + } + + // pad missing bytes + uint8_t offset = int_type - data_length; + for (uint8_t i = 0; i < offset; i++) { + destination[int_type - i - 1] = 0; + } + + for (uint8_t i = 1; i <= data_length; i++) { + destination[int_type - offset - i] = source[i - 1]; + } +} diff --git a/sensirion_common.h b/sensirion_common.h index cfcd19f..e290933 100644 --- a/sensirion_common.h +++ b/sensirion_common.h @@ -50,6 +50,11 @@ extern "C" { #define SENSIRION_NUM_WORDS(x) (sizeof(x) / SENSIRION_WORD_SIZE) #define SENSIRION_MAX_BUFFER_WORDS 32 +/** + * Enum to describe the type of an integer + */ +typedef enum { BYTE = 1, SHORT = 2, INTEGER = 4, LONG_INTEGER = 8 } INT_TYPE; + /** * sensirion_common_bytes_to_int16_t() - Convert an array of bytes to an int16_t * @@ -174,6 +179,17 @@ void sensirion_common_float_to_bytes(const float value, uint8_t* bytes); void sensirion_common_copy_bytes(const uint8_t* source, uint8_t* destination, uint16_t data_length); +/** + * sensirion_common_to_integer() - Copy bytes from byte array to integer. + * + * @param source Array of bytes to be copied. + * @param int_value Pointer to integer of bytes to be copied to. + * @param int_type Type (size) of the integer to be copied. + * @param data_length Number of bytes to copy. + */ +void sensirion_common_to_integer(const uint8_t* source, uint8_t* destination, + INT_TYPE int_type, uint8_t data_length); + #ifdef __cplusplus } #endif diff --git a/sensirion_i2c.c b/sensirion_i2c.c index 784c402..5f709fc 100644 --- a/sensirion_i2c.c +++ b/sensirion_i2c.c @@ -177,6 +177,19 @@ uint16_t sensirion_i2c_add_command_to_buffer(uint8_t* buffer, uint16_t offset, return offset; } +uint16_t sensirion_i2c_add_command16_to_buffer(uint8_t* buffer, uint16_t offset, + uint16_t command) { + buffer[offset++] = (uint8_t)((command & 0xFF00) >> 8); + buffer[offset++] = (uint8_t)((command & 0x00FF) >> 0); + return offset; +} + +uint16_t sensirion_i2c_add_command8_to_buffer(uint8_t* buffer, uint16_t offset, + uint8_t command) { + buffer[offset++] = command; + return offset; +} + uint16_t sensirion_i2c_add_uint32_t_to_buffer(uint8_t* buffer, uint16_t offset, uint32_t data) { buffer[offset++] = (uint8_t)((data & 0xFF000000) >> 24); @@ -238,7 +251,7 @@ uint16_t sensirion_i2c_add_float_to_buffer(uint8_t* buffer, uint16_t offset, } uint16_t sensirion_i2c_add_bytes_to_buffer(uint8_t* buffer, uint16_t offset, - uint8_t* data, + const uint8_t* data, uint16_t data_length) { uint16_t i; diff --git a/sensirion_i2c.h b/sensirion_i2c.h index db99c20..45ff5c3 100644 --- a/sensirion_i2c.h +++ b/sensirion_i2c.h @@ -181,6 +181,39 @@ int16_t sensirion_i2c_read_cmd(uint8_t address, uint16_t cmd, uint16_t sensirion_i2c_add_command_to_buffer(uint8_t* buffer, uint16_t offset, uint16_t command); +/** + * sensirion_i2c_add_command16_to_buffer() - Add a command to the buffer at + * the specified offset. This function is equivalent to the + * function sensirion_i2c_add_command_to_buffer(). + * + * @param buffer Pointer to buffer in which the write frame will be prepared. + * Caller needs to make sure that there is enough space after + * offset left to write the data into the buffer. + * @param offset Offset of the next free byte in the buffer. + * @param command Command to be written into the buffer. + * + * @return Offset of next free byte in the buffer after writing the data. + */ +uint16_t sensirion_i2c_add_command16_to_buffer(uint8_t* buffer, uint16_t offset, + uint16_t command); + +/** + * sensirion_i2c_add_command8_to_buffer() - Add a command to the buffer at + * offset. Adds one bytes command to the buffer. + * This is used for sensor that only take one command byte such as + * SHT. + * + * @param buffer Pointer to buffer in which the write frame will be prepared. + * Caller needs to make sure that there is enough space after + * offset left to write the data into the buffer. + * @param offset Offset of the next free byte in the buffer. + * @param command Command to be written into the buffer. + * + * @return Offset of next free byte in the buffer after writing the data. + */ +uint16_t sensirion_i2c_add_command8_to_buffer(uint8_t* buffer, uint16_t offset, + uint8_t command); + /** * sensirion_i2c_add_uint32_t_to_buffer() - Add a uint32_t to the buffer at * offset. Adds 6 bytes to the buffer. @@ -274,7 +307,8 @@ uint16_t sensirion_i2c_add_float_to_buffer(uint8_t* buffer, uint16_t offset, * data. */ uint16_t sensirion_i2c_add_bytes_to_buffer(uint8_t* buffer, uint16_t offset, - uint8_t* data, uint16_t data_length); + const uint8_t* data, + uint16_t data_length); /** * sensirion_i2c_write_data() - Writes data to the Sensor. diff --git a/sensirion_i2c_hal.c b/sensirion_i2c_hal.c index d63f815..d368cf2 100644 --- a/sensirion_i2c_hal.c +++ b/sensirion_i2c_hal.c @@ -83,7 +83,7 @@ void sensirion_i2c_hal_free(void) { * @param count number of bytes to read from I2C and store in the buffer * @returns 0 on success, error code otherwise */ -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count) { /* TODO:IMPLEMENT */ return NOT_IMPLEMENTED_ERROR; } @@ -100,7 +100,7 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) { * @returns 0 on success, error code otherwise */ int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count) { + uint8_t count) { /* TODO:IMPLEMENT */ return NOT_IMPLEMENTED_ERROR; } diff --git a/sensirion_i2c_hal.h b/sensirion_i2c_hal.h index f97444a..d6267b8 100644 --- a/sensirion_i2c_hal.h +++ b/sensirion_i2c_hal.h @@ -71,7 +71,7 @@ void sensirion_i2c_hal_free(void); * @param count number of bytes to read from I2C and store in the buffer * @returns 0 on success, error code otherwise */ -int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count); +int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint8_t count); /** * Execute one write transaction on the I2C bus, sending a given number of @@ -85,7 +85,7 @@ int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count); * @returns 0 on success, error code otherwise */ int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, - uint16_t count); + uint8_t count); /** * Sleep for a given number of microseconds. The function should delay the diff --git a/tests/Makefile b/tests/Makefile index a0b32ba..3da3839 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,19 +1,33 @@ -driver_dir := .. -mux_dir := ../i2c-mux-testbed -i2c_mux_sources = ${mux_dir}/i2c_mux.h ${mux_dir}/i2c_mux.c -common_sources = ${driver_dir}/sensirion_config.h ${driver_dir}/sensirion_common.h ${driver_dir}/sensirion_common.c -i2c_sources = ${driver_dir}/sensirion_i2c_hal.h ${driver_dir}/sensirion_i2c.h ${driver_dir}/sensirion_i2c.c -sensirion_test_sources = sensirion_test_setup.cpp ${i2c_mux_sources} +# use the second argument of make as argument to control test bed initialization +TEST_ARG := $(wordlist 2, 2, $(MAKECMDGOALS)) +# ...turn it into do-nothing target +$(eval $(TEST_ARG):;@:) + + ifeq ($(TEST_ARG), mux) + driver_dir := .. + mux_dir := ../i2c-mux-testbed + i2c_mux_sources = ${mux_dir}/i2c_mux.h ${mux_dir}/i2c_mux.c + macros := "-D USE_MUX" + else + mux_dir := . + i2c_mux_sources = + macros := + endif + +driver_dir := .. +common_sources = $(driver_dir)/sensirion_config.h $(driver_dir)/sensirion_common.h $(driver_dir)/sensirion_common.c +i2c_sources = $(driver_dir)/sensirion_i2c_hal.h ${driver_dir}/sensirion_i2c.h $(driver_dir)/sensirion_i2c.c +sensirion_test_sources = sensirion_test_setup.cpp $(i2c_mux_sources) -sw_i2c_dir := ${driver_dir}/sample-implementations/GPIO_bit_banging +sw_i2c_dir := $(driver_dir)/sample-implementations/GPIO_bit_banging -hw_i2c_impl_src = ${driver_dir}/sample-implementations/linux_user_space/sensirion_i2c_hal.c -sw_i2c_impl_src = ${sw_i2c_dir}/sample-implementations/linux_user_space/sensirion_i2c_gpio.c ${sw_i2c_dir}/sensirion_i2c_hal.c +hw_i2c_impl_src = $(driver_dir)/sample-implementations/linux_user_space/sensirion_i2c_hal.c +sw_i2c_impl_src = $(sw_i2c_dir)/sample-implementations/linux_user_space/sensirion_i2c_gpio.c $(sw_i2c_dir)/sensirion_i2c_hal.c -scd4x_sources = ${driver_dir}/scd4x_i2c.h ${driver_dir}/scd4x_i2c.c +scd4x_sources = $(driver_dir)/scd4x_i2c.h $(driver_dir)/scd4x_i2c.c -CXXFLAGS ?= $(CFLAGS) -fsanitize=address -I${mux_dir} -I${driver_dir} -I${sw_i2c_dir} +CXXFLAGS ?= $(CFLAGS) -fsanitize=address -I$(mux_dir) -I$(driver_dir) -I$(sw_i2c_dir) ${macros} ifdef CI CXXFLAGS += -Werror endif @@ -22,18 +36,18 @@ LDFLAGS ?= -lasan -lstdc++ -lCppUTest -lCppUTestExt .PHONY: clean test -scd4x_test_binaries := scd4x-test-hw_i2c scd4x-test-sw_i2c +scd4x_test_binaries := scd4x_test_hw_i2c scd4x_test_sw_i2c -all: ${scd4x_test_binaries} +all: $(scd4x_test_binaries) -scd4x-test-hw_i2c: scd4x_i2c_test.cpp ${scd4x_sources} ${sensirion_test_sources} ${i2c_sources} ${hw_i2c_impl_src} ${common_sources} +scd4x_test_hw_i2c: scd4x_i2c_test.cpp $(scd4x_sources) $(sensirion_test_sources) $(i2c_sources) $(hw_i2c_impl_src) $(common_sources) $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -scd4x-test-sw_i2c: scd4x_i2c_test.cpp ${scd4x_sources} ${sensirion_test_sources} ${i2c_sources} ${sw_i2c_impl_src} ${common_sources} +scd4x_test_sw_i2c: scd4x_i2c_test.cpp $(scd4x_sources) $(sensirion_test_sources) $(i2c_sources) $(sw_i2c_impl_src) $(common_sources) $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -test: ${scd4x_test_binaries} - set -ex; for test in ${scd4x_test_binaries}; do echo $${test}; ./$${test}; echo; done; +test: $(scd4x_test_binaries) + set -ex; for test in $(scd4x_test_binaries); do echo $${test}; ./$${test}; echo; done; clean: - $(RM) ${scd4x_test_binaries} + $(RM) $(scd4x_test_binaries) diff --git a/tests/scd4x_i2c_test.cpp b/tests/scd4x_i2c_test.cpp index 0bce7cb..f72c667 100644 --- a/tests/scd4x_i2c_test.cpp +++ b/tests/scd4x_i2c_test.cpp @@ -1,35 +1,11 @@ /* - * Copyright (c) 2021, Sensirion AG - * All rights reserved. + * THIS FILE IS AUTOMATICALLY GENERATED * - * 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. + * Generator: sensirion-driver-generator 1.1.2 + * Product: scd4x + * Model-Version: 2.0 */ -#include "i2c_mux.h" #include "scd4x_i2c.h" #include "sensirion_common.h" #include "sensirion_i2c.h" @@ -38,268 +14,256 @@ #include #include -TEST_GROUP (SCD4X_Tests) { - void setup() { - sensirion_i2c_hal_init(); - - // Select MUX 2 channel 0 - int16_t error = sensirion_i2c_mux_set_single_channel(0x72, 0); - CHECK_EQUAL_ZERO_TEXT(error, "sensirion_i2c_mux_set_single_channel"); +#define sensirion_hal_sleep_us sensirion_i2c_hal_sleep_usec - // try to reset sensor - (void)scd4x_wake_up(); - (void)scd4x_stop_periodic_measurement(); - error = scd4x_reinit(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_reinit"); +void print_ushort_array(uint16_t* array, uint16_t len) { + uint16_t i = 0; + printf("0x"); + for (; i < len; i++) { + printf("%04x", array[i]); } +} - void teardown() { - sensirion_i2c_hal_free(); +TEST_GROUP (SCD4X_Tests) { + void setup() { + scd4x_init(0x62); } }; -TEST (SCD4X_Tests, SCD4X_Test_start_periodic_measurement) { - int16_t error; - error = scd4x_start_periodic_measurement(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_start_periodic_measurement"); - - sensirion_i2c_hal_sleep_usec(5000000); - uint16_t co2; - uint16_t temperature; - uint16_t humidity; - error = scd4x_read_measurement_ticks(&co2, &temperature, &humidity); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_read_measurement_ticks"); - - printf("co2: %i\n", co2); - printf("temperature: %i\n", temperature); - printf("humidity: %i\n", humidity); - - error = scd4x_stop_periodic_measurement(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_stop_periodic_measurement"); +TEST (SCD4X_Tests, test_set_temperature_offset_raw1) { + int16_t local_error = 0; + local_error = scd4x_set_temperature_offset_raw(1498); + CHECK_EQUAL_ZERO_TEXT(local_error, "set_temperature_offset_raw"); } -TEST (SCD4X_Tests, SCD4X_Test_read_measurement_ticks_fails_in_idle) { - int16_t error; - uint16_t co2; - uint16_t temperature; - uint16_t humidity; - error = scd4x_read_measurement_ticks(&co2, &temperature, &humidity); - CHECK_TEXT(error != 0, "scd4x_read_measurement_ticks should fail in idle"); +TEST (SCD4X_Tests, test_get_temperature_offset_raw1) { + int16_t local_error = 0; + uint16_t offset_temperature = 0; + local_error = scd4x_get_temperature_offset_raw(&offset_temperature); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_temperature_offset_raw"); + printf("offset_temperature: %u\n", offset_temperature); } -TEST (SCD4X_Tests, SCD4X_Test_stop_periodic_measurement_in_idle) { - int16_t error; - error = scd4x_stop_periodic_measurement(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_stop_periodic_measurement"); +TEST (SCD4X_Tests, test_set_sensor_altitude1) { + int16_t local_error = 0; + local_error = scd4x_set_sensor_altitude(0); + CHECK_EQUAL_ZERO_TEXT(local_error, "set_sensor_altitude"); } -TEST (SCD4X_Tests, SCD4X_Test_get_temperature_offset_ticks_after_reinit) { - int16_t error; - uint16_t t_offset; - error = scd4x_get_temperature_offset_ticks(&t_offset); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_get_temperature_offset"); - printf("t_offset: %i\n", t_offset); - - CHECK_EQUAL_TEXT(t_offset, 1498, "T offset wrong after reinit") +TEST (SCD4X_Tests, test_get_sensor_altitude1) { + int16_t local_error = 0; + uint16_t sensor_altitude = 0; + local_error = scd4x_get_sensor_altitude(&sensor_altitude); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_sensor_altitude"); + printf("sensor_altitude: %u\n", sensor_altitude); } -TEST (SCD4X_Tests, SCD4X_Test_set_temperature_offset_ticks) { - int16_t error; - error = scd4x_set_temperature_offset_ticks(0); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_set_temperature_offset"); - - uint16_t t_offset; - error = scd4x_get_temperature_offset_ticks(&t_offset); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_get_temperature_offset"); - printf("t_offset: %i\n", t_offset); - - CHECK_EQUAL_TEXT(t_offset, 0, "T offset should be 0") +TEST (SCD4X_Tests, test_get_serial_number1) { + int16_t local_error = 0; + uint16_t serial_number[3] = {0}; + local_error = scd4x_get_serial_number(serial_number, 3); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_serial_number"); + printf("serial_number: "); + print_ushort_array(serial_number, 3); + printf("\n"); } -TEST (SCD4X_Tests, SCD4X_Test_get_sensor_altitude_default) { - int16_t error; - uint16_t sensor_altitude; - error = scd4x_get_sensor_altitude(&sensor_altitude); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_get_sensor_altitude"); - printf("sensor_altitude: %i\n", sensor_altitude); - - CHECK_EQUAL_TEXT(sensor_altitude, 0, - "sensor_altitude should be 0 by default"); +TEST (SCD4X_Tests, test_perform_forced_recalibration1) { + int16_t local_error = 0; + uint16_t frc_correction = 0; + local_error = scd4x_perform_forced_recalibration(400, &frc_correction); + CHECK_EQUAL_ZERO_TEXT(local_error, "perform_forced_recalibration"); + printf("frc_correction: %u\n", frc_correction); } -TEST (SCD4X_Tests, SCD4X_Test_set_sensor_altitude) { - int16_t error; - error = scd4x_set_sensor_altitude(42); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_set_sensor_altitude"); - - uint16_t sensor_altitude; - error = scd4x_get_sensor_altitude(&sensor_altitude); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_get_sensor_altitude"); - printf("sensor_altitude: %i\n", sensor_altitude); - - CHECK_EQUAL_TEXT(sensor_altitude, 42, - "sensor_altitude should be the set value"); +TEST (SCD4X_Tests, test_set_automatic_self_calibration_enabled1) { + int16_t local_error = 0; + local_error = scd4x_set_automatic_self_calibration_enabled(1); + CHECK_EQUAL_ZERO_TEXT(local_error, + "set_automatic_self_calibration_enabled"); } -TEST (SCD4X_Tests, SCD4X_Test_set_ambient_pressure) { - int16_t error; - uint16_t ambient_pressure = 0; - error = scd4x_set_ambient_pressure(ambient_pressure); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_set_ambient_pressure"); +TEST (SCD4X_Tests, test_get_automatic_self_calibration_enabled1) { + int16_t local_error = 0; + uint16_t asc_enabled = 0; + local_error = scd4x_get_automatic_self_calibration_enabled(&asc_enabled); + CHECK_EQUAL_ZERO_TEXT(local_error, + "get_automatic_self_calibration_enabled"); + printf("asc_enabled: %u\n", asc_enabled); } -TEST (SCD4X_Tests, SCD4X_Test_perform_forced_recalibration) { - int16_t error; - uint16_t target_co2_concentration = 400; - uint16_t frc_correction; - error = scd4x_perform_forced_recalibration(target_co2_concentration, - &frc_correction); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_perform_forced_recalibration"); - printf("frc_correction: %i\n", frc_correction); +TEST (SCD4X_Tests, test_set_automatic_self_calibration_target1) { + int16_t local_error = 0; + local_error = scd4x_set_automatic_self_calibration_target(400); + CHECK_EQUAL_ZERO_TEXT(local_error, "set_automatic_self_calibration_target"); } -TEST (SCD4X_Tests, SCD4X_Test_get_automatic_self_calibration_default) { - int16_t error; - uint16_t asc_enabled; - error = scd4x_get_automatic_self_calibration(&asc_enabled); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_get_automatic_self_calibration"); - printf("asc_enabled: %i\n", asc_enabled); - CHECK_EQUAL_TEXT(asc_enabled, 1, "ASC should be enabled by default"); +TEST (SCD4X_Tests, test_get_automatic_self_calibration_target1) { + int16_t local_error = 0; + uint16_t asc_target = 0; + local_error = scd4x_get_automatic_self_calibration_target(&asc_target); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_automatic_self_calibration_target"); + printf("asc_target: %u\n", asc_target); } -TEST (SCD4X_Tests, SCD4X_Test_set_automatic_self_calibration) { - int16_t error; - uint16_t asc_enabled = 0; - error = scd4x_set_automatic_self_calibration(asc_enabled); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_set_automatic_self_calibration"); - - error = scd4x_get_automatic_self_calibration(&asc_enabled); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_get_automatic_self_calibration"); - printf("asc_enabled: %i\n", asc_enabled); - CHECK_EQUAL_TEXT(asc_enabled, 0, "ASC should be set correctly"); +TEST (SCD4X_Tests, test_persist_settings1) { + int16_t local_error = 0; + local_error = scd4x_persist_settings(); + CHECK_EQUAL_ZERO_TEXT(local_error, "persist_settings"); } -TEST (SCD4X_Tests, SCD4X_Test_start_low_power_periodic_measurement) { - int16_t error; - error = scd4x_start_low_power_periodic_measurement(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_start_low_power_periodic_measurement"); - - sensirion_i2c_hal_sleep_usec(3000000); - - uint16_t co2; - uint16_t temperature; - uint16_t humidity; - error = scd4x_read_measurement_ticks(&co2, &temperature, &humidity); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_read_measurement_ticks"); - - printf("co2: %i\n", co2); - printf("temperature: %i\n", temperature); - printf("humidity: %i\n", humidity); - - error = scd4x_stop_periodic_measurement(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_stop_periodic_measurement"); +TEST (SCD4X_Tests, test_perform_self_test1) { + int16_t local_error = 0; + uint16_t sensor_status = 0; + local_error = scd4x_perform_self_test(&sensor_status); + CHECK_EQUAL_ZERO_TEXT(local_error, "perform_self_test"); + printf("sensor_status: %u\n", sensor_status); } -TEST (SCD4X_Tests, SCD4X_Test_get_data_ready_flag) { - int16_t error; - bool data_ready; - error = scd4x_get_data_ready_flag(&data_ready); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_get_data_ready_flag"); - printf("data_ready: %i\n", data_ready); +TEST (SCD4X_Tests, test_perform_factory_reset1) { + int16_t local_error = 0; + local_error = scd4x_perform_factory_reset(); + CHECK_EQUAL_ZERO_TEXT(local_error, "perform_factory_reset"); } -/* - * Persist settings may break the test -TEST (SCD4X_Tests, SCD4X_Test_persist_settings) { - int16_t error; - error = scd4x_persist_settings(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_persist_settings"); +TEST (SCD4X_Tests, test_reinit1) { + int16_t local_error = 0; + local_error = scd4x_reinit(); + CHECK_EQUAL_ZERO_TEXT(local_error, "reinit"); } -*/ -TEST (SCD4X_Tests, SCD4X_Test_get_serial_number) { - int16_t error; - uint16_t serial_0; - uint16_t serial_1; - uint16_t serial_2; - error = scd4x_get_serial_number(&serial_0, &serial_1, &serial_2); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_get_serial_number"); - printf("serial_0: %i\n", serial_0); - printf("serial_1: %i\n", serial_1); - printf("serial_2: %i\n", serial_2); +TEST (SCD4X_Tests, test_get_sensor_variant_raw1) { + int16_t local_error = 0; + uint16_t sensor_variant = 0; + local_error = scd4x_get_sensor_variant_raw(&sensor_variant); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_sensor_variant_raw"); + printf("sensor_variant: %u\n", sensor_variant); } -TEST (SCD4X_Tests, SCD4X_Test_perform_self_test) { - int16_t error; - uint16_t sensor_status; - error = scd4x_perform_self_test(&sensor_status); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_perform_self_test"); - printf("sensor_status: %i\n", sensor_status); +TEST (SCD4X_Tests, test_get_sensor_variant1) { + int16_t local_error = 0; + scd4x_sensor_variant a_sensor_variant = SCD4X_SENSOR_VARIANT_UNKNOWN; + local_error = scd4x_get_sensor_variant(&a_sensor_variant); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_sensor_variant"); + printf("a_sensor_variant: %i\n", a_sensor_variant); } -/* - * Continous factory reset may break the device -TEST (SCD4X_Tests, SCD4X_Test_perform_factory_reset) { - int16_t error; - error = scd4x_perform_factory_reset(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_perform_factory_reset"); +TEST (SCD4X_Tests, test_set_automatic_self_calibration_initial_period1) { + int16_t local_error = 0; + local_error = scd4x_set_automatic_self_calibration_initial_period(44); + CHECK_EQUAL_ZERO_TEXT(local_error, + "set_automatic_self_calibration_initial_period"); } -*/ -TEST (SCD4X_Tests, SCD4X_Test_reinit) { - int16_t error; - error = scd4x_reinit(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_reinit"); +TEST (SCD4X_Tests, test_get_automatic_self_calibration_initial_period1) { + int16_t local_error = 0; + uint16_t asc_initial_period = 0; + local_error = scd4x_get_automatic_self_calibration_initial_period( + &asc_initial_period); + CHECK_EQUAL_ZERO_TEXT(local_error, + "get_automatic_self_calibration_initial_period"); + printf("asc_initial_period: %u\n", asc_initial_period); } -TEST (SCD4X_Tests, SCD4X_Test_measure_single_shot) { - int16_t error; - error = scd4x_measure_single_shot(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_measure_single_shot"); - - uint16_t co2; - uint16_t temperature; - uint16_t humidity; - error = scd4x_read_measurement_ticks(&co2, &temperature, &humidity); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_read_measurement_ticks"); - - printf("co2: %i\n", co2); - printf("temperature: %i\n", temperature); - printf("humidity: %i\n", humidity); +TEST (SCD4X_Tests, test_set_automatic_self_calibration_standard_period1) { + int16_t local_error = 0; + local_error = scd4x_set_automatic_self_calibration_standard_period(156); + CHECK_EQUAL_ZERO_TEXT(local_error, + "set_automatic_self_calibration_standard_period"); } -TEST (SCD4X_Tests, SCD4X_Test_measure_single_shot_rht_only) { - int16_t error; - error = scd4x_measure_single_shot_rht_only(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_measure_single_shot_rht_only"); - - uint16_t co2; - uint16_t temperature; - uint16_t humidity; - error = scd4x_read_measurement_ticks(&co2, &temperature, &humidity); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_read_measurement_ticks"); - - printf("co2: %i\n", co2); - printf("temperature: %i\n", temperature); - printf("humidity: %i\n", humidity); - - CHECK_EQUAL_TEXT(co2, 0, "CO2 should be zero in rht only measurement"); +TEST (SCD4X_Tests, test_get_automatic_self_calibration_standard_period1) { + int16_t local_error = 0; + uint16_t asc_standard_period = 0; + local_error = scd4x_get_automatic_self_calibration_standard_period( + &asc_standard_period); + CHECK_EQUAL_ZERO_TEXT(local_error, + "get_automatic_self_calibration_standard_period"); + printf("asc_standard_period: %u\n", asc_standard_period); } -TEST (SCD4X_Tests, SCD4X_Test_power_down) { - int16_t error; - error = scd4x_power_down(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_power_down"); +TEST (SCD4X_Tests, test_measure_single_shot_rht_only1) { + int16_t local_error = 0; + local_error = scd4x_measure_single_shot_rht_only(); + CHECK_EQUAL_ZERO_TEXT(local_error, "measure_single_shot_rht_only"); +} - sensirion_i2c_hal_sleep_usec(20000); +TEST (SCD4X_Tests, test_measure_single_shot1) { + int16_t local_error = 0; + local_error = scd4x_measure_single_shot(); + CHECK_EQUAL_ZERO_TEXT(local_error, "measure_single_shot"); +} - error = scd4x_wake_up(); - printf("error: %i\n", error); - CHECK_EQUAL_ZERO_TEXT(error, "wake-up should not forward error"); +TEST (SCD4X_Tests, test_start_periodic_measurement1) { + int16_t local_error = 0; + uint16_t co2_concentration = 0; + uint16_t temperature = 0; + uint16_t relative_humidity = 0; + uint32_t a_ambient_pressure = 0; + uint16_t ambient_pressure = 0; + bool arg_0 = false; + uint16_t data_ready_status = 0; + local_error = scd4x_start_periodic_measurement(); + CHECK_EQUAL_ZERO_TEXT(local_error, "start_periodic_measurement"); + local_error = scd4x_read_measurement_raw(&co2_concentration, &temperature, + &relative_humidity); + CHECK_EQUAL_ZERO_TEXT(local_error, "read_measurement_raw"); + printf("co2_concentration: %u ", co2_concentration); + printf("temperature: %u ", temperature); + printf("relative_humidity: %u\n", relative_humidity); + local_error = scd4x_set_ambient_pressure(101300); + CHECK_EQUAL_ZERO_TEXT(local_error, "set_ambient_pressure"); + local_error = scd4x_get_ambient_pressure(&a_ambient_pressure); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_ambient_pressure"); + printf("a_ambient_pressure: %u\n", a_ambient_pressure); + local_error = scd4x_set_ambient_pressure_raw(1013); + CHECK_EQUAL_ZERO_TEXT(local_error, "set_ambient_pressure_raw"); + local_error = scd4x_get_ambient_pressure_raw(&ambient_pressure); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_ambient_pressure_raw"); + printf("ambient_pressure: %u\n", ambient_pressure); + local_error = scd4x_get_data_ready_status(&arg_0); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_data_ready_status"); + printf("arg_0: %d\n", arg_0); + local_error = scd4x_get_data_ready_status_raw(&data_ready_status); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_data_ready_status_raw"); + printf("data_ready_status: %u\n", data_ready_status); + local_error = scd4x_stop_periodic_measurement(); + CHECK_EQUAL_ZERO_TEXT(local_error, "stop_periodic_measurement"); } -TEST (SCD4X_Tests, SCD4X_Test_wake_up) { - int16_t error; - error = scd4x_wake_up(); - CHECK_EQUAL_ZERO_TEXT(error, "scd4x_wake_up"); +TEST (SCD4X_Tests, test_start_low_power_periodic_measurement1) { + int16_t local_error = 0; + uint16_t co2_concentration = 0; + uint16_t temperature = 0; + uint16_t relative_humidity = 0; + uint32_t a_ambient_pressure = 0; + uint16_t ambient_pressure = 0; + bool arg_0 = false; + uint16_t data_ready_status = 0; + local_error = scd4x_start_low_power_periodic_measurement(); + CHECK_EQUAL_ZERO_TEXT(local_error, "start_low_power_periodic_measurement"); + local_error = scd4x_read_measurement_raw(&co2_concentration, &temperature, + &relative_humidity); + CHECK_EQUAL_ZERO_TEXT(local_error, "read_measurement_raw"); + printf("co2_concentration: %u ", co2_concentration); + printf("temperature: %u ", temperature); + printf("relative_humidity: %u\n", relative_humidity); + local_error = scd4x_set_ambient_pressure(101300); + CHECK_EQUAL_ZERO_TEXT(local_error, "set_ambient_pressure"); + local_error = scd4x_get_ambient_pressure(&a_ambient_pressure); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_ambient_pressure"); + printf("a_ambient_pressure: %u\n", a_ambient_pressure); + local_error = scd4x_set_ambient_pressure_raw(1013); + CHECK_EQUAL_ZERO_TEXT(local_error, "set_ambient_pressure_raw"); + local_error = scd4x_get_ambient_pressure_raw(&ambient_pressure); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_ambient_pressure_raw"); + printf("ambient_pressure: %u\n", ambient_pressure); + local_error = scd4x_get_data_ready_status(&arg_0); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_data_ready_status"); + printf("arg_0: %d\n", arg_0); + local_error = scd4x_get_data_ready_status_raw(&data_ready_status); + CHECK_EQUAL_ZERO_TEXT(local_error, "get_data_ready_status_raw"); + printf("data_ready_status: %u\n", data_ready_status); + local_error = scd4x_stop_periodic_measurement(); + CHECK_EQUAL_ZERO_TEXT(local_error, "stop_periodic_measurement"); } diff --git a/tests/sensirion_test_setup.cpp b/tests/sensirion_test_setup.cpp index 22dbb6e..e47f022 100644 --- a/tests/sensirion_test_setup.cpp +++ b/tests/sensirion_test_setup.cpp @@ -1,5 +1,21 @@ +#include "sensirion_test_setup.h" #include "CppUTest/CommandLineTestRunner.h" +#include "sensirion_i2c_hal.h" + +#ifdef USE_MUX +#include "i2c_mux.h" +#define INIT_TESTBED(x, y) sensirion_i2c_mux_set_single_channel((x), (y)) +#else +#define INIT_TESTBED(x, y) 0 +#endif + +#define MUX_CHANNEL 0x71 int main(int argc, char** argv) { - return CommandLineTestRunner::RunAllTests(argc, argv); + sensirion_i2c_hal_init(); + int16_t error = INIT_TESTBED(MUX_CHANNEL, 1); + CHECK_EQUAL_ZERO_TEXT(error, "test-bed initialization failed"); + int result = CommandLineTestRunner::RunAllTests(argc, argv); + sensirion_i2c_hal_free(); + return result; }