Added files (not yet modified)

This commit is contained in:
Jan Mrna 2022-06-12 22:49:01 +02:00
commit 0b57fc0a3c
2 changed files with 187 additions and 0 deletions

129
scd4x.c Normal file
View File

@ -0,0 +1,129 @@
/*
* sht4x.c
*
* Created on: Jun 8, 2021
* Author: user
*/
#include "scd4x.h"
#include "main.h" /* for uart_disable_interrupts() */
int8_t scd4x_send_cmd(scd4x_cmd_t cmd)
{
uint8_t buffer[32];
int result;
// start measurement
buffer[0] = cmd >> 8;
buffer[1] = cmd & 0x00ff;
result = i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2);
if (result == I2C_ERROR_TX_INCOMPLETE) {
return SCD4X_ERROR;
}
/* Sensirion sensors return NACK after last byte (so NACK at the end is ok) */
return SCD4X_OK;
}
int8_t scd4x_get_serial(uint8_t serial[6])
{
uint8_t buffer[16];
int result;
scd4x_send_cmd(SCD4X_GET_SERIAL_NUMBER);
result = i2c_receive(SCD4X_I2C_ADDRESS << 1, buffer, 9);
if (result != I2C_OK) {
return SCD4X_ERROR;
}
return SCD4X_OK;
}
int8_t scd4x_read_data(uint8_t *buffer, int len)
{
return SCD4X_OK;
}
int8_t scd4x_start_periodic_measurement( void )
{
return scd4x_send_cmd(SCD4X_START_PERIODIC_MEASUREMENT);
}
int8_t scd4x_stop_periodic_measurement( void )
{
return scd4x_send_cmd(SCD4X_STOP_PERIODIC_MEASUREMENT);
}
int8_t scd4x_perform_factory_reset( void )
{
return scd4x_send_cmd(SCD4X_PERFORM_FACTORY_RESET);
}
int8_t scd4x_read_measurement(uint16_t *co2, int16_t *temperature, uint16_t *relative_humidity)
{
uint8_t buffer[32];
int result;
// start measurement
// TODO: Check for data ready
/*
buffer[0] = GET_DATA_READY_STATUS >> 8;
buffer[1] = GET_DATA_READY_STATUS & 0x00ff;
result = i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2);
if (result != I2C_OK) {
return SCD4X_ERROR;
}
LL_mDelay(100); // 10 ms should be enough
// read out
result = i2c_receive(SCD4X_I2C_ADDRESS<<1, buffer, 6);
if (result != I2C_OK) {
return SCD4X_ERROR;
}*/
// start measurement
buffer[0] = SCD4X_READ_MEASUREMENT >> 8;
buffer[1] = SCD4X_READ_MEASUREMENT & 0x00ff;
// disable interrupts to prevent MODBUS/I2C conflict
uart_disable_interrupts();
result = i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2);
uart_enable_interrupts();
if (result != I2C_OK) {
return SCD4X_ERROR;
}
LL_mDelay(1); // 10 ms should be enough
// read out
uart_disable_interrupts();
result = i2c_receive(SCD4X_I2C_ADDRESS<<1, buffer, 9);
uart_enable_interrupts();
if (result != I2C_OK)
{
return SCD4X_ERROR;
}
/* Convert to T and RH; taken directly from pseudocode in SHT4x datasheet, page 3 */
uint32_t co2_ticks = (buffer[0] << 8) + buffer[1];
uint8_t co2_crc = buffer[2];
uint32_t t_ticks = (buffer[3] << 8) + buffer[4];
uint8_t t_crc = buffer[5];
uint32_t rh_ticks = (buffer[6] << 8) + buffer[7];
uint8_t rh_crc = buffer[8];
/* check CRC-8 checksum */
uint8_t crc_correct = crc8_calculate(buffer, 2) == co2_crc;
crc_correct &= crc8_calculate(buffer + 3, 2) == t_crc;
crc_correct &= crc8_calculate(buffer + 6, 2) == rh_crc;
if (!crc_correct) {
return SCD4X_CRC8_ERROR;
}
/* copy to output variables */
int t_degC = -450 + 10 * 175 * t_ticks / 65535;
int rh_pRH = 100 * rh_ticks / 65535;
if (rh_pRH > 100) {
rh_pRH = 100;
}
if (rh_pRH < 0) {
rh_pRH = 0;
}
*co2 = co2_ticks;
*temperature = t_degC;
*relative_humidity = rh_pRH;
return SCD4X_OK;
}

58
scd4x.h Normal file
View File

@ -0,0 +1,58 @@
/*
* sht4x.h
*
* Created on: Jun 8, 2021
* Author: user
*/
#ifndef INC_SCD4X_H_
#define INC_SCD4X_H_
#include "stdint.h"
#include "stm32l0xx_ll_i2c.h"
#include "stm32l0xx_ll_utils.h"
#include "i2c.h"
#include "crc8.h"
/*
* Defines & macros
*/
#define SCD4X_I2C_ADDRESS 0x62
/*
* Return values
*/
#define SCD4X_OK 0
#define SCD4X_ERROR -1 // generic error
#define SCD4X_CRC8_ERROR -2 // checksum failed
/*
* Data types
*/
typedef enum {
SCD4X_START_PERIODIC_MEASUREMENT = 0x21B1,
SCD4X_READ_MEASUREMENT = 0xEC05,
SCD4X_STOP_PERIODIC_MEASUREMENT = 0x3F86,
SCD4X_GET_DATA_READY_STATUS = 0xE4B8,
SCD4X_PERFORM_FACTORY_RESET = 0x3632,
SCD4X_GET_SERIAL_NUMBER = 0x3682
} scd4x_cmd_t;
/*
* Function prototypes
*/
int8_t scd4x_send_cmd(scd4x_cmd_t cmd);
int8_t scd4x_read_data(uint8_t *buffer, int len);
int8_t scd4x_start_periodic_measurement( void );
int8_t scd4x_stop_periodic_measurement( void );
int8_t scd4x_perform_factory_reset( void );
int8_t scd4x_read_measurement(uint16_t * co2, int16_t *temperature, uint16_t *relative_humidity);
#endif /* INC_SCD4X_H_ */