Added sgp40 lib
This commit is contained in:
parent
8c1421dd84
commit
567525cdf8
@ -32,6 +32,7 @@
|
|||||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths.1572529382" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths" valueType="includePath">
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths.1572529382" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths" valueType="includePath">
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sht4x}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sht4x}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/crc8}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/crc8}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sgp40}""/>
|
||||||
</option>
|
</option>
|
||||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.366934534" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
|
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.366934534" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
|
||||||
</tool>
|
</tool>
|
||||||
@ -61,6 +62,7 @@
|
|||||||
<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
|
<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sht4x}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sht4x}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/crc8}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/crc8}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sgp40}""/>
|
||||||
</option>
|
</option>
|
||||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1544503170" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
|
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1544503170" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
|
||||||
</tool>
|
</tool>
|
||||||
@ -90,6 +92,7 @@
|
|||||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="Libs/crc8"/>
|
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="Libs/crc8"/>
|
||||||
|
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="Libs/sgp40"/>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="Libs/sht4x"/>
|
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="Libs/sht4x"/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -124,6 +127,7 @@
|
|||||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths.700537390" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths" valueType="includePath">
|
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths.700537390" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.includepaths" valueType="includePath">
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sht4x}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sht4x}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/crc8}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/crc8}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sgp40}""/>
|
||||||
</option>
|
</option>
|
||||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.1707174983" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
|
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.1707174983" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
|
||||||
</tool>
|
</tool>
|
||||||
@ -152,6 +156,7 @@
|
|||||||
<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
|
<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sht4x}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sht4x}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/crc8}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/crc8}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Libs/sgp40}""/>
|
||||||
</option>
|
</option>
|
||||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1160143889" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
|
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1160143889" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
|
||||||
</tool>
|
</tool>
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* sgp4x.h
|
|
||||||
*
|
|
||||||
* Created on: Jan 9, 2022
|
|
||||||
* Author: david
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INC_SGP40_H_
|
|
||||||
#define INC_SGP40_H_
|
|
||||||
|
|
||||||
|
|
||||||
#include "stdint.h"
|
|
||||||
#include "stm32l0xx_ll_i2c.h"
|
|
||||||
#include "stm32l0xx_ll_utils.h"
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "crc8.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Defines & macros
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SGP40_I2C_ADDRESS 0x59
|
|
||||||
#define SGP40_MAX_MEAS_DURATION_MS 50
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return values
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SGP40_OK 0
|
|
||||||
#define SGP40_ERROR -1 // generic error
|
|
||||||
#define SGP40_CRC8_ERROR -2 // checksum failed
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
SGP40_MEASURE_RAW_SIGNAL = 0x260F,
|
|
||||||
SGP40_EXECUTE_SELF_TEST = 0x280E,
|
|
||||||
SGP40_TURN_HEATER_OFF = 0x3615,
|
|
||||||
SGP40_GET_SERIAL_NUMBER = 0x3682,
|
|
||||||
SGP40_SOFT_RESET = 0x0006
|
|
||||||
} sgp40_cmd_t;
|
|
||||||
|
|
||||||
int8_t sgp40_send_cmd(sgp40_cmd_t cmd);
|
|
||||||
|
|
||||||
int8_t sgp40_measure_raw_signal (uint16_t * voc_ticks);
|
|
||||||
int8_t sgp40_measure_raw_signal_compensated (uint16_t * voc_ticks, uint16_t relative_humidity, int16_t temperature);
|
|
||||||
int8_t sgp40_execute_self_test ( uint8_t * test_result);
|
|
||||||
int8_t sgp40_get_serial_number ( uint8_t serial[6]);
|
|
||||||
int8_t sgp40_turn_heater_off ( void );
|
|
||||||
int8_t sgp40_soft_reset ( void );
|
|
||||||
|
|
||||||
#endif /* INC_SGP40_H_ */
|
|
@ -198,6 +198,26 @@ int8_t sht4x_enable_interrupts(void)
|
|||||||
uart_enable_interrupts();
|
uart_enable_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t sgp40_i2c_transmit(uint8_t address, uint8_t *buffer, int len)
|
||||||
|
{
|
||||||
|
i2c_transmit(address, buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t sgp40_i2c_receive(uint8_t address, uint8_t *buffer, int len)
|
||||||
|
{
|
||||||
|
i2c_receive(address, buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t sgp40_disable_interrupts(void)
|
||||||
|
{
|
||||||
|
uart_disable_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t sgp40_enable_interrupts(void)
|
||||||
|
{
|
||||||
|
uart_enable_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
void delay_ms(int delay_ms)
|
void delay_ms(int delay_ms)
|
||||||
{
|
{
|
||||||
LL_mDelay(delay_ms);
|
LL_mDelay(delay_ms);
|
||||||
|
@ -1,186 +0,0 @@
|
|||||||
/*
|
|
||||||
* SGP40.c
|
|
||||||
*
|
|
||||||
* Created on: Jan 9, 2022
|
|
||||||
* Author: david
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sgp40.h>
|
|
||||||
#include "main.h" /* for uart_disable_interrupts() */
|
|
||||||
|
|
||||||
int8_t sgp40_send_cmd(sgp40_cmd_t cmd)
|
|
||||||
{
|
|
||||||
uint8_t buffer[32];
|
|
||||||
int result;
|
|
||||||
|
|
||||||
// start measurement
|
|
||||||
buffer[0] = cmd >> 8;
|
|
||||||
buffer[1] = cmd & 0x00ff;
|
|
||||||
uart_disable_interrupts();
|
|
||||||
result = i2c_transmit(SGP40_I2C_ADDRESS<<1, buffer, 2);
|
|
||||||
uart_enable_interrupts();
|
|
||||||
if (result == I2C_ERROR_TX_INCOMPLETE) {
|
|
||||||
return SGP40_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sensirion sensors return NACK after last byte (so NACK at the end is ok) */
|
|
||||||
return SGP40_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t sgp40_measure_raw_signal(uint16_t * voc_ticks)
|
|
||||||
{
|
|
||||||
uint8_t buffer[32];
|
|
||||||
int result;
|
|
||||||
|
|
||||||
/* Start measurement */
|
|
||||||
buffer[0] = 0x26;
|
|
||||||
buffer[1] = 0x0F;
|
|
||||||
buffer[2] = 0x80;
|
|
||||||
buffer[3] = 0x00;
|
|
||||||
buffer[4] = 0xA2;
|
|
||||||
buffer[5] = 0x66;
|
|
||||||
buffer[6] = 0x66;
|
|
||||||
buffer[7] = 0x93;
|
|
||||||
|
|
||||||
/* Returns NACK if CRC is wrong */
|
|
||||||
uart_disable_interrupts();
|
|
||||||
result = i2c_transmit(SGP40_I2C_ADDRESS<<1, buffer, 8);
|
|
||||||
uart_enable_interrupts();
|
|
||||||
if (result != I2C_OK) {
|
|
||||||
return SGP40_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
LL_mDelay(SGP40_MAX_MEAS_DURATION_MS); // 30ms
|
|
||||||
|
|
||||||
uart_disable_interrupts();
|
|
||||||
result = i2c_receive(SGP40_I2C_ADDRESS<<1, buffer, 3);
|
|
||||||
uart_enable_interrupts();
|
|
||||||
if (result != I2C_OK)
|
|
||||||
{
|
|
||||||
return SGP40_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
*voc_ticks = (buffer[0] << 8) + buffer[1];
|
|
||||||
uint8_t voc_ticks_crc = buffer[2];
|
|
||||||
uint8_t crc_correct = crc8_calculate(buffer, 2) == voc_ticks_crc;
|
|
||||||
if (!crc_correct) {
|
|
||||||
return SGP40_CRC8_ERROR;
|
|
||||||
}
|
|
||||||
return SGP40_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t sgp40_measure_raw_signal_compensated(uint16_t * voc_ticks, uint16_t relative_humidity, int16_t temperature)
|
|
||||||
{
|
|
||||||
uint8_t buffer[32];
|
|
||||||
int result;
|
|
||||||
|
|
||||||
uint16_t rh_ticks = (uint16_t)((uint32_t)relative_humidity * 65535 / 100);
|
|
||||||
uint16_t t_ticks = (uint16_t)(((uint32_t)temperature/10 + 45) * 65535 / 175);
|
|
||||||
|
|
||||||
buffer[0] = SGP40_MEASURE_RAW_SIGNAL >> 8;
|
|
||||||
buffer[1] = SGP40_MEASURE_RAW_SIGNAL & 0x00ff;
|
|
||||||
buffer[2] = (uint8_t)(rh_ticks >> 8);
|
|
||||||
buffer[3] = (uint8_t)rh_ticks;
|
|
||||||
buffer[4] = crc8_calculate(buffer+2, 2);
|
|
||||||
buffer[5] = (uint8_t)(t_ticks >> 8);
|
|
||||||
buffer[6] = (uint8_t)t_ticks;
|
|
||||||
buffer[7] = crc8_calculate(buffer+5, 2);
|
|
||||||
|
|
||||||
/* Returns NACK if CRC is wrong */
|
|
||||||
uart_disable_interrupts();
|
|
||||||
result = i2c_transmit(SGP40_I2C_ADDRESS<<1, buffer, 8);
|
|
||||||
uart_enable_interrupts();
|
|
||||||
if (result != I2C_OK) {
|
|
||||||
return SGP40_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
LL_mDelay(SGP40_MAX_MEAS_DURATION_MS); // 30ms
|
|
||||||
|
|
||||||
uart_disable_interrupts();
|
|
||||||
result = i2c_receive(SGP40_I2C_ADDRESS<<1, buffer, 3);
|
|
||||||
uart_enable_interrupts();
|
|
||||||
if (result != I2C_OK)
|
|
||||||
{
|
|
||||||
return SGP40_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
*voc_ticks = (buffer[0] << 8) + buffer[1];
|
|
||||||
uint8_t voc_ticks_crc = buffer[2];
|
|
||||||
uint8_t crc_correct = crc8_calculate(buffer, 2) == voc_ticks_crc;
|
|
||||||
if (!crc_correct) {
|
|
||||||
return SGP40_CRC8_ERROR;
|
|
||||||
}
|
|
||||||
return SGP40_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t SGP40_execute_self_test ( uint8_t * test_result)
|
|
||||||
{
|
|
||||||
uint8_t buffer[16];
|
|
||||||
int8_t result;
|
|
||||||
|
|
||||||
result = sgp40_send_cmd(SGP40_EXECUTE_SELF_TEST);
|
|
||||||
if (result != I2C_OK) {
|
|
||||||
return SGP40_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
LL_mDelay(350);
|
|
||||||
|
|
||||||
uart_disable_interrupts();
|
|
||||||
result = i2c_receive(SGP40_I2C_ADDRESS << 1, buffer, 3);
|
|
||||||
uart_enable_interrupts();
|
|
||||||
if (result != I2C_OK) {
|
|
||||||
return SGP40_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_result = buffer[0];
|
|
||||||
uint8_t test_result_crc = buffer[2];
|
|
||||||
|
|
||||||
uint8_t crc_correct = crc8_calculate(buffer, 2) == test_result_crc;
|
|
||||||
if (!crc_correct) {
|
|
||||||
return SGP40_CRC8_ERROR;
|
|
||||||
}
|
|
||||||
return SGP40_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t SGP40_get_serial_number(uint8_t serial[6])
|
|
||||||
{
|
|
||||||
uint8_t buffer[16];
|
|
||||||
|
|
||||||
uart_disable_interrupts();
|
|
||||||
sgp40_send_cmd(SGP40_GET_SERIAL_NUMBER);
|
|
||||||
uart_enable_interrupts();
|
|
||||||
|
|
||||||
LL_mDelay(5);
|
|
||||||
|
|
||||||
uart_disable_interrupts();
|
|
||||||
i2c_receive(SGP40_I2C_ADDRESS << 1, buffer, 9);
|
|
||||||
uart_enable_interrupts();
|
|
||||||
|
|
||||||
serial[0] = buffer[0];
|
|
||||||
serial[1] = buffer[1];
|
|
||||||
uint8_t crc_ser01 = buffer[3];
|
|
||||||
serial[2] = buffer[4];
|
|
||||||
serial[3] = buffer[5];
|
|
||||||
uint8_t crc_ser23 = buffer[6];
|
|
||||||
serial[4] = buffer[7];
|
|
||||||
serial[5] = buffer[8];
|
|
||||||
uint8_t crc_ser45 = buffer[9];
|
|
||||||
|
|
||||||
uint8_t crc_correct = crc8_calculate(buffer, 2) == crc_ser01;
|
|
||||||
crc_correct &= crc8_calculate(buffer + 3, 2) == crc_ser23;
|
|
||||||
crc_correct &= crc8_calculate(buffer + 6, 2) == crc_ser45;
|
|
||||||
if (!crc_correct) {
|
|
||||||
return SGP40_CRC8_ERROR;
|
|
||||||
}
|
|
||||||
return SGP40_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t SGP40_turn_heater_off(void)
|
|
||||||
{
|
|
||||||
return sgp40_send_cmd(SGP40_TURN_HEATER_OFF);
|
|
||||||
}
|
|
||||||
int8_t SGP40_soft_reset(void)
|
|
||||||
{
|
|
||||||
return sgp40_send_cmd(SGP40_SOFT_RESET);
|
|
||||||
}
|
|
@ -1 +1 @@
|
|||||||
Subproject commit a0ed61200d27028b93251ef5f8d4d04f96860c4f
|
Subproject commit cd15bbfa2496a10240519b4a6cd13bee875fd130
|
Loading…
Reference in New Issue
Block a user