Merge sht4x_minimal
This commit is contained in:
22
fw/Core/Inc/crc8.h
Normal file
22
fw/Core/Inc/crc8.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* crc.h
|
||||
*
|
||||
* Created on: Jun 9, 2021
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#ifndef INC_CRC8_H_
|
||||
#define INC_CRC8_H_
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
/*
|
||||
* Definitions & macros
|
||||
*/
|
||||
|
||||
#define CRC8_POLYNOMIAL 0x31
|
||||
#define CRC8_INIT 0xFF
|
||||
|
||||
uint8_t crc8_calculate(const uint8_t *data, uint16_t count);
|
||||
|
||||
#endif /* INC_CRC8_H_ */
|
||||
46
fw/Core/Inc/i2c.h
Normal file
46
fw/Core/Inc/i2c.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* i2c.h
|
||||
*
|
||||
* Created on: Jun 8, 2021
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#ifndef INC_I2C_H_
|
||||
#define INC_I2C_H_
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stm32l0xx_ll_i2c.h"
|
||||
|
||||
/*
|
||||
* Defines & macros
|
||||
*/
|
||||
|
||||
#define NULL 0
|
||||
|
||||
/*
|
||||
* Return values for I2C functions
|
||||
*/
|
||||
|
||||
#define I2C_OK 0
|
||||
#define I2C_ERROR -1 // generic error
|
||||
#define I2C_ERROR_NACK -2 // NACK was received during transfer
|
||||
#define I2C_ERROR_TX_INCOMPLETE -3 // number of TXed bytes != buffer length
|
||||
#define I2C_ERROR_RX_INCOMPLETE -4 // number of RXed bytes != buffer length
|
||||
|
||||
/*
|
||||
* Type definitions
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
I2C_TypeDef *i2c;
|
||||
} i2c_context_t;
|
||||
|
||||
/*
|
||||
* Function declarations
|
||||
*/
|
||||
|
||||
int i2c_init(i2c_context_t *context);
|
||||
int i2c_transmit(uint8_t address, uint8_t *buffer, int len);
|
||||
int i2c_receive(uint8_t address, uint8_t *buffer, int len);
|
||||
|
||||
#endif /* INC_I2C_H_ */
|
||||
@@ -48,6 +48,8 @@ extern "C" {
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "i2c.h"
|
||||
#include "sht4x.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
57
fw/Core/Inc/sht4x.h
Normal file
57
fw/Core/Inc/sht4x.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* sht4x.h
|
||||
*
|
||||
* Created on: Jun 8, 2021
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#ifndef INC_SHT4X_H_
|
||||
#define INC_SHT4X_H_
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stm32l0xx_ll_i2c.h"
|
||||
#include "stm32l0xx_ll_utils.h"
|
||||
#include "i2c.h"
|
||||
#include "crc8.h"
|
||||
|
||||
/*
|
||||
* Defines & macros
|
||||
*/
|
||||
|
||||
#define SHT4X_I2C_ADDRESS 0x44
|
||||
|
||||
/*
|
||||
* Return values
|
||||
*/
|
||||
|
||||
#define SHT4X_OK 0
|
||||
#define SHT4X_ERROR -1 // generic error
|
||||
#define SHT4X_CRC8_ERROR -2 // checksum failed
|
||||
|
||||
/*
|
||||
* Data types
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
START_MEAS_HIGH_PRECISION = 0xFD,
|
||||
START_MEAS_MEDIUM_PRECISION = 0xF6,
|
||||
START_MEAS_LOW_PRECISION = 0xE0,
|
||||
READ_SERIAL = 0x89,
|
||||
SOFT_RESET = 0x94,
|
||||
HEATER_200_mW_1_s = 0x39,
|
||||
HEATER_200_mW_01_s = 0x32,
|
||||
HEATER_110_mW_1_s = 0x2F,
|
||||
HEATER_110_mW_01_s = 0x24,
|
||||
HEATER_20_mW_1_s = 0x1E,
|
||||
HEATER_20_mW_01_s = 0x15
|
||||
} sht4x_cmd_t;
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
|
||||
int8_t sht4x_send_cmd(sht4x_cmd_t cmd);
|
||||
int8_t sht4x_read_data(uint8_t *buffer, int len);
|
||||
int8_t sht4x_measure(int *temperature, int *relative_humidity);
|
||||
|
||||
#endif /* INC_SHT4X_H_ */
|
||||
28
fw/Core/Src/crc8.c
Normal file
28
fw/Core/Src/crc8.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* crc.c
|
||||
*
|
||||
* Created on: Jun 9, 2021
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#include "crc8.h"
|
||||
|
||||
/* Stolen from Sensirion SCD4x datasheet, section 3.11 */
|
||||
uint8_t crc8_calculate(const uint8_t *data, uint16_t count)
|
||||
{
|
||||
uint16_t current_byte;
|
||||
uint8_t crc = CRC8_INIT;
|
||||
uint8_t crc_bit;
|
||||
/* calculates 8-Bit checksum with given polynomial */
|
||||
for (current_byte = 0; current_byte < count; ++current_byte) {
|
||||
crc ^= (data[current_byte]);
|
||||
for(crc_bit = 8; crc_bit > 0; --crc_bit) {
|
||||
if (crc & 0x80) {
|
||||
crc =(crc << 1) ^ CRC8_POLYNOMIAL;
|
||||
} else {
|
||||
crc = (crc << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
64
fw/Core/Src/i2c.c
Normal file
64
fw/Core/Src/i2c.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* i2c.c
|
||||
*
|
||||
* Created on: Jun 8, 2021
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
i2c_context_t *i2c_context;
|
||||
|
||||
int i2c_init(i2c_context_t *context)
|
||||
{
|
||||
if (context == NULL) {
|
||||
return I2C_ERROR;
|
||||
}
|
||||
i2c_context = context;
|
||||
return I2C_OK;
|
||||
}
|
||||
|
||||
int i2c_transmit(uint8_t address, uint8_t *buffer, int len)
|
||||
{
|
||||
LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len,
|
||||
LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
|
||||
int i = 0;
|
||||
// Autoend mode will raise STOP flag if NACK is detected
|
||||
// (or if desired number of bytes is transmitted)
|
||||
while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
|
||||
if (LL_I2C_IsActiveFlag_TXE(i2c_context->i2c)) {
|
||||
if (i < len) {
|
||||
LL_I2C_TransmitData8(i2c_context->i2c, buffer[i++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_I2C_ClearFlag_STOP(i2c_context->i2c);
|
||||
if (LL_I2C_IsActiveFlag_NACK(i2c_context->i2c)) {
|
||||
return I2C_ERROR_NACK;
|
||||
}
|
||||
if (len != i) {
|
||||
// this will probably never happen, as NACK flag
|
||||
// is raised everytime len != number of TXed bytes
|
||||
return I2C_ERROR_TX_INCOMPLETE;
|
||||
}
|
||||
return I2C_OK;
|
||||
}
|
||||
|
||||
int i2c_receive(uint8_t address, uint8_t *buffer, int len)
|
||||
{
|
||||
LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len,
|
||||
LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
|
||||
int i = 0;
|
||||
while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
|
||||
if (LL_I2C_IsActiveFlag_RXNE(i2c_context->i2c)) {
|
||||
if (i < len) {
|
||||
buffer[i++] = LL_I2C_ReceiveData8(i2c_context->i2c);
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_I2C_ClearFlag_STOP(i2c_context->i2c);
|
||||
if (len != i) {
|
||||
return I2C_ERROR_RX_INCOMPLETE;
|
||||
}
|
||||
return I2C_OK; // TODO error detection
|
||||
}
|
||||
@@ -98,7 +98,10 @@ int main(void)
|
||||
/* USER CODE BEGIN 2 */
|
||||
LL_I2C_Enable(I2C1);
|
||||
LL_LPUART_Enable(LPUART1);
|
||||
/* LED PWM context */
|
||||
/* I2C context init (for SHT4x and SCD4x) */
|
||||
i2c_context_t i2c_context;
|
||||
i2c_context.i2c = I2C1;
|
||||
i2c_init(&i2c_context);
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
@@ -107,13 +110,17 @@ int main(void)
|
||||
uint8_t uart_data_dummy = 0;
|
||||
while (1)
|
||||
{
|
||||
/* RS485 test */
|
||||
LL_LPUART_SetDESignalPolarity(LPUART1, 1);
|
||||
LL_LPUART_TransmitData8(LPUART1, uart_data_dummy);
|
||||
uart_data_dummy++;
|
||||
|
||||
/* SHT41 measurement */
|
||||
int T, RH;
|
||||
sht4x_measure(&T, &RH);
|
||||
|
||||
LL_mDelay(1000);
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
@@ -216,7 +223,6 @@ static void MX_I2C1_Init(void)
|
||||
LL_I2C_Init(I2C1, &I2C_InitStruct);
|
||||
LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
|
||||
/* USER CODE BEGIN I2C1_Init 2 */
|
||||
|
||||
/* USER CODE END I2C1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
53
fw/Core/Src/sht4x.c
Normal file
53
fw/Core/Src/sht4x.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* sht4x.c
|
||||
*
|
||||
* Created on: Jun 8, 2021
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#include "sht4x.h"
|
||||
|
||||
int8_t sht4x_send_cmd(sht4x_cmd_t cmd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int8_t sht4x_read_data(uint8_t *buffer, int len)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int8_t sht4x_measure(int *temperature, int *relative_humidity)
|
||||
{
|
||||
uint8_t buffer[32];
|
||||
int result;
|
||||
|
||||
// start measurement
|
||||
buffer[0] = START_MEAS_HIGH_PRECISION;
|
||||
result = i2c_transmit(SHT4X_I2C_ADDRESS<<1, buffer, 1);
|
||||
if (result != I2C_OK) {
|
||||
return SHT4X_ERROR;
|
||||
}
|
||||
LL_mDelay(100); // 10 ms should be enough
|
||||
// read out
|
||||
result = i2c_receive(SHT4X_I2C_ADDRESS<<1, buffer, 6);
|
||||
if (result != I2C_OK) {
|
||||
return SHT4X_ERROR;
|
||||
}
|
||||
// TODO checksum
|
||||
// Convert to T and RH; taken directly from pseudocode in SHT4x datasheet, page 3
|
||||
uint32_t t_ticks = (buffer[0] << 8) + buffer[1];
|
||||
uint32_t rh_ticks = (buffer[3] << 8) + buffer[4];
|
||||
int t_degC = -45 + 175 * t_ticks / 65535;
|
||||
int rh_pRH = -6 + 125 * rh_ticks / 65535;
|
||||
if (rh_pRH > 100) {
|
||||
rh_pRH = 100;
|
||||
}
|
||||
if (rh_pRH < 0) {
|
||||
rh_pRH = 0;
|
||||
}
|
||||
*temperature = t_degC;
|
||||
*relative_humidity = rh_pRH;
|
||||
|
||||
return SHT4X_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user