10 #define SENSIRION_BIG_ENDIAN 0
11 #define SFM3019_I2C_ADDRESS 0x2E
13 #define SFM3019_CMD_START_CONTINUOUS_MEASUREMENT_O2 \
14 SFM_CMD_START_CONTINUOUS_MEASUREMENT_GAS0
15 #define SFM3019_CMD_START_CONTINUOUS_MEASUREMENT_AIR \
16 SFM_CMD_START_CONTINUOUS_MEASUREMENT_GAS1
17 #define SFM3019_CMD_START_CONTINUOUS_MEASUREMENT_AIR_O2_MIX \
18 SFM_CMD_START_CONTINUOUS_MEASUREMENT_GAS_MIX_0
20 #define SFM3019_SOFT_RESET_TIME_US 2000
21 #define SENSIRION_I2C_CLOCK_PERIOD_USEC 10
25 #define STATUS_FAIL (-1)
27 #if SENSIRION_BIG_ENDIAN
28 #define be16_to_cpu(s) (s)
29 #define be32_to_cpu(s) (s)
30 #define be64_to_cpu(s) (s)
31 #define SENSIRION_WORDS_TO_BYTES(a, w) ()
35 #define be16_to_cpu(s) (((uint16_t)(s) << 8) | (0xff & ((uint16_t)(s)) >> 8))
36 #define be32_to_cpu(s) \
37 (((uint32_t)be16_to_cpu(s) << 16) | (0xffff & (be16_to_cpu((s) >> 16))))
38 #define be64_to_cpu(s) \
39 (((uint64_t)be32_to_cpu(s) << 32) | \
40 (0xffffffff & ((uint64_t)be32_to_cpu((s) >> 32))))
47 #define SENSIRION_WORDS_TO_BYTES(a, w) \
48 for (uint16_t *__a = (uint16_t *)(a), __e = (w), __w = 0; __w < __e; \
50 __a[__w] = be16_to_cpu(__a[__w]); \
55 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
58 #define CRC8_POLYNOMIAL 0x31
59 #define CRC8_INIT 0xFF
62 #define SENSIRION_COMMAND_SIZE 2
63 #define SENSIRION_WORD_SIZE 2
64 #define SENSIRION_NUM_WORDS(x) (sizeof(x) / SENSIRION_WORD_SIZE)
65 #define SENSIRION_MAX_BUFFER_WORDS 32
68 #define SFM_CMD_READ_PRODUCT_IDENTIFIER 0xE102
70 #define SFM_CMD_READ_SCALE_FACTOR_OFFSET_AND_FLOW_UNIT 0x3661
72 #define SFM_CMD_STOP_CONTINUOUS_MEASUREMENT 0x3FF9
80 uint16_t current_byte;
85 for (current_byte = 0; current_byte < count; ++current_byte) {
86 crc ^= (data[current_byte]);
87 for (crc_bit = 8; crc_bit > 0; --crc_bit) {
105 const uint8_t data = 0x06;
111 const uint16_t* args, uint8_t num_args) {
116 buf[idx++] = (uint8_t)((cmd & 0xFF00) >> 8);
117 buf[idx++] = (uint8_t)((cmd & 0x00FF) >> 0);
119 for (i = 0; i < num_args; ++i) {
120 buf[idx++] = (uint8_t)((args[i] & 0xFF00) >> 8);
121 buf[idx++] = (uint8_t)((args[i] & 0x00FF) >> 0);
131 uint16_t num_words) {
136 uint8_t*
const buf8 = (uint8_t*)word_buf;
151 data[j++] = buf8[i + 1];
158 uint16_t num_words) {
167 for (i = 0; i < num_words; ++i)
181 const uint16_t* data_words,
182 uint16_t num_words) {
191 uint32_t delay_us, uint16_t* data_words,
192 uint16_t num_words) {
208 uint16_t* data_words, uint16_t num_words) {
217 uint8_t readData[32];
218 uint8_t rxByteCount = 0;
223 memcpy(data, readData, count);
245 hwi->__delay_blocking_ms((useconds / 1000) + 1);
260 uint32_t* product_number,
261 uint8_t(*serial_number)[8]) {
272 if (product_number) {
273 *product_number = ((uint32_t)buf[0] << 24) + ((uint32_t)buf[1] << 16) +
274 ((uint32_t)buf[2] << 8) + (uint32_t)buf[3];
277 for (
size_t i = 0; i < 8; ++i) {
278 (*serial_number)[i] = buf[i + 4];
287 int16_t* flow_offset, uint16_t* unit) {
289 uint16_t measurement_cmd_word = (uint16_t)measurement_cmd;
294 &measurement_cmd_word, 1);
305 *flow_scale = (int16_t)buf[0];
308 *flow_offset = (int16_t)buf[1];
317 int16_t flow_raw,
float* flow) {
329 return temperature_raw / 200.0f;
336 sfm_config, measurement_cmd, &sfm_config->
flow_scale,
347 int16_t* temperature_raw,
349 uint16_t buf[3] = {};
355 *flow_raw = (int16_t)buf[0];
357 if (temperature_raw) {
358 *temperature_raw = (int16_t)buf[1];
401 if (driver_version) {
420 uint32_t timeout = millis();
423 if (millis() - timeout > 1000)
425 hwi->__delay_blocking_ms(10);
428 uint32_t product_number = 0;
429 uint8_t serial_number[8] = {};
431 &product_number, &serial_number);
438 for (
size_t i = 0; i < 8; ++i) {
443 hwi->__delay_blocking_ms(1000);
454 hwi->__delay_blocking_ms(100);
464 int16_t temperature_raw;
470 &temperature_raw, &status);