Modified scd4x to function as a standalone lib

This commit is contained in:
Jan Mrna 2022-06-17 08:58:22 +02:00
parent 0b57fc0a3c
commit 3d2833d2cd
2 changed files with 42 additions and 40 deletions

78
scd4x.c
View File

@ -6,7 +6,25 @@
*/ */
#include "scd4x.h" #include "scd4x.h"
#include "main.h" /* for uart_disable_interrupts() */
/*
* Functions to be implemented by user
*/
/* I2C */
int8_t scd4x_i2c_transmit(uint8_t address, uint8_t *buffer, int len) __attribute__((weak));
int8_t scd4x_i2c_receive(uint8_t address, uint8_t *buffer, int len) __attribute__((weak));
/* CRC */
uint8_t sensirion_crc8_calculate(const uint8_t *data, uint16_t count) __attribute__((weak));
/* Interrupts */
int8_t scd4x_disable_interrupts(void) __attribute__((weak));
int8_t scd4x_enable_interrupts(void) __attribute__((weak));
/* delay function */
void delay_ms(int delay_ms) __attribute__((weak));
/*
* Public functions
*/
int8_t scd4x_send_cmd(scd4x_cmd_t cmd) int8_t scd4x_send_cmd(scd4x_cmd_t cmd)
{ {
@ -16,8 +34,10 @@ int8_t scd4x_send_cmd(scd4x_cmd_t cmd)
// start measurement // start measurement
buffer[0] = cmd >> 8; buffer[0] = cmd >> 8;
buffer[1] = cmd & 0x00ff; buffer[1] = cmd & 0x00ff;
result = i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2); scd4x_disable_interrupts();
if (result == I2C_ERROR_TX_INCOMPLETE) { result = scd4x_i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2);
scd4x_enable_interrupts();
if (result != 0) {
return SCD4X_ERROR; return SCD4X_ERROR;
} }
@ -31,8 +51,10 @@ int8_t scd4x_get_serial(uint8_t serial[6])
int result; int result;
scd4x_send_cmd(SCD4X_GET_SERIAL_NUMBER); scd4x_send_cmd(SCD4X_GET_SERIAL_NUMBER);
result = i2c_receive(SCD4X_I2C_ADDRESS << 1, buffer, 9); scd4x_disable_interrupts();
if (result != I2C_OK) { result = scd4x_i2c_receive(SCD4X_I2C_ADDRESS << 1, buffer, 9);
scd4x_enable_interrupts();
if (result != 0) {
return SCD4X_ERROR; return SCD4X_ERROR;
} }
return SCD4X_OK; return SCD4X_OK;
@ -63,38 +85,22 @@ int8_t scd4x_read_measurement(uint16_t *co2, int16_t *temperature, uint16_t *rel
uint8_t buffer[32]; uint8_t buffer[32];
int result; int result;
// start measurement /* 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[0] = SCD4X_READ_MEASUREMENT >> 8;
buffer[1] = SCD4X_READ_MEASUREMENT & 0x00ff; buffer[1] = SCD4X_READ_MEASUREMENT & 0x00ff;
// disable interrupts to prevent MODBUS/I2C conflict /* disable interrupts to prevent MODBUS/I2C conflict */
uart_disable_interrupts(); scd4x_disable_interrupts();
result = i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2); result = scd4x_i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2);
uart_enable_interrupts(); scd4x_enable_interrupts();
if (result != I2C_OK) { if (result != 0) {
return SCD4X_ERROR; return SCD4X_ERROR;
} }
LL_mDelay(1); // 10 ms should be enough delay_ms(1);
// read out /* read out */
uart_disable_interrupts(); scd4x_disable_interrupts();
result = i2c_receive(SCD4X_I2C_ADDRESS<<1, buffer, 9); result = scd4x_i2c_receive(SCD4X_I2C_ADDRESS<<1, buffer, 9);
uart_enable_interrupts(); scd4x_enable_interrupts();
if (result != I2C_OK) if (result != 0)
{ {
return SCD4X_ERROR; return SCD4X_ERROR;
} }
@ -106,9 +112,9 @@ int8_t scd4x_read_measurement(uint16_t *co2, int16_t *temperature, uint16_t *rel
uint32_t rh_ticks = (buffer[6] << 8) + buffer[7]; uint32_t rh_ticks = (buffer[6] << 8) + buffer[7];
uint8_t rh_crc = buffer[8]; uint8_t rh_crc = buffer[8];
/* check CRC-8 checksum */ /* check CRC-8 checksum */
uint8_t crc_correct = crc8_calculate(buffer, 2) == co2_crc; uint8_t crc_correct = sensirion_crc8_calculate(buffer, 2) == co2_crc;
crc_correct &= crc8_calculate(buffer + 3, 2) == t_crc; crc_correct &= sensirion_crc8_calculate(buffer + 3, 2) == t_crc;
crc_correct &= crc8_calculate(buffer + 6, 2) == rh_crc; crc_correct &= sensirion_crc8_calculate(buffer + 6, 2) == rh_crc;
if (!crc_correct) { if (!crc_correct) {
return SCD4X_CRC8_ERROR; return SCD4X_CRC8_ERROR;
} }

View File

@ -9,10 +9,6 @@
#define INC_SCD4X_H_ #define INC_SCD4X_H_
#include "stdint.h" #include "stdint.h"
#include "stm32l0xx_ll_i2c.h"
#include "stm32l0xx_ll_utils.h"
#include "i2c.h"
#include "crc8.h"
/* /*
* Defines & macros * Defines & macros