From 7e48b82c9d1bed06018228362ab8b900aafea28a Mon Sep 17 00:00:00 2001 From: dooku Date: Tue, 8 Jun 2021 19:40:34 +0200 Subject: [PATCH] Moved I2C related functions to i2c.c --- fw/Core/Inc/i2c.h | 44 ++++++++++++++++++++++++++++++++++ fw/Core/Inc/main.h | 1 + fw/Core/Inc/sht4x.h | 13 ++++++---- fw/Core/Src/i2c.c | 55 ++++++++++++++++++++++++++++++++++++++++++ fw/Core/Src/main.c | 8 +++---- fw/Core/Src/sht4x.c | 58 +++++++++++---------------------------------- 6 files changed, 126 insertions(+), 53 deletions(-) create mode 100644 fw/Core/Inc/i2c.h create mode 100644 fw/Core/Src/i2c.c diff --git a/fw/Core/Inc/i2c.h b/fw/Core/Inc/i2c.h new file mode 100644 index 0000000..f655255 --- /dev/null +++ b/fw/Core/Inc/i2c.h @@ -0,0 +1,44 @@ +/* + * 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 + +/* + * 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_ */ diff --git a/fw/Core/Inc/main.h b/fw/Core/Inc/main.h index 94b7091..841662e 100644 --- a/fw/Core/Inc/main.h +++ b/fw/Core/Inc/main.h @@ -49,6 +49,7 @@ extern "C" { /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "led.h" +#include "i2c.h" #include "sht4x.h" /* USER CODE END Includes */ diff --git a/fw/Core/Inc/sht4x.h b/fw/Core/Inc/sht4x.h index a73fd2c..0e133f3 100644 --- a/fw/Core/Inc/sht4x.h +++ b/fw/Core/Inc/sht4x.h @@ -10,6 +10,7 @@ #include "stdint.h" #include "stm32l0xx_ll_i2c.h" +#include "i2c.h" /* * Defines & macros @@ -18,12 +19,15 @@ #define SHT4X_I2C_ADDRESS 0x44 /* - * Data types + * Return values */ -typedef struct { - I2C_TypeDef *i2c; -} sht4x_context_t; +#define SHT4X_OK 0 +#define SHT4X_ERROR -1 // generic error + +/* + * Data types + */ typedef enum { START_MEAS_HIGH_PRECISION = 0xFD, @@ -43,7 +47,6 @@ typedef enum { * Function prototypes */ -int sht4x_init(sht4x_context_t *context); int sht4x_send_cmd(sht4x_cmd_t cmd); int sht4x_read_data(uint8_t *buffer, int len); int sht4x_measure(int *temperature, int *relative_humidity); diff --git a/fw/Core/Src/i2c.c b/fw/Core/Src/i2c.c new file mode 100644 index 0000000..ed52827 --- /dev/null +++ b/fw/Core/Src/i2c.c @@ -0,0 +1,55 @@ +/* + * 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_ADDRESSING_MODE_7BIT, len, + LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); + int i = 0; + 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; + } + return I2C_OK; +} + +int i2c_receive(uint8_t address, uint8_t *buffer, int len) +{ + LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRESSING_MODE_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); + + return I2C_OK; // TODO error detection +} diff --git a/fw/Core/Src/main.c b/fw/Core/Src/main.c index 9227917..6007773 100644 --- a/fw/Core/Src/main.c +++ b/fw/Core/Src/main.c @@ -108,10 +108,10 @@ int main(void) led_context.blue_led_pin = LED_B_Pin; led_init(&led_context, 50, 1000); led_set_color(80, 0, 0); - /* SHT4x context init */ - sht4x_context_t sht4x_context; - sht4x_context.i2c = I2C1; - sht4x_init(&sht4x_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 */ /* Infinite loop */ diff --git a/fw/Core/Src/sht4x.c b/fw/Core/Src/sht4x.c index d6dd018..9f14b54 100644 --- a/fw/Core/Src/sht4x.c +++ b/fw/Core/Src/sht4x.c @@ -7,43 +7,6 @@ #include "sht4x.h" -sht4x_context_t *sht4x_context; - -int sht4x_init(sht4x_context_t *context) -{ - sht4x_context = context; -} - -void i2c_transmit(uint8_t address, uint8_t *buffer, int len) -{ - LL_I2C_HandleTransfer(sht4x_context->i2c, address, LL_I2C_ADDRESSING_MODE_7BIT, len, - LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); - int i = 0; - while (!LL_I2C_IsActiveFlag_STOP(sht4x_context->i2c)) { - if (LL_I2C_IsActiveFlag_TXE(sht4x_context->i2c)) { - if (i < len) { - LL_I2C_TransmitData8(sht4x_context->i2c, buffer[i++]); - } - } - } - LL_I2C_ClearFlag_STOP(sht4x_context->i2c); -} - -void i2c_receive(uint8_t address, uint8_t *buffer, int len) -{ - LL_I2C_HandleTransfer(sht4x_context->i2c, address, LL_I2C_ADDRESSING_MODE_7BIT, len, - LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ); - int i = 0; - while (!LL_I2C_IsActiveFlag_STOP(sht4x_context->i2c)) { - if (LL_I2C_IsActiveFlag_RXNE(sht4x_context->i2c)) { - if (i < len) { - buffer[i++] = LL_I2C_ReceiveData8(sht4x_context->i2c); - } - } - } - LL_I2C_ClearFlag_STOP(sht4x_context->i2c); -} - int sht4x_send_cmd(sht4x_cmd_t cmd) { @@ -57,17 +20,22 @@ int sht4x_read_data(uint8_t *buffer, int len) int sht4x_measure(int *temperature, int *relative_humidity) { uint8_t buffer[32]; + int result; // start measurement buffer[0] = START_MEAS_HIGH_PRECISION; - i2c_transmit(SHT4X_I2C_ADDRESS, buffer, 1); - // delay TODO - volatile int j,k; - for (j = 0; j < 100000; j++); + result = i2c_transmit(SHT4X_I2C_ADDRESS, buffer, 1); + if (result != I2C_OK) { + return SHT4X_ERROR; + } + // busy delay (LL_mDelay uses SysTick which doesn't work at the moment) TODO + for (volatile int j = 0; j < 100000; j++); // read out - i2c_receive(SHT4X_I2C_ADDRESS, buffer, 6); - // TODO - + result = i2c_receive(SHT4X_I2C_ADDRESS, buffer, 6); + if (result != I2C_OK) { + return SHT4X_ERROR; + } + // 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; @@ -80,4 +48,6 @@ int sht4x_measure(int *temperature, int *relative_humidity) } *temperature = t_degC; *relative_humidity = rh_pRH; + + return SHT4X_OK; }