21#define SCD41_ADDR (0x62 << 1)
24#define SCD41_CMD_START_PERIODIC 0x21b1
25#define SCD41_CMD_START_LOW_POWER_PERIODIC 0x21ac
26#define SCD41_CMD_START_SINGLE_SHOT 0x219D
28#define SCD41_CMD_START SCD41_CMD_START_PERIODIC
32#define SCD41_CMD_STOP_PERIODIC 0x3f86
33#define SCD41_CMD_SET_ALTITUDE 0x2427
34#define SCD41_CMD_READ_MEAS 0xec05
35#define SCD41_CMD_GET_DATA_READY 0xe4b8
36#define SCD41_CMD_REINIT 0x3646
39scd41_t _scd41Data = {};
40scd41_t _bck_scd41Data = {};
42static int8_t _isScd41 = 0;
45static HAL_StatusTypeDef scd41_WriteWithCRC(I2C_HandleTypeDef *hi2c, uint16_t cmd, uint16_t val)
48 tx[0] = (uint8_t) (cmd >> 8);
49 tx[1] = (uint8_t) (cmd & 0xFF);
50 tx[2] = (uint8_t) (val >> 8);
51 tx[3] = (uint8_t) (val & 0xFF);
53 return HAL_I2C_Master_Transmit(hi2c, SCD41_ADDR, tx, 5, 100);
56static HAL_StatusTypeDef scd41_onOff(I2C_HandleTypeDef *hi2c, uint16_t onOff)
58 HAL_StatusTypeDef status = HAL_ERROR;
61 cmd[0] = (onOff >> 8);
62 cmd[1] = (onOff & 0xFF);
63 status = HAL_I2C_Master_Transmit(hi2c, SCD41_ADDR, cmd, 2, HAL_MAX_DELAY);
66 _isScd41 = (status == HAL_OK);
70int8_t scd41_Is(I2C_HandleTypeDef *hi2c, int8_t tryInit)
72 if (!_isScd41 && tryInit)
77HAL_StatusTypeDef scd41_On(I2C_HandleTypeDef *hi2c)
79 HAL_StatusTypeDef status = HAL_ERROR;
83 status = scd41_onOff(hi2c, SCD41_CMD_START);
84 _scd41Data.IsDataValid = 0;
94HAL_StatusTypeDef scd41_Off(I2C_HandleTypeDef *hi2c)
96 return scd41_onOff(hi2c, SCD41_CMD_STOP_PERIODIC);
99HAL_StatusTypeDef scd41_Init(I2C_HandleTypeDef *hi2c)
111 cmd[0] = (SCD41_CMD_REINIT >> 8);
112 cmd[1] = (SCD41_CMD_REINIT & 0xFF);
113 if ((ret = HAL_I2C_Master_Transmit(hi2c, SCD41_ADDR, cmd, 2, HAL_MAX_DELAY)) != HAL_OK)
119 if ((ret = scd41_WriteWithCRC(hi2c, SCD41_CMD_SET_ALTITUDE,
_systemParams.SensAltitude)) != HAL_OK)
135 _isScd41 = (ret==HAL_OK);
143HAL_StatusTypeDef scd41_IsDataReady(I2C_HandleTypeDef *hi2c)
145 HAL_StatusTypeDef status = HAL_ERROR;
150 { (SCD41_CMD_GET_DATA_READY >> 8), (SCD41_CMD_GET_DATA_READY & 0xFF) };
157 if ((status = HAL_I2C_Master_Transmit(hi2c, SCD41_ADDR, cmd, 2, 100)) != HAL_OK)
162 if ((status = HAL_I2C_Master_Receive(hi2c, SCD41_ADDR, buf, 3, 100)) != HAL_OK)
182 status = ((dataReady & 0x07FF) != 0) ? HAL_OK : HAL_BUSY;
190HAL_StatusTypeDef scd41_Read(I2C_HandleTypeDef *hi2c)
192 HAL_StatusTypeDef status = scd41_IsDataReady(hi2c);
194 if (status == HAL_OK)
197 { (SCD41_CMD_READ_MEAS >> 8), (SCD41_CMD_READ_MEAS & 0xFF) };
203 if ((status = HAL_I2C_Master_Transmit(hi2c, SCD41_ADDR, cmd, 2, HAL_MAX_DELAY)) != HAL_OK)
207 if ((status = HAL_I2C_Master_Receive(hi2c, SCD41_ADDR, buf, 9, HAL_MAX_DELAY)) != HAL_OK)
219 _scd41Data.Co2 = (float) ((uint16_t) ((buf[0] << 8) | buf[1]));
220 _scd41Data.Temperature = -45.0f + 175.0f * (float) ((buf[3] << 8) | buf[4]) / 65536.0f;
221 _scd41Data.Humidity = 100.0f * (float) ((buf[6] << 8) | buf[7]) / 65536.0f;
222 _scd41Data.IsDataValid = 1;
228void scd41_LogData(
char *buf)
231 sprintf(buf,
"|scd41 co2:%d temp:" PRIf_02 " hum:" PRIf_02 " ", (
int) _scd41Data.Co2,
PRIf_02D(_scd41Data.Temperature),
PRIf_02D(_scd41Data.Humidity));
This file contains all the function prototypes for the i2c.c file.
HAL_StatusTypeDef I2C_IsDeviceReadyMT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
Wrapper around HAL_I2C_IsDeviceReady() that recovers from a busy bus. If the HAL I2C bus is in a BUSY...
#define PRIf_02D(fData)
Expands to integer and fractional arguments for use with PRIf_02. Splits a float/double into the inte...
#define PRIf_02
printf format string for printing a float/double as integer with 2 decimal places....
mems_MainBlock_t _memsMainBlock
Global instance of the main flash control block; loaded by mems_ReadMainBlock().
HAL_StatusTypeDef mems_WriteMainBlock()
writing the main block on flash. The main block is stored on address 0
systemParams_t _systemParams
void HAL_Delay(__IO uint32_t Delay)
uint8_t calculateCrc(uint8_t *data, uint8_t len)
Calculate a CRC-8 checksum (Sensirion polynomial) over a byte buffer. Used to validate sensor I2C res...