diff --git a/fw/.cproject b/fw/.cproject
new file mode 100644
index 0000000..51ffe1b
--- /dev/null
+++ b/fw/.cproject
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/fw/.mxproject b/fw/.mxproject
new file mode 100644
index 0000000..53d6a27
--- /dev/null
+++ b/fw/.mxproject
@@ -0,0 +1,24 @@
+[PreviousLibFiles]
+LibFiles=Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.c;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h;Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h;Drivers/CMSIS/Device/ST/STM32L0xx/Source/Templates/system_stm32l0xx.c;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/cmsis_version.h;
+
+[PreviousUsedCubeIDEFiles]
+SourceFiles=Core/Src/main.c;Core/Src/stm32l0xx_it.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.c;Drivers/CMSIS/Device/ST/STM32L0xx/Source/Templates/system_stm32l0xx.c;Core/Src/system_stm32l0xx.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c;Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.c;Drivers/CMSIS/Device/ST/STM32L0xx/Source/Templates/system_stm32l0xx.c;Core/Src/system_stm32l0xx.c;;;
+HeaderPath=Drivers/STM32L0xx_HAL_Driver/Inc;Drivers/CMSIS/Device/ST/STM32L0xx/Include;Drivers/CMSIS/Include;Core/Inc;
+CDefines=USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:37000;VDD_VALUE:3300;PREFETCH_ENABLE:0;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;STM32L031xx;USE_FULL_LL_DRIVER;HSE_VALUE:8000000;HSE_STARTUP_TIMEOUT:100;LSE_STARTUP_TIMEOUT:5000;LSE_VALUE:32768;MSI_VALUE:2097000;HSI_VALUE:16000000;LSI_VALUE:37000;VDD_VALUE:3300;PREFETCH_ENABLE:0;INSTRUCTION_CACHE_ENABLE:1;DATA_CACHE_ENABLE:1;
+
+[PreviousGenFiles]
+AdvancedFolderStructure=true
+HeaderFileListSize=3
+HeaderFiles#0=/home/david/VelesLabs/Smart Household/wired_sensors/RHT_Wired_Sensor/fw/Core/Inc/stm32l0xx_it.h
+HeaderFiles#1=/home/david/VelesLabs/Smart Household/wired_sensors/RHT_Wired_Sensor/fw/Core/Inc/stm32_assert.h
+HeaderFiles#2=/home/david/VelesLabs/Smart Household/wired_sensors/RHT_Wired_Sensor/fw/Core/Inc/main.h
+HeaderFolderListSize=1
+HeaderPath#0=/home/david/VelesLabs/Smart Household/wired_sensors/RHT_Wired_Sensor/fw/Core/Inc
+HeaderFiles=;
+SourceFileListSize=2
+SourceFiles#0=/home/david/VelesLabs/Smart Household/wired_sensors/RHT_Wired_Sensor/fw/Core/Src/stm32l0xx_it.c
+SourceFiles#1=/home/david/VelesLabs/Smart Household/wired_sensors/RHT_Wired_Sensor/fw/Core/Src/main.c
+SourceFolderListSize=1
+SourcePath#0=/home/david/VelesLabs/Smart Household/wired_sensors/RHT_Wired_Sensor/fw/Core/Src
+SourceFiles=;
+
diff --git a/fw/.project b/fw/.project
new file mode 100644
index 0000000..433351c
--- /dev/null
+++ b/fw/.project
@@ -0,0 +1,32 @@
+
+
+ rht_wired_sensor
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ com.st.stm32cube.ide.mcu.MCUProjectNature
+ com.st.stm32cube.ide.mcu.MCUCubeProjectNature
+ org.eclipse.cdt.core.cnature
+ com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature
+ com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature
+ com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature
+ com.st.stm32cube.ide.mcu.MCURootProjectNature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/fw/.settings/language.settings.xml b/fw/.settings/language.settings.xml
new file mode 100644
index 0000000..d9e4b1f
--- /dev/null
+++ b/fw/.settings/language.settings.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/fw/.settings/stm32cubeide.project.prefs b/fw/.settings/stm32cubeide.project.prefs
new file mode 100644
index 0000000..2a751da
--- /dev/null
+++ b/fw/.settings/stm32cubeide.project.prefs
@@ -0,0 +1,4 @@
+66BE74F758C12D739921AEA421D593D3=11
+8DF89ED150041C4CBC7CB9A9CAA90856=807411C90E25B050C1E13646B7FEB5AA
+DC22A860405A8BF2F2C095E5B6529F12=807411C90E25B050C1E13646B7FEB5AA
+eclipse.preferences.version=1
diff --git a/fw/Core/Inc/config.h b/fw/Core/Inc/config.h
new file mode 100644
index 0000000..bb357d8
--- /dev/null
+++ b/fw/Core/Inc/config.h
@@ -0,0 +1,145 @@
+/*
+ * config.h
+ *
+ * Created on: Sep 5, 2021
+ * Author: david
+ */
+
+#ifndef INC_CONFIG_H_
+#define INC_CONFIG_H_
+
+/* TODO: add comments to everything */
+
+/* EXAMPLE of USAGE */
+/*
+config_t new_config;
+new_config.led_co2_alert_limit1 = 1000;
+new_config.led_co2_alert_limit2 = 2000;
+new_config.led_on = 1;
+new_config.modbus_addr = 0x11;
+config_write(&new_config);
+
+config_t config;
+config_read(&config);
+*/
+
+#include "stdint.h"
+#include "stm32l0xx.h"
+/* DESCRIPTION OF THE DATA STRUCTURE */
+/*
+ * Data are divided into two groups:
+ * A) DEVICE DESCRIPTION
+ * Can not be changed by the user.
+ * These data can be only read.
+ * These data are:
+ * * VENDOR NAME
+ * * PRODUCT CODE
+ * * PRODUCT NAME
+ * * REVISION
+ * * SERIAL NUMBER
+ * B) DEVICE CONFIGURATION
+ * Can be changed by the user.
+ * These data are:
+ * * MODBUS ADDRESS - Modbus Address of the device. Default is 254
+ * * LED ON - Whether the CO2 Level Indication LED should be on or off
+ * * LED CO2 ALERT LIMIT 1 - CO2 Level when the LED color changes Green<->Yellow
+ * * LED CO2 ALERT LIMIT 2 - CO2 Level when the LED color changes Yellow<->Red
+ *
+ * Device description data can be accessed using direct readout from the memory
+ * Device configuration data can be accessed using config_t struct.
+ */
+#define CONFIG_DEFAULT_LED_ON 1
+#define CONFIG_DEFAULT_LED_BRIGHTNESS 100
+#define CONFIG_DEFAULT_LED_ALERT1_LIMIT 1500
+#define CONFIG_DEFAULT_LED_ALERT2_LIMIT 3000
+#define CONFIG_DEFAULT_LED_SMOOTH 1
+#define CONFIG_DEFAULT_SCD4x_T_OFFSET 0
+#define CONFIG_DEFAULT_BAUDRATE_INDEX 0
+
+#define CONFIG_MODBUS_ADDR_LENGTH 2
+#define CONFIG_BAUDRATE_INDEX_LENGTH 2
+#define CONFIG_LED_ON_LENGTH 2
+#define CONFIG_LED_BRIGHTNESS_LENGTH 2
+#define CONFIG_LED_SMOOTH_LENGTH 2
+#define CONFIG_LED_ALERT1_LENGTH 2
+#define CONFIG_LED_ALERT2_LENGTH 2
+#define CONFIG_LED_ALERT2_LENGTH 2
+#define CONFIG_SCD4x_T_OFFSET_LENGTH 2
+#define VENDOR_NAME_LENGTH 64
+#define PRODUCT_CODE_LENGTH 64
+#define PRODUCT_NAME_LENGTH 64
+#define REVISION_LENGTH 16
+#define SERIAL_NUMBER_LENGTH 64
+
+#define EEPROM_EMPTY_BYTE 0x00
+
+#define EEPROM_ADDR_START ((uint32_t)0x08080000)
+#define EEPROM_ADDR_END ((uint32_t)0x080803FF)
+
+#define CONFIG_EEPROM_ADDR_MODBUS_ADDR EEPROM_ADDR_START
+#define CONFIG_EEPROM_ADDR_BAUDRATE_INDEX (CONFIG_EEPROM_ADDR_MODBUS_ADDR + CONFIG_MODBUS_ADDR_LENGTH)
+#define CONFIG_EEPROM_ADDR_LED_ON (CONFIG_EEPROM_ADDR_BAUDRATE_INDEX + CONFIG_BAUDRATE_INDEX_LENGTH)
+#define CONFIG_EEPROM_ADDR_LED_BRIGHTNESS (CONFIG_EEPROM_ADDR_LED_ON + CONFIG_LED_ON_LENGTH)
+#define CONFIG_EEPROM_ADDR_LED_SMOOTH (CONFIG_EEPROM_ADDR_LED_BRIGHTNESS + CONFIG_LED_BRIGHTNESS_LENGTH)
+#define CONFIG_EEPROM_ADDR_LED_ALERT1 (CONFIG_EEPROM_ADDR_LED_SMOOTH + CONFIG_LED_SMOOTH_LENGTH)
+#define CONFIG_EEPROM_ADDR_LED_ALERT2 (CONFIG_EEPROM_ADDR_LED_ALERT1 + CONFIG_LED_ALERT1_LENGTH)
+#define CONFIG_EEPROM_ADDR_SCD4x_T_OFFSET (CONFIG_EEPROM_ADDR_LED_ALERT2 + CONFIG_LED_ALERT2_LENGTH)
+
+#define CONFIG_EEPROM_ADDR_VENDOR_NAME (CONFIG_EEPROM_ADDR_SCD4x_T_OFFSET + CONFIG_SCD4x_T_OFFSET_LENGTH)
+#define CONFIG_EEPROM_ADDR_PRODUCT_CODE (CONFIG_EEPROM_ADDR_VENDOR_NAME + VENDOR_NAME_LENGTH)
+#define CONFIG_EEPROM_ADDR_PRODUCT_NAME (CONFIG_EEPROM_ADDR_PRODUCT_CODE + PRODUCT_CODE_LENGTH)
+#define CONFIG_EEPROM_ADDR_REVISION (CONFIG_EEPROM_ADDR_PRODUCT_NAME + PRODUCT_NAME_LENGTH)
+#define CONFIG_EEPROM_ADDR_SERIAL_NUMBER (CONFIG_EEPROM_ADDR_REVISION + REVISION_LENGTH)
+
+#define FLASH_PEKEY1 ((uint32_t)0x89ABCDEF)
+#define FLASH_PEKEY2 ((uint32_t)0x02030405)
+
+#define CONFIG_OK 0
+#define CONFIG_ERROR -1
+
+#define EEPROM_OK 0
+#define EEPROM_ERROR -1
+#define EEPROM_UNLOCK_ERROR -2
+#define EEPROM_LOCK_ERROR -3
+#define EEPROM_WRITE_ERROR -4
+#define EEPROM_ADDR_ERROR -5
+
+#define SYSTICK_FREQ_HZ 12000000
+#define EEPROM_TIMEOUT_MAX_MS_INV 200
+
+/*
+ * Variables
+ */
+
+extern const uint32_t config_baudrates[];
+extern const uint8_t config_baudrates_length;
+
+/*
+ * Type definitions
+ */
+
+typedef struct
+{
+ /* LED CONFIG */
+ uint8_t led_on;
+ uint16_t led_brightness;
+ uint8_t led_smooth;
+ uint16_t led_co2_alert_limit1;
+ uint16_t led_co2_alert_limit2;
+
+ /* SCD4x Temperature sensor offset */
+ int16_t scd4x_t_offset;
+
+ /* MODBUS CONFIG */
+ uint16_t modbus_addr;
+ uint32_t baudrate_index;
+} config_t;
+
+
+/* const uint32_t baudrates [] = {19200, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800, 115200}; */
+
+int8_t config_read(config_t *config);
+int8_t config_write(config_t *config);
+
+#endif /* INC_CONFIG_H_ */
+
diff --git a/fw/Core/Inc/crc8.h b/fw/Core/Inc/crc8.h
new file mode 100644
index 0000000..6820352
--- /dev/null
+++ b/fw/Core/Inc/crc8.h
@@ -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 ((uint8_t)0x31)
+#define CRC8_INIT ((uint8_t)0xFF)
+
+uint8_t crc8_calculate(const uint8_t *data, uint16_t count);
+
+#endif /* INC_CRC8_H_ */
diff --git a/fw/Core/Inc/i2c.h b/fw/Core/Inc/i2c.h
new file mode 100644
index 0000000..29b78dd
--- /dev/null
+++ b/fw/Core/Inc/i2c.h
@@ -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
+ */
+
+int8_t i2c_init(i2c_context_t *context);
+int8_t i2c_transmit(uint8_t address, uint8_t *buffer, int len);
+int8_t i2c_receive(uint8_t address, uint8_t *buffer, int len);
+
+#endif /* INC_I2C_H_ */
diff --git a/fw/Core/Inc/ltr329.h b/fw/Core/Inc/ltr329.h
new file mode 100644
index 0000000..7294a2a
--- /dev/null
+++ b/fw/Core/Inc/ltr329.h
@@ -0,0 +1,93 @@
+/*
+ * ltr329.h
+ *
+ * Created on: May 22, 2022
+ * Author: david
+ */
+
+#ifndef INC_LTR329_H_
+#define INC_LTR329_H_
+
+#include "stdint.h"
+#include "stm32l0xx_ll_i2c.h"
+#include "stm32l0xx_ll_utils.h"
+#include "i2c.h"
+
+#define LTR329_I2C_ADDRESS 0x29
+
+/*
+ * Return values
+ */
+
+#define LTR329_OK 0
+#define LTR329_ERROR -1 // generic error
+
+/* LTR-329ALS-01 Registers */
+/* Datasheet: https://optoelectronics.liteon.com/upload/download/DS86-2014-0006/LTR-329ALS-01_DS_V1.pdf */
+typedef enum
+{
+ LTR329_ALS_CONTR = 0x80, /* RW */
+ LTR329_ALS_MEAS_RATE = 0x85, /* RW */
+ LTR329_PART_ID = 0x86, /* R */
+ LTR329_MANUFAC_ID = 0x87, /* R */
+ LTR329_ALS_DATA_CH1_0 = 0x88, /* R */
+ LTR329_ALS_DATA_CH1_1 = 0x89, /* R */
+ LTR329_ALS_DATA_CH0_0 = 0x8A, /* R */
+ LTR329_ALS_DATA_CH0_1 = 0x8B, /* R */
+ LTR329_ALS_STATUS = 0x8C /* R */
+} ltr329_cmd_t;
+
+/* Bit masks for ALS Mode */
+typedef enum
+{
+ LTR329_MODE_STAND_BY = 0b00000000, /* DEFAULT */
+ LTR329_MODE_ACTIVE = 0b00000001
+} ltr329_als_mode_t;
+
+/* Bit masks for Gain settings */
+typedef enum
+{
+ LTR329_GAIN_1X = 0b00000000, /* DEFAULT */
+ LTR329_GAIN_2X = 0b00000100,
+ LTR329_GAIN_4X = 0b00001000,
+ LTR329_GAIN_8X = 0b00001100,
+ LTR329_GAIN_48X = 0b00011000,
+ LTR329_GAIN_96X = 0b00011100,
+ LTR329_GAIN_RESERVED1 = 0b00010000,
+ LTR329_GAIN_RESERVED2 = 0b00010100
+} ltr329_gain_t;
+
+/* Bit masks for Integration Time settings */
+typedef enum
+{
+ LTR329_INTEGRATION_50MS = 0b00001000,
+ LTR329_INTEGRATION_100MS = 0b00000000, /* DEFAULT */
+ LTR329_INTEGRATION_150MS = 0b00100000,
+ LTR329_INTEGRATION_200MS = 0b00010000,
+ LTR329_INTEGRATION_250MS = 0b00101000,
+ LTR329_INTEGRATION_300MS = 0b00110000,
+ LTR329_INTEGRATION_350MS = 0b00111000,
+ LTR329_INTEGRATION_400MS = 0b00011000
+} ltr329_integration_time_t;
+
+/* Bit masks for Measurement Rate settings */
+typedef enum
+{
+ LTR329_MEAS_RATE_50MS = 0b00000000,
+ LTR329_MEAS_RATE_100MS = 0b00000001,
+ LTR329_MEAS_RATE_200MS = 0b00000010,
+ LTR329_MEAS_RATE_500MS = 0b00000011, /* DEFAULT */
+ LTR329_MEAS_RATE_1000MS = 0b00000100,
+ LTR329_MEAS_RATE_2000MS = 0b00000111
+} ltr329_measurement_rate_t;
+
+static int8_t ltr329_read_register (ltr329_cmd_t register_addr, uint8_t *register_data );
+static int8_t ltr329_write_register (ltr329_cmd_t register_addr, uint8_t register_data);
+int8_t ltr329_write_settings (ltr329_gain_t gain, ltr329_als_mode_t mode, ltr329_integration_time_t integ_time, ltr329_measurement_rate_t meas_rate);
+int8_t ltr329_read_settings (ltr329_gain_t *gain, ltr329_als_mode_t *mode, ltr329_integration_time_t *integ_time, ltr329_measurement_rate_t *meas_rate);
+int8_t ltr329_sw_reset( void );
+int8_t ltr329_measure (uint16_t *data_ch0, uint16_t *data_ch1);
+int8_t ltr329_read_status_register(uint8_t *data_valid, uint8_t *new_data, ltr329_gain_t *gain);
+int8_t ltr329_read_device_info (uint8_t *manufacturer_id, uint8_t *part_id);
+
+#endif /* INC_LTR329_H_ */
diff --git a/fw/Core/Inc/main.h b/fw/Core/Inc/main.h
new file mode 100644
index 0000000..8413ac1
--- /dev/null
+++ b/fw/Core/Inc/main.h
@@ -0,0 +1,118 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : main.h
+ * @brief : Header for main.c file.
+ * This file contains the common defines of the application.
+ ******************************************************************************
+ * @attention
+ *
+ *
© Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAIN_H
+#define __MAIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l0xx_ll_i2c.h"
+#include "stm32l0xx_ll_iwdg.h"
+#include "stm32l0xx_ll_crs.h"
+#include "stm32l0xx_ll_rcc.h"
+#include "stm32l0xx_ll_bus.h"
+#include "stm32l0xx_ll_system.h"
+#include "stm32l0xx_ll_exti.h"
+#include "stm32l0xx_ll_cortex.h"
+#include "stm32l0xx_ll_utils.h"
+#include "stm32l0xx_ll_pwr.h"
+#include "stm32l0xx_ll_dma.h"
+#include "stm32l0xx_ll_tim.h"
+#include "stm32l0xx_ll_usart.h"
+#include "stm32l0xx_ll_gpio.h"
+
+#if defined(USE_FULL_ASSERT)
+#include "stm32_assert.h"
+#endif /* USE_FULL_ASSERT */
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+#include "i2c.h"
+#include "sht4x.h"
+#include "ltr329.h"
+#include "modbus.h"
+#include "config.h"
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void Error_Handler(void);
+
+/* USER CODE BEGIN EFP */
+int8_t uart_disable_interrupts(void);
+int8_t uart_enable_interrupts(void);
+
+/* USER CODE END EFP */
+
+/* Private defines -----------------------------------------------------------*/
+#ifndef NVIC_PRIORITYGROUP_0
+#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
+ 4 bits for subpriority */
+#define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006) /*!< 1 bit for pre-emption priority,
+ 3 bits for subpriority */
+#define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority,
+ 2 bits for subpriority */
+#define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority,
+ 1 bit for subpriority */
+#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority,
+ 0 bit for subpriority */
+#endif
+/* USER CODE BEGIN Private defines */
+#define SYSTEM_CLOCK_HZ 12000000
+#define MEASUREMENT_PERIOD_S 6
+#define RESET_MAGIC_NUMBER 0xABCD
+#define MODBUS_ASSERT(x) if (x == 0) return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED
+#define CELSIUS_TO_FAHRENHEIT(x) (x * 9 / 5 + 320)
+
+extern uint16_t usart2_rx_message_index;
+extern uint16_t usart2_rx_message_len;
+extern uint8_t usart2_rx_done;
+extern uint8_t usart2_rx_message_too_long;
+
+extern uint8_t tim21_elapsed_period;
+
+/* USER CODE END Private defines */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAIN_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/fw/Core/Inc/modbus.h b/fw/Core/Inc/modbus.h
new file mode 100644
index 0000000..ff01f65
--- /dev/null
+++ b/fw/Core/Inc/modbus.h
@@ -0,0 +1,231 @@
+/*
+ * modbus.h
+ *
+ * Created on: Jul 18, 2021
+ * Author: user
+ *
+ * Modbus slave RTU library (does NOT support ASCII and TCP)
+ *
+ * Useful links:
+ * https://www.picotech.com/library/oscilloscopes/modbus-serial-protocol-decoding
+ * https://ipc2u.com/articles/knowledge-base/modbus-rtu-made-simple-with-detailed-descriptions-and-examples/
+ * https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
+ * https://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
+ *
+ * Note that byte order is big endian.
+ *
+ * USAGE:
+ *
+ * 1) Implement functions modbus_callback_function() and modbus_uart_transmit_function()
+ * - modbus_uart_transmit_function() sends data via UART
+ * - modbus_callback_function() does the real work: read sensors, set outputs...
+ * note that when filling buffers (e.g. input_registers[]) user must
+ * ensure that all data is big-endian
+ * These functions are implementation-specific.
+ * 2) Set device address (variable modbus_device_address); you can do this either
+ * - setting modbus_device_address directly (modbus.h needs to be included, duh)
+ * - using modbus_set_device_address(uint8_t address) function
+ * Or you can leave address as-is (MODBUS_DEFAULT_SLAVE_ADDRESS) and set it via
+ * Modbus during runtime
+ * 3) Call modbus_process_msg() after message reception; you need to observe Modbus RTU timing:
+ * - pauses between chars in frame are less or equal to 1.5 char
+ * - pauses between frames are at least 3.5 chars (of silence)
+ * For more information see section 2.5.1.1 (MODBUS Message RTU Framing)
+ * in "MODBUS over Serial Line: Specification and Implementation Guide"
+ *
+ */
+
+#ifndef SRC_MODBUS_H_
+#define SRC_MODBUS_H_
+
+#include "stdint.h"
+#include "stddef.h"
+#include "string.h"
+
+/*
+ * Defines & macros
+ */
+
+#define MODBUS_BROADCAST_ADDR 0
+#define MODBUS_DEFAULT_SLAVE_ADDRESS 247 /* 255 may be used for bridge device */
+/* minimal frame length is 4 bytes: 1 B slave address, 1 B function code, 2 B CRC */
+#define MODBUS_MINIMAL_FRAME_LEN 4
+#define MODBUS_MINIMAL_READWRITE_LEN 4
+#define MODBUS_MINIMAL_WRITE_MULTIPLE_LEN 5
+#define MODBUS_READ_DEVICE_ID_REQUEST_LEN 4
+#define MODBUS_READ_DEVICE_ID_RESPONSE_HEADER_LEN 4
+#define MODBUS_READ_DEVICE_ID_RESPONSE_OFFSET 3
+#define MODBUS_MAX_RTU_FRAME_SIZE 256
+#define MODBUS_BUFFER_SIZE MODBUS_MAX_RTU_FRAME_SIZE /* alias */
+#define MODBUS_ERROR_FLAG 0x80
+#define MODBUS_MAX_REGISTERS 125
+/* read device id constants */
+#define MODBUS_MEI 0x0E
+#define MODBUS_DEVICE_ID_INDIVIDUAL_ACCESS_FLAG 0x80
+#define MODBUS_MORE_FOLLOWS 0xFF
+#define MODBUS_NO_MORE_FOLLOWS 0x00
+#define MODBUS_BASIC_OBJECT_COUNT 3
+#define MODBUS_REGULAR_OBJECT_COUNT 7
+
+/*
+ * Return values
+ */
+
+#define MODBUS_OK 0
+#define MODBUS_ERROR -1 // generic error
+#define MODBUS_ERROR_CRC -2 // checksum failed
+#define MODBUS_ERROR_FRAME_INVALID -3 // invalid frame format / length
+#define MODBUS_ERROR_OUT_OF_BOUNDS -4 // requested register is out of bounds
+#define MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED -5 // function not implemented in callback
+#define MODBUS_ERROR_REGISTER_NOT_IMPLEMENTED -6 // register not implemented in callback
+#define MODBUS_ERROR_DEVICE_ID_NOT_IMPLEMENTED -7
+
+/*
+ * Data types
+ */
+
+/* Public functions codes (Modbus Application protocol specification, section 5.1) */
+typedef enum {
+ /* single bit access functions */
+ MODBUS_READ_COILS = 1,
+ MODBUS_READ_DO = 1, // alias
+ MODBUS_READ_DISCRETE_INPUTS = 2,
+ MODBUS_READ_DI = 2, // alias
+ MODBUS_WRITE_SINGLE_COIL = 5,
+ MODBUS_WRITE_SINGLE_DO = 5, // alias
+ MODBUS_WRITE_MULTIPLE_COILS = 15,
+ MODBUS_WRITE_MULTIPLE_DO = 15, // alias
+ /* 16-bit access functions */
+ MODBUS_READ_HOLDING_REGISTERS = 3,
+ MODBUS_READ_AO = 3, // alias
+ MODBUS_READ_INPUT_REGISTERS = 4,
+ MODBUS_READ_AI = 4, // alias
+ MODBUS_WRITE_SINGLE_REGISTER = 6,
+ MODBUS_WRITE_SINGLE_AO = 6, // alias
+ MODBUS_WRITE_MULTIPLE_REGISTERS = 16,
+ MODBUS_WRITE_MULTIPLE_AO = 16, // alias
+ MODBUS_MASK_WRITE_REGISTER = 22,
+ MODBUS_READ_WRITE_MULTIPLE_REGISTERS = 23,
+ MODBUS_READ_FIFO_QUEUE = 24,
+ /* file record access */
+ MODBUS_READ_FILE_RECORD = 20,
+ MODBUS_WRITE_FILE_RECORD = 21,
+ /* diagnostics */
+ MODBUS_READ_EXCEPTION_STATUS = 7,
+ MODBUS_DIAGNOSTIC = 8, /* sub codes: 00-18,20 */
+ MODBUS_GET_COM_EVENT_COUNTER = 11,
+ MODBUS_GET_COM_EVENT_LOG = 12,
+ MODBUS_REPORT_SLAVE_ID = 17,
+ MODBUS_READ_DEVICE_IDENTIFICATION = 43, /* sub codes: 14 */
+} modbus_function_code_t;
+
+typedef enum {
+ MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 1,
+ MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS = 2,
+ MODBUS_EXCEPTION_ILLEGAL_REGISTER_QUANTITY = 2,
+ MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE = 3,
+ MODBUS_EXCEPTION_SLAVE_DEVICE_FAILURE = 4,
+ MODBUS_EXCEPTION_ACKNOWLEDGE = 5,
+ MODBUS_EXCEPTION_SLAVE_DEVICE_BUSY = 6,
+ MODBUS_EXCEPTION_MEMORY_PARITY_ERROR = 8,
+ MODBUS_EXCEPTION_GATEWAY_PATH_UNAVAILABLE = 10,
+ MODBUS_EXCEPTION_GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 11,
+ MODBUS_EXCEPTION_ILLEGAL_DEVICE_ID_CODE = 3
+} modbus_exception_code_t;
+
+typedef struct {
+ modbus_function_code_t function_code : 8;
+ uint16_t register_address; // e.g. first register of A0: 0
+ uint16_t register_number; // e.g. first register of A0: 40001
+ uint8_t register_count; // number of registers to be read/written
+
+ modbus_exception_code_t exception;
+
+ uint8_t broadcast; // 1 if broadcast, 0 otherwise
+
+ union {
+ uint8_t buffer8b[MODBUS_MAX_RTU_FRAME_SIZE];
+ uint16_t buffer16b[MODBUS_MAX_RTU_FRAME_SIZE/2];
+ uint16_t input_registers[MODBUS_MAX_REGISTERS];
+ uint16_t holding_registers[MODBUS_MAX_REGISTERS];
+ int16_t input_registers_signed[MODBUS_MAX_REGISTERS];
+ int16_t holding_registers_signed[MODBUS_MAX_REGISTERS];
+ };
+
+ /* process device id */
+ uint8_t read_device_id_code;
+ uint8_t object_id;
+} modbus_transaction_t;
+
+typedef enum {
+ MODBUS_DO_START_NUMBER = 1, // Discrete output coils
+ MODBUS_DO_END_NUMBER = 9999,
+ MODBUS_DI_START_NUMBER = 10001, // Discrete input contacts
+ MODBUS_DI_END_NUMBER = 19999,
+ MODBUS_AI_START_NUMBER = 30001, // Analog input registers
+ MODBUS_AI_END_NUMBER = 39999,
+ MODBUS_AO_START_NUMBER = 40001, // Analog output (holding registers)
+ MODBUS_AO_END_NUMBER = 49999
+} modbus_register_number_t;
+
+typedef enum {
+ MODBUS_CONFORMITY_BASIC = 1,
+ MODBUS_CONFORMITY_REGULAR = 2,
+ MODBUS_CONFORMITY_EXTENDED = 3,
+ MODBUS_INDIVIDUAL_ACCESS = 4 /* not actually part of conformity, but I'll keep it here anyway */
+} modbus_conformity_level_t;
+
+/* Device ID datatypes */
+#define MODBUS_DEVICE_ID_OBJECT_NUM 7
+typedef struct {
+ union {
+ struct {
+ /* Basic category (mandatory part) */
+ char *VendorName;
+ char *ProductCode;
+ char *MajorMinorRevision;
+ /* Regular category (optional part) */
+ char *VendorUrl;
+ char *ProductName;
+ char *ModelName;
+ char *UserApplicationName;
+ /* Extended category (optional part) */
+ // Nothing here yet!
+ } object_name;
+ char *object_id[MODBUS_DEVICE_ID_OBJECT_NUM];
+ };
+ uint8_t conformity_level;
+} modbus_device_id_t;
+
+/*
+ * Global variables
+ */
+
+/* device address: declared in modbus.c */
+extern uint8_t modbus_slave_address;
+
+/* shared modbus buffer; defined in modbus.c; may be used elsewhere in code */
+extern uint8_t modbus_buffer[];
+
+/* modbus device id struct */
+extern modbus_device_id_t *modbus_device_id;
+
+/*
+ * Function prototypes
+ */
+
+/* process message: should be called in when modbus message was received (e.g. in main.c)
+ * modbus_process_msg() may call following functions:
+ * - modbus_callback_function() if data readout is requested
+ * - modbus_uart_transmit_function() if response is required
+ * Both functions have to be implemented by user.
+ */
+int8_t modbus_slave_process_msg(const uint8_t *buffer, int len);
+int8_t modbus_slave_init_device_id(modbus_device_id_t *device_id);
+int8_t modbus_slave_set_address(uint8_t address);
+/* modbus callback function type - should be implemented by user (e.g. in main.c) */
+int8_t modbus_slave_callback(modbus_transaction_t *transaction);
+/* UART transmit function type - should be implemented by user (e.g. in main.c) */
+int8_t modbus_transmit_function(uint8_t *buffer, uint16_t data_len);
+
+#endif /* SRC_MODBUS_H_ */
diff --git a/fw/Core/Inc/sht4x.h b/fw/Core/Inc/sht4x.h
new file mode 100644
index 0000000..36c4351
--- /dev/null
+++ b/fw/Core/Inc/sht4x.h
@@ -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 {
+ SHT4X_START_MEAS_HIGH_PRECISION = 0xFD,
+ SHT4X_START_MEAS_MEDIUM_PRECISION = 0xF6,
+ SHT4X_START_MEAS_LOW_PRECISION = 0xE0,
+ SHT4X_READ_SERIAL = 0x89,
+ SHT4X_SOFT_RESET = 0x94,
+ SHT4X_HEATER_200_mW_1_s = 0x39,
+ SHT4X_HEATER_200_mW_01_s = 0x32,
+ SHT4X_HEATER_110_mW_1_s = 0x2F,
+ SHT4X_HEATER_110_mW_01_s = 0x24,
+ SHT4X_HEATER_20_mW_1_s = 0x1E,
+ SHT4X_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(int16_t *temperature, uint16_t *relative_humidity);
+
+#endif /* INC_SHT4X_H_ */
diff --git a/fw/Core/Inc/stm32_assert.h b/fw/Core/Inc/stm32_assert.h
new file mode 100644
index 0000000..ca09699
--- /dev/null
+++ b/fw/Core/Inc/stm32_assert.h
@@ -0,0 +1,53 @@
+/**
+ ******************************************************************************
+ * @file stm32_assert.h
+ * @brief STM32 assert file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2018 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32_ASSERT_H
+#define __STM32_ASSERT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Includes ------------------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_ASSERT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/fw/Core/Inc/stm32l0xx_it.h b/fw/Core/Inc/stm32l0xx_it.h
new file mode 100644
index 0000000..c2f720d
--- /dev/null
+++ b/fw/Core/Inc/stm32l0xx_it.h
@@ -0,0 +1,65 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32l0xx_it.h
+ * @brief This file contains the headers of the interrupt handlers.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32L0xx_IT_H
+#define __STM32L0xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void SVC_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+void TIM21_IRQHandler(void);
+void USART2_IRQHandler(void);
+/* USER CODE BEGIN EFP */
+/* USER CODE END EFP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L0xx_IT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/fw/Core/Src/config.c b/fw/Core/Src/config.c
new file mode 100644
index 0000000..08f6112
--- /dev/null
+++ b/fw/Core/Src/config.c
@@ -0,0 +1,243 @@
+/*
+ * config.c
+ *
+ * Created on: Sep 5, 2021
+ * Author: david
+ */
+
+#include "config.h"
+
+/*
+ * Variables
+ */
+/* Baudrates - STM32L0xx can do baudrates from 1200 to 115200
+ * - default value has index 0 */
+const uint32_t config_baudrates[] = {
+ 19200, // 0
+ 4800, // 1
+ 9600, // 2
+ 14400, // 3
+ 19200, // 4
+ 28800, // 5
+ 38400, // 6
+ 57600, // 7
+ 76800, // 8
+ 115200 // 9
+};
+const uint8_t config_baudrates_length = 10;
+
+/* Function to lock the EEPROM */
+static int8_t eeprom_lock(void);
+/* Function to unlock the EEPROM */
+static int8_t eeprom_unlock(void);
+/* Function to write one byte to the EEPROM */
+/* IMPORTANT: EEPROM must be unlocked first */
+static int8_t eeprom_program_byte(uint32_t addr, uint8_t ee_data);
+/* Function to write two bytes to the EEPROM */
+/* IMPORTANT: EEPROM must be unlocked first */
+static int8_t eeprom_program_halfword(uint32_t addr, uint16_t ee_data);
+/* Function to write four bytes to the EEPROM */
+/* IMPORTANT: EEPROM must be unlocked first */
+static int8_t eeprom_program_word(uint32_t addr, uint32_t ee_data);
+
+int8_t config_read(config_t *config)
+{
+ config->modbus_addr = *(uint16_t *) (CONFIG_EEPROM_ADDR_MODBUS_ADDR);
+ config->baudrate_index = *(uint16_t *) (CONFIG_EEPROM_ADDR_BAUDRATE_INDEX);
+ config->led_on = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ON);
+ config->led_brightness = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_BRIGHTNESS);
+ config->led_smooth = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_SMOOTH);
+ config->led_co2_alert_limit1 = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ALERT1);
+ config->led_co2_alert_limit2 = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ALERT2);
+ config->scd4x_t_offset = *(int16_t *) (CONFIG_EEPROM_ADDR_SCD4x_T_OFFSET);
+
+ /* Check if the EEPROM is initialized - do not check:
+ * LED ON
+ * LED SMOOTH
+ * SCD4x T OFFSET
+ * BAUDRATE INDEX
+ * those can be 0 */
+ if ((config->modbus_addr == EEPROM_EMPTY_BYTE) ||
+ (config->led_co2_alert_limit1 == EEPROM_EMPTY_BYTE) ||
+ (config->led_co2_alert_limit2 == EEPROM_EMPTY_BYTE) ||
+ (config->led_brightness == EEPROM_EMPTY_BYTE))
+ {
+ return CONFIG_ERROR;
+ }
+ return CONFIG_OK;
+}
+
+int8_t config_write(config_t *config)
+{
+ /* Unlock the EEPROM */
+ if (eeprom_unlock() != EEPROM_OK)
+ {
+ return EEPROM_UNLOCK_ERROR;
+ }
+ /* Reset the ERASE and DATA bits in the FLASH_PECR register to disable any residual erase */
+ FLASH->PECR = FLASH->PECR & ~(FLASH_PECR_ERASE | FLASH_PECR_DATA);
+
+ /* Write MODBUS ADDRESS */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_MODBUS_ADDR, config->modbus_addr) != EEPROM_OK)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+ /* Write BAUDRATE */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_BAUDRATE_INDEX, config->baudrate_index) != EEPROM_OK)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+
+ /* Write LED ON */
+ if (eeprom_program_byte(CONFIG_EEPROM_ADDR_LED_ON, config->led_on) != EEPROM_OK)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+
+ /* Write LED BRIGHTNESS */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_BRIGHTNESS, config->led_brightness) != EEPROM_OK)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+
+ /* Write LED SMOOTH */
+ if (eeprom_program_byte(CONFIG_EEPROM_ADDR_LED_SMOOTH, config->led_smooth) != EEPROM_OK)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+
+ /* Write LED CO2 ALERT LIMIT 1 */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT1, config->led_co2_alert_limit1) != EEPROM_OK)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+
+ /* Write LED CO2 ALERT LIMIT 2 */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT2, config->led_co2_alert_limit2) != EEPROM_OK)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+
+ /* Write LED SCD4x TEMPERATURE OFFSET */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_SCD4x_T_OFFSET, config->scd4x_t_offset) != EEPROM_OK)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+
+ /* Lock EEPROM*/
+ if (eeprom_lock() != EEPROM_OK)
+ {
+ return EEPROM_LOCK_ERROR;
+ }
+ return CONFIG_OK;
+}
+
+static int8_t eeprom_lock(void)
+{
+ uint32_t tick_start = SysTick->VAL;
+ while ((FLASH->SR & FLASH_SR_BSY) != 0) /* Wait for FLASH to be free */
+ {
+ /* Timeout test */
+ /* The maximum writing time is 3.94ms (half-word) */
+ uint32_t tick_last = SysTick->VAL;
+ uint32_t tick_diff;
+ if (tick_start <= tick_last)
+ {
+ tick_diff = tick_last - tick_start;
+ } else
+ {
+ tick_diff = (0xFFFFFFFF - tick_last) + tick_start;
+ }
+
+ /* If the time difference is more than 5ms */
+ if (tick_diff >= (uint32_t)((uint32_t)SYSTICK_FREQ_HZ*(uint32_t)EEPROM_TIMEOUT_MAX_MS_INV))
+ {
+ return EEPROM_LOCK_ERROR;
+ }
+ }
+
+ FLASH->PECR = FLASH->PECR & ~(FLASH_PECR_ERRIE | FLASH_PECR_EOPIE); /* disable flash interrupts */
+ FLASH->PECR = FLASH->PECR | FLASH_PECR_PELOCK; /* Lock memory with PELOCK */
+
+ return EEPROM_OK;
+}
+
+static int8_t eeprom_unlock(void)
+{
+ uint32_t tick_start = SysTick->VAL;
+ while ((FLASH->SR & FLASH_SR_BSY) != 0) /* Wait for FLASH to be free */
+ {
+ /* Timeout test */
+ /* The maximum writing time is 3.94ms (half-word) */
+ uint32_t tick_last = SysTick->VAL;
+ uint32_t tick_diff;
+ if (tick_start <= tick_last)
+ {
+ tick_diff = tick_last - tick_start;
+ } else
+ {
+ tick_diff = (0xFFFFFFFF - tick_last) + tick_start;
+ }
+
+ /* If the time difference is more than 5ms */
+ if (tick_diff >= (uint32_t)((uint32_t)SYSTICK_FREQ_HZ*(uint32_t)EEPROM_TIMEOUT_MAX_MS_INV))
+ {
+ return EEPROM_UNLOCK_ERROR;
+ }
+ }
+ if ((FLASH->PECR & FLASH_PECR_PELOCK) != 0) /* If PELOCK is locked */
+ {
+ /* Unlock PELOCK */
+ FLASH->PEKEYR = FLASH_PEKEY1; /* PEKEY1 */
+ FLASH->PEKEYR = FLASH_PEKEY2; /* PEKEY2 */
+ }
+ FLASH->PECR = FLASH->PECR | (FLASH_PECR_ERRIE | FLASH_PECR_EOPIE); /* enable flash interrupts */
+ return EEPROM_OK;
+}
+
+static int8_t eeprom_program_byte(uint32_t addr, uint8_t ee_data)
+{
+ if ((EEPROM_ADDR_START <= addr) && (addr <= EEPROM_ADDR_END - 1))
+ {
+ *(uint8_t *)(addr) = ee_data; /* write data to EEPROM */
+ if (*(uint8_t *)(addr) != ee_data)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+ return EEPROM_OK;
+ } else
+ {
+ return EEPROM_ADDR_ERROR;
+ }
+}
+static int8_t eeprom_program_halfword(uint32_t addr, uint16_t ee_data)
+{
+ if ((EEPROM_ADDR_START <= addr) && (addr <= EEPROM_ADDR_END - 2))
+ {
+ *(uint16_t *)(addr) = ee_data; /* write data to EEPROM */
+ if (*(uint16_t *)(addr) != ee_data)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+ return EEPROM_OK;
+ } else
+ {
+ return EEPROM_ADDR_ERROR;
+ }
+}
+
+static int8_t eeprom_program_word(uint32_t addr, uint32_t ee_data)
+{
+ if ((EEPROM_ADDR_START <= addr) && (addr <= EEPROM_ADDR_END - 4))
+ {
+ *(uint32_t *)(addr) = ee_data; /* write data to EEPROM */
+ if (*(uint32_t *)(addr) != ee_data)
+ {
+ return EEPROM_WRITE_ERROR;
+ }
+ return EEPROM_OK;
+ } else
+ {
+ return EEPROM_ADDR_ERROR;
+ }
+}
diff --git a/fw/Core/Src/crc8.c b/fw/Core/Src/crc8.c
new file mode 100644
index 0000000..312cdf4
--- /dev/null
+++ b/fw/Core/Src/crc8.c
@@ -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;
+}
diff --git a/fw/Core/Src/i2c.c b/fw/Core/Src/i2c.c
new file mode 100644
index 0000000..f6a78f8
--- /dev/null
+++ b/fw/Core/Src/i2c.c
@@ -0,0 +1,69 @@
+/*
+ * i2c.c
+ *
+ * Created on: Jun 8, 2021
+ * Author: user
+ */
+
+#include "i2c.h"
+#include "stm32l0xx_ll_usart.h"
+
+static i2c_context_t *i2c_context;
+
+int8_t i2c_init(i2c_context_t *context)
+{
+ if (context == NULL) {
+ return I2C_ERROR;
+ }
+ i2c_context = context;
+ return I2C_OK;
+}
+
+int8_t 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);
+ LL_I2C_ClearFlag_TXE(i2c_context->i2c);
+ if (len != i) {
+ /* If we detect NACK during transaction (before the end of the last byte) */
+ return I2C_ERROR_TX_INCOMPLETE;
+ }
+ /* NACK after last byte is ok */
+// if (LL_I2C_IsActiveFlag_NACK(i2c_context->i2c)) {
+//
+// return I2C_ERROR_NACK;
+// }
+ return I2C_OK;
+}
+
+int8_t 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);
+ LL_I2C_ClearFlag_STOP(i2c_context->i2c);
+ 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;
+}
diff --git a/fw/Core/Src/ltr329.c b/fw/Core/Src/ltr329.c
new file mode 100644
index 0000000..6918d7d
--- /dev/null
+++ b/fw/Core/Src/ltr329.c
@@ -0,0 +1,202 @@
+/*
+ * ltr329.c
+ *
+ * Created on: May 22, 2022
+ * Author: david
+ */
+#include "ltr329.h"
+#include "main.h" /* for uart_disable_interrupts() */
+
+static int8_t ltr329_read_register (ltr329_cmd_t register_addr, uint8_t *register_data )
+{
+ uint8_t tx_buffer[1];
+ uint8_t rx_buffer[1];
+ int result;
+
+ // start measurement
+ tx_buffer[0] = register_addr;
+ /* disable interrupts to prevent modbus/i2c conflict */
+ uart_disable_interrupts();
+ result = i2c_transmit(LTR329_I2C_ADDRESS<<1, tx_buffer, 1);
+ uart_enable_interrupts();
+ if (result != I2C_OK) {
+ return LTR329_ERROR;
+ }
+ LL_mDelay(10); /* 10 ms should be enough */
+ /* read out */
+ uart_disable_interrupts();
+ result = i2c_receive(LTR329_I2C_ADDRESS<<1, rx_buffer, 1);
+ uart_enable_interrupts();
+ if (result != I2C_OK) {
+ return LTR329_ERROR;
+ }
+
+ *register_data = rx_buffer[0];
+ return LTR329_OK;
+}
+
+static int8_t ltr329_write_register (ltr329_cmd_t register_addr, uint8_t register_data)
+{
+ uint8_t tx_buffer[2];
+ int result;
+
+ // start measurement
+ tx_buffer[0] = register_addr;
+ tx_buffer[1] = register_data;
+ /* disable interrupts to prevent modbus/i2c conflict */
+ uart_disable_interrupts();
+ result = i2c_transmit(LTR329_I2C_ADDRESS<<1, tx_buffer, 2);
+ uart_enable_interrupts();
+ if (result != I2C_OK) {
+ return LTR329_ERROR;
+ }
+ return LTR329_OK;
+}
+
+int8_t ltr329_write_settings (ltr329_gain_t gain, ltr329_als_mode_t mode, ltr329_integration_time_t integ_time, ltr329_measurement_rate_t meas_rate)
+{
+ int8_t result;
+ /* Write Gain and ALS Mode */
+ result = ltr329_write_register(LTR329_ALS_CONTR, (gain | mode));
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+ /* Write Integration Time and Measurement Rate */
+
+ result = ltr329_write_register(LTR329_ALS_MEAS_RATE, (integ_time | meas_rate));
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+ return LTR329_OK;
+}
+
+int8_t ltr329_read_settings (ltr329_gain_t *gain, ltr329_als_mode_t *mode, ltr329_integration_time_t *integ_time, ltr329_measurement_rate_t *meas_rate)
+{
+ int8_t result;
+ uint8_t control_register_data;
+ uint8_t rate_register_data;
+
+ result = ltr329_read_register(LTR329_ALS_CONTR, &control_register_data);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+
+ result = ltr329_read_register(LTR329_ALS_MEAS_RATE, &rate_register_data);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+
+ uint8_t control_register_gain_mask = 0b00011100;
+ uint8_t control_register_mode_mask = 0b00000001;
+ uint8_t rate_register_int_time_mask = 0b00111000;
+ uint8_t rate_register_rate_mask = 0b00000111;
+
+ /* Return Registers Values */
+ /* TODO: This might not be safe */
+ *gain = control_register_data & control_register_gain_mask;
+ *mode = control_register_data & control_register_mode_mask;
+ *integ_time = rate_register_data & rate_register_int_time_mask;
+ *meas_rate = rate_register_data & rate_register_rate_mask;
+
+ return LTR329_OK;
+}
+
+int8_t ltr329_sw_reset( void )
+{
+ int8_t result;
+ /* Write Gain and ALS Mode */
+ result = ltr329_write_register(LTR329_ALS_CONTR, 0b00000010);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+ return LTR329_OK;
+}
+
+int8_t ltr329_measure (uint16_t *data_ch0, uint16_t *data_ch1)
+{
+ uint8_t ch0_l, ch0_h, ch1_l, ch1_h;
+ int result;
+ result = ltr329_read_register(LTR329_ALS_DATA_CH0_0, &ch0_l);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+ result = ltr329_read_register(LTR329_ALS_DATA_CH0_1, &ch0_h);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+ result = ltr329_read_register(LTR329_ALS_DATA_CH1_0, &ch1_l);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+ result = ltr329_read_register(LTR329_ALS_DATA_CH1_1, &ch1_h);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+
+ *data_ch0 = (ch0_h << 8) + ch0_l;
+ *data_ch1 = (ch1_h << 8) + ch1_l;
+ return LTR329_OK;
+}
+
+int8_t ltr329_read_status_register(uint8_t *data_valid, uint8_t *new_data, ltr329_gain_t *gain)
+{
+ int8_t result;
+ uint8_t status_register_data;
+ result = ltr329_read_register(LTR329_ALS_STATUS, &status_register_data);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+
+ /* Check data valid */
+ uint8_t data_invalid_mask = 0b10000000;
+ if ((status_register_data & data_invalid_mask) == data_invalid_mask)
+ {
+ *data_valid = 0;
+ } else
+ {
+ *data_valid = 1;
+ }
+
+ /* Check if there is new data */
+ uint8_t data_status_mask = 0b00000100;
+ if ((status_register_data & data_status_mask) == data_status_mask)
+ {
+ *new_data = 1;
+ } else
+ {
+ *new_data = 0;
+ }
+
+ /* Check Gain */
+ /* TODO: This might not be safe */
+ uint8_t gain_mask = 0b01110000;
+ *gain = status_register_data & gain_mask;
+
+ return LTR329_OK;
+}
+
+int8_t ltr329_read_device_info (uint8_t *manufacturer_id, uint8_t *part_id)
+{
+ int8_t result;
+ result = ltr329_read_register(LTR329_MANUFAC_ID, manufacturer_id);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+ result = ltr329_read_register(LTR329_PART_ID, part_id);
+ if (result != LTR329_OK)
+ {
+ return LTR329_ERROR;
+ }
+ return LTR329_OK;
+}
diff --git a/fw/Core/Src/main.c b/fw/Core/Src/main.c
new file mode 100644
index 0000000..ef371fd
--- /dev/null
+++ b/fw/Core/Src/main.c
@@ -0,0 +1,749 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : main.c
+ * @brief : Main program body
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+/*
+ * BASE CLOCK 12MHz
+ * Desired interrupt period 60s
+ */
+const uint16_t tim21_prescaler = 60000-1; // 100Hz
+//const uint16_t tim21_period = 12000-1; // 60s
+//const uint16_t tim21_period = 1200-1; // 6s
+const uint16_t tim21_period = MEASUREMENT_PERIOD_S * (SYSTEM_CLOCK_HZ / tim21_prescaler) - 1;
+//const uint16_t tim21_period = 200-1; // 1s
+
+/* Input register memory map
+ * (All registers are 16-bit)
+ * -------------------------
+ *
+ * 30010 : CO2 [ppm] Unsigned value in range [0,40000]
+ * 30011 : T [deg_C * 10] From SHT4x; unsigned value in range [0; 1250]; e.g. 21.5 C => 215
+ * 30012 : RH [%] From SHT4x; unsigned value in range [0; 100]
+ *
+ * Backup T and RH sensor:
+ * 30013 : T [deg_C * 10] From SCD4x; unsigned value in range [0; 600]; e.g. 21.5 C => 215
+ * 30014 : RH [%] From SCD4x; unsigned value in range [0; 100]
+ *
+ * Extended temperature range (signed values):
+ * 30015 : T [deg_C * 10] From SHT4x; signed value (two's complement) in range [-400;1250]
+ * 30016 : T [deg_C * 10] From SCD4x; signed value (two's complement) in range [-100;600]; e.g. -12.3 C => -123
+ *
+ */
+/* Input registers memory map implementation */
+enum
+{
+ REGISTER_NUM_T = 30010, /* deg C */
+ REGISTER_NUM_T_F = 30011, /* deg F */
+ REGISTER_NUM_RH = 30012 /* %, from SHT4x */
+
+ /* VOC Index has initial blackout beriod, when the data is not ready. VOC index is 0 during this period */
+} data_registers_numbers;
+
+enum
+{
+ REGISTER_NUM_MODBUS_ADDR = 40007,
+ REGISTER_NUM_BAUDRATE = 40008,
+ REGISTER_NUM_RESET_DEVICE = 40100
+} config_registers_numbers;
+
+enum
+{
+ REGISTER_NUM_VENDOR_NAME = 30010,
+ REGISTER_NUM_PRODUCT_CODE = 30011,
+ REGISTER_NUM_REVISION = 30012,
+ REGISTER_NUM_PRODUCT_NAME = 30013,
+ REGISTER_NUM_SERIAL_NUMBER = 30014
+} identification_registers_numbers;
+
+/* Variables to store the measured data */
+int16_t T_SHT4x, TF_SHT4x;
+uint16_t RH_SHT4x;
+uint16_t light_ch0, light_ch1;
+
+/* Struct to store the sensor config */
+config_t sensor_config;
+/* Device ID struct */
+modbus_device_id_t device_id;
+uint8_t sensor_config_pending_write = 0;
+uint8_t baudrate_changed = 0;
+uint8_t modbus_address_changed = 0;
+uint8_t co2_valid = 0;
+
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+void SystemClock_Config(void);
+static void MX_GPIO_Init(void);
+static void MX_I2C1_Init(void);
+static void MX_USART2_UART_Init(void);
+static void MX_TIM21_Init(void);
+static void MX_IWDG_Init(void);
+/* USER CODE BEGIN PFP */
+void USART2_TX_Buffer(uint8_t* buffer_tx, uint16_t buffer_tx_len);
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+ * @brief The application entry point.
+ * @retval int
+ */
+int main(void)
+{
+ /* USER CODE BEGIN 1 */
+
+ /* USER CODE END 1 */
+
+ /* MCU Configuration--------------------------------------------------------*/
+
+ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
+ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
+
+ /* System interrupt init*/
+ /* SysTick_IRQn interrupt configuration */
+ NVIC_SetPriority(SysTick_IRQn, 3);
+
+ /* USER CODE BEGIN Init */
+
+ /* USER CODE END Init */
+
+ /* Configure the system clock */
+ SystemClock_Config();
+
+ /* USER CODE BEGIN SysInit */
+ /* Read config from EEPROM - if unsuccessful, set the default values*/
+ int8_t config_read_status = config_read(&sensor_config);
+ if (config_read_status != CONFIG_OK)
+ {
+ sensor_config.modbus_addr = MODBUS_DEFAULT_SLAVE_ADDRESS;
+ sensor_config.led_co2_alert_limit1 = CONFIG_DEFAULT_LED_ALERT1_LIMIT;
+ sensor_config.led_co2_alert_limit2 = CONFIG_DEFAULT_LED_ALERT2_LIMIT;
+ sensor_config.led_on = CONFIG_DEFAULT_LED_ON;
+ sensor_config.led_brightness = CONFIG_DEFAULT_LED_BRIGHTNESS;
+ sensor_config.led_smooth = CONFIG_DEFAULT_LED_SMOOTH;
+ sensor_config.scd4x_t_offset = CONFIG_DEFAULT_SCD4x_T_OFFSET;
+ sensor_config.baudrate_index = CONFIG_DEFAULT_BAUDRATE_INDEX;
+ }
+ /* USER CODE END SysInit */
+
+ /* Initialize all configured peripherals */
+ MX_GPIO_Init();
+ MX_I2C1_Init();
+ MX_USART2_UART_Init();
+ MX_TIM21_Init();
+ MX_IWDG_Init();
+ /* USER CODE BEGIN 2 */
+
+ /* Turn on MAGENTA LED to signal startup state */
+// LL_GPIO_ResetOutputPin(LED_R_GPIO_Port, LED_R_Pin);
+// LL_GPIO_ResetOutputPin(LED_G_GPIO_Port, LED_G_Pin);
+// LL_GPIO_ResetOutputPin(LED_B_GPIO_Port, LED_B_Pin);
+
+ /* Enable I2C for sensors */
+ LL_I2C_Enable(I2C1);
+
+
+ /* Set the modbus address */
+ modbus_slave_set_address(sensor_config.modbus_addr);
+
+ /* Enable UART for RS485 */
+ LL_USART_Enable(USART2);
+
+ /* Start the timer for measurement triggering */
+ LL_TIM_EnableCounter(TIM21);
+ LL_TIM_EnableIT_UPDATE(TIM21);
+
+ /* I2C context init (for SHT4x and SCD4x) */
+ i2c_context_t i2c_context;
+ i2c_context.i2c = I2C1;
+ i2c_init(&i2c_context);
+
+ /* Fill device ID struct */
+ device_id.object_name.VendorName = "Veles Labs";
+ device_id.object_name.ProductCode = "124C41";
+ device_id.object_name.MajorMinorRevision = "1.2";
+ device_id.object_name.VendorUrl = "https://veles-labs.com";
+ device_id.object_name.ProductName = "RHT_Wired";
+ device_id.object_name.ModelName = "Hugo";
+ modbus_slave_init_device_id(&device_id);
+ /* USER CODE END 2 */
+
+ /* Infinite loop */
+ /* USER CODE BEGIN WHILE */
+
+ /* Wait 1000ms for sensors initialization */
+ /* SHT4x Init Time: max 1 ms (datasheet pg. 8) */
+ /* LTR329 Init Time: max 100 ms (datasheet pg. 9) */
+ LL_mDelay(1000);
+
+ /* Initiualize LTR329 */
+ int8_t ltr_ret;
+ uint8_t ltr_cont_reg_val;
+ uint8_t ltr_rate_reg_val;
+ do
+ {
+ ltr_ret = ltr329_write_settings(LTR329_GAIN_48X, LTR329_MODE_ACTIVE, LTR329_INTEGRATION_100MS, LTR329_MEAS_RATE_100MS);
+ /* TODO: Check register status */
+ } while (ltr_ret != 0);
+
+
+ static uint32_t new_baud;
+ /* Enter the main loop */
+ while (1)
+ {
+ /* Watchdog is set to 28 s (37 kHz, prescaler 256, 4095 reload value) */
+ LL_IWDG_ReloadCounter(IWDG);
+ if (usart2_rx_done == 1)
+ {
+ /* Process the message */
+ if (usart2_rx_message_too_long)
+ {
+ /* Do nothing, just delete the buffer and set the flag back to zero*/
+ usart2_rx_message_too_long = 0;
+ } else
+ {
+ /* Process the message:
+ * message is stored in modbus_buffer[], no copying necessary;
+ * but we need to make sure that modbus_buffer[] will not be used while
+ * processing the message: this can be done by disabling RX interrupt */
+ LL_USART_DisableIT_RXNE(USART2);
+ modbus_slave_process_msg(modbus_buffer, usart2_rx_message_len);
+ /* Reset the RX DONE flag */
+ usart2_rx_done = 0;
+ LL_USART_EnableIT_RXNE(USART2);
+ }
+ /* Reset the RX DONE flag */
+ usart2_rx_done = 0;
+ }
+ /* if config changed (MODBUS write), reflect changes to EEPROM */
+ if (sensor_config_pending_write) {
+ config_write(&sensor_config);
+ sensor_config_pending_write = 0;
+ }
+ if (modbus_address_changed)
+ {
+ modbus_slave_set_address(sensor_config.modbus_addr);
+ modbus_address_changed = 0;
+ }
+ if (baudrate_changed)
+ {
+ while (!LL_USART_IsActiveFlag_TXE(USART2));
+ uart_disable_interrupts();
+
+ LL_USART_SetBaudRate(USART2, SYSTICK_FREQ_HZ, LL_USART_OVERSAMPLING_16, config_baudrates[sensor_config.baudrate_index]);
+ uart_enable_interrupts();
+ LL_USART_EnableDirectionRx(USART2);
+ LL_USART_EnableDirectionTx(USART2);
+ baudrate_changed = 0;
+
+ new_baud = LL_USART_GetBaudRate(USART2, SYSTICK_FREQ_HZ, LL_USART_OVERSAMPLING_16);
+ }
+ /* It is time for measurement */
+ if (tim21_elapsed_period == 1)
+ {
+ /* TODO: Check the data */
+ /* Read SHT4x data (always connected) */
+ sht4x_measure(&T_SHT4x, &RH_SHT4x);
+ TF_SHT4x = CELSIUS_TO_FAHRENHEIT(T_SHT4x);
+
+ /* Red LTR329 values */
+ uint8_t data_valid, new_data;
+ ltr329_gain_t set_gain;
+ ltr_ret = ltr329_read_status_register(&data_valid, &new_data, &set_gain);
+ /* TODO: Do something with the flags */
+ ltr_ret = ltr329_measure(&light_ch0, &light_ch1);
+
+ /* Reset the TIM21 Elapsed Period Flag */
+ tim21_elapsed_period = 0;
+ }
+ /* USER CODE END WHILE */
+
+ /* USER CODE BEGIN 3 */
+ }
+ /* USER CODE END 3 */
+}
+
+/**
+ * @brief System Clock Configuration
+ * @retval None
+ */
+void SystemClock_Config(void)
+{
+ LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
+ while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_0)
+ {
+ }
+ LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
+ LL_RCC_HSI_Enable();
+
+ /* Wait till HSI is ready */
+ while(LL_RCC_HSI_IsReady() != 1)
+ {
+
+ }
+ LL_RCC_HSI_SetCalibTrimming(16);
+ LL_RCC_LSI_Enable();
+
+ /* Wait till LSI is ready */
+ while(LL_RCC_LSI_IsReady() != 1)
+ {
+
+ }
+ LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLL_MUL_3, LL_RCC_PLL_DIV_4);
+ LL_RCC_PLL_Enable();
+
+ /* Wait till PLL is ready */
+ while(LL_RCC_PLL_IsReady() != 1)
+ {
+
+ }
+ LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
+ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
+ LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
+ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
+
+ /* Wait till System clock is ready */
+ while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
+ {
+
+ }
+
+ LL_Init1msTick(12000000);
+
+ LL_SetSystemCoreClock(12000000);
+ LL_RCC_SetUSARTClockSource(LL_RCC_USART2_CLKSOURCE_PCLK1);
+ LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
+}
+
+/**
+ * @brief I2C1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_I2C1_Init(void)
+{
+
+ /* USER CODE BEGIN I2C1_Init 0 */
+
+ /* USER CODE END I2C1_Init 0 */
+
+ LL_I2C_InitTypeDef I2C_InitStruct = {0};
+
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
+ /**I2C1 GPIO Configuration
+ PA9 ------> I2C1_SCL
+ PA10 ------> I2C1_SDA
+ */
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
+
+ /* USER CODE BEGIN I2C1_Init 1 */
+
+ /* USER CODE END I2C1_Init 1 */
+ /** I2C Initialization
+ */
+ LL_I2C_EnableAutoEndMode(I2C1);
+ LL_I2C_DisableOwnAddress2(I2C1);
+ LL_I2C_DisableGeneralCall(I2C1);
+ LL_I2C_EnableClockStretching(I2C1);
+ I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
+ I2C_InitStruct.Timing = 0x40000A0B;
+ I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
+ I2C_InitStruct.DigitalFilter = 0;
+ I2C_InitStruct.OwnAddress1 = 0;
+ I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
+ I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
+ 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 */
+
+}
+
+/**
+ * @brief IWDG Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_IWDG_Init(void)
+{
+
+ /* USER CODE BEGIN IWDG_Init 0 */
+
+ /* USER CODE END IWDG_Init 0 */
+
+ /* USER CODE BEGIN IWDG_Init 1 */
+
+ /* USER CODE END IWDG_Init 1 */
+ LL_IWDG_Enable(IWDG);
+ LL_IWDG_EnableWriteAccess(IWDG);
+ LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_256);
+ LL_IWDG_SetReloadCounter(IWDG, 4095);
+ while (LL_IWDG_IsReady(IWDG) != 1)
+ {
+ }
+
+ LL_IWDG_ReloadCounter(IWDG);
+ /* USER CODE BEGIN IWDG_Init 2 */
+
+ /* USER CODE END IWDG_Init 2 */
+
+}
+
+/**
+ * @brief TIM21 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_TIM21_Init(void)
+{
+
+ /* USER CODE BEGIN TIM21_Init 0 */
+
+ /* USER CODE END TIM21_Init 0 */
+
+ LL_TIM_InitTypeDef TIM_InitStruct = {0};
+
+ /* Peripheral clock enable */
+ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM21);
+
+ /* TIM21 interrupt Init */
+ NVIC_SetPriority(TIM21_IRQn, 0);
+ NVIC_EnableIRQ(TIM21_IRQn);
+
+ /* USER CODE BEGIN TIM21_Init 1 */
+
+ /* USER CODE END TIM21_Init 1 */
+ TIM_InitStruct.Prescaler = tim21_prescaler;
+ TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
+ TIM_InitStruct.Autoreload = tim21_period;
+ TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
+ LL_TIM_Init(TIM21, &TIM_InitStruct);
+ LL_TIM_EnableARRPreload(TIM21);
+ LL_TIM_SetClockSource(TIM21, LL_TIM_CLOCKSOURCE_INTERNAL);
+ LL_TIM_SetTriggerOutput(TIM21, LL_TIM_TRGO_RESET);
+ LL_TIM_DisableMasterSlaveMode(TIM21);
+ /* USER CODE BEGIN TIM21_Init 2 */
+
+ /* USER CODE END TIM21_Init 2 */
+
+}
+
+/**
+ * @brief USART2 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_USART2_UART_Init(void)
+{
+
+ /* USER CODE BEGIN USART2_Init 0 */
+
+ /* USER CODE END USART2_Init 0 */
+
+ LL_USART_InitTypeDef USART_InitStruct = {0};
+
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* Peripheral clock enable */
+ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
+
+ LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
+ /**USART2 GPIO Configuration
+ PA1 ------> USART2_DE
+ PA2 ------> USART2_TX
+ PA3 ------> USART2_RX
+ */
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
+ LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* USART2 interrupt Init */
+ NVIC_SetPriority(USART2_IRQn, 0);
+ NVIC_EnableIRQ(USART2_IRQn);
+
+ /* USER CODE BEGIN USART2_Init 1 */
+
+ /* USER CODE END USART2_Init 1 */
+ USART_InitStruct.BaudRate = config_baudrates[sensor_config.baudrate_index];
+ USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_9B;
+ USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
+ USART_InitStruct.Parity = LL_USART_PARITY_EVEN;
+ USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
+ USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
+ USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
+ LL_USART_Init(USART2, &USART_InitStruct);
+ LL_USART_EnableDEMode(USART2);
+ LL_USART_SetDESignalPolarity(USART2, LL_USART_DE_POLARITY_HIGH);
+ LL_USART_SetDEAssertionTime(USART2, 0);
+ LL_USART_SetDEDeassertionTime(USART2, 0);
+ LL_USART_ConfigAsyncMode(USART2);
+ LL_USART_Enable(USART2);
+ /* USER CODE BEGIN USART2_Init 2 */
+
+ /* Enable IDLE Interrupt */
+ LL_USART_EnableIT_IDLE(USART2);
+
+ /* Enable RX Not Empty Interrupt */
+ LL_USART_EnableIT_RXNE(USART2);
+
+ LL_USART_EnableDirectionRx(USART2);
+ LL_USART_EnableDirectionTx(USART2);
+ LL_USART_Enable(USART2);
+ /* USER CODE END USART2_Init 2 */
+
+}
+
+/**
+ * @brief GPIO Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_GPIO_Init(void)
+{
+
+ /* GPIO Ports Clock Enable */
+ LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
+
+}
+
+/* USER CODE BEGIN 4 */
+void USART2_TX_Buffer(uint8_t* buffer_tx, uint16_t buffer_tx_len)
+{
+ __disable_irq();
+ for (uint16_t i = 0; i < buffer_tx_len; i++)
+ {
+ LL_USART_TransmitData9(USART2, buffer_tx[i]);
+ while (!LL_USART_IsActiveFlag_TXE(USART2));
+ }
+ __enable_irq();
+}
+
+int8_t uart_disable_interrupts(void)
+{
+ LL_USART_Disable(USART2);
+ LL_USART_DisableIT_IDLE(USART2);
+ LL_USART_EnableIT_RXNE(USART2);
+
+ return 0;
+}
+
+int8_t uart_enable_interrupts(void)
+{
+ LL_USART_Enable(USART2);
+ LL_USART_EnableIT_IDLE(USART2);
+ LL_USART_EnableIT_RXNE(USART2);
+
+ return 0;
+}
+
+int8_t modbus_slave_callback(modbus_transaction_t *transaction)
+{
+ uint16_t register_number = transaction->register_number;
+ switch (transaction->function_code)
+ {
+ case MODBUS_READ_INPUT_REGISTERS:
+ for (int i = 0; i < transaction->register_count; i++, register_number++)
+ {
+ switch (register_number)
+ {
+ case REGISTER_NUM_T:
+ transaction->input_registers_signed[i] = (int16_t)T_SHT4x;
+ break;
+ case REGISTER_NUM_T_F:
+ transaction->input_registers_signed[i] = (int16_t)TF_SHT4x;
+ break;
+ case REGISTER_NUM_RH:
+ transaction->input_registers[i] = (uint16_t)RH_SHT4x;
+ break;
+ default:
+ return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
+ }
+ }
+ return MODBUS_OK;
+ case MODBUS_READ_HOLDING_REGISTERS:
+ for (int i = 0; i < transaction->register_count; i++, register_number++)
+ {
+ switch (register_number)
+ {
+ case REGISTER_NUM_MODBUS_ADDR:
+ transaction->holding_registers[i] = (uint16_t)(sensor_config.modbus_addr);
+ break;
+ case REGISTER_NUM_BAUDRATE:
+ transaction->holding_registers[i] = (uint16_t)(sensor_config.baudrate_index);
+ break;
+ default:
+ return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
+ }
+ }
+ return MODBUS_OK;
+ case MODBUS_WRITE_SINGLE_REGISTER:
+ transaction->register_count = 1;
+ case MODBUS_WRITE_MULTIPLE_REGISTERS:
+ for (int i = 0; i < transaction->register_count; i++, register_number++)
+ {
+ switch (register_number)
+ {
+ case REGISTER_NUM_MODBUS_ADDR:
+ /* allowed values: [1, 247] (from 1 to 247) as given in section 2.1 of document
+ * MODBUS over Serial Line: Specification and Implementation Guide (V1.02) */
+ if (transaction->holding_registers[i] < 1 || transaction->holding_registers[i] > 247) {
+ return MODBUS_ERROR_OUT_OF_BOUNDS;
+ }
+ sensor_config.modbus_addr = (uint16_t) transaction->holding_registers[i];
+ modbus_address_changed = 1;
+ break;
+ case REGISTER_NUM_BAUDRATE:
+ /* allowed values: [0, 9] (from 0 to 9, where 9 == config_baudrates_length) */
+ if (transaction->holding_registers[i] >= config_baudrates_length) {
+ return MODBUS_ERROR_OUT_OF_BOUNDS;
+ }
+ sensor_config.baudrate_index = (uint16_t) (transaction->holding_registers[i]);
+ baudrate_changed = 1;
+ break;
+ case REGISTER_NUM_RESET_DEVICE:
+ if (transaction->holding_registers[i] == 0xABCD) {
+ /* software reset */
+ NVIC_SystemReset();
+ } else {
+ return MODBUS_ERROR_OUT_OF_BOUNDS;
+ }
+ break;
+ default:
+ return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
+ }
+ }
+ sensor_config_pending_write = 1;
+ return MODBUS_OK;
+ default:
+ return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED;
+ }
+ /* Catch-all error */
+ return MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED; /* nothing implemented yet! TODO */
+}
+
+int8_t modbus_transmit_function(uint8_t *buffer, uint16_t data_len)
+{
+ /* TODO */
+ USART2_TX_Buffer(buffer, data_len);
+ return MODBUS_OK;
+}
+/* USER CODE END 4 */
+
+/**
+ * @brief This function is executed in case of error occurrence.
+ * @retval None
+ */
+void Error_Handler(void)
+{
+ /* USER CODE BEGIN Error_Handler_Debug */
+ /* User can add his own implementation to report the HAL error return state */
+ __disable_irq();
+ while (1)
+ {
+ }
+ /* USER CODE END Error_Handler_Debug */
+}
+
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief Reports the name of the source file and the source line number
+ * where the assert_param error has occurred.
+ * @param file: pointer to the source file name
+ * @param line: assert_param error line source number
+ * @retval None
+ */
+void assert_failed(uint8_t *file, uint32_t line)
+{
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/fw/Core/Src/modbus.c b/fw/Core/Src/modbus.c
new file mode 100644
index 0000000..ddf37b6
--- /dev/null
+++ b/fw/Core/Src/modbus.c
@@ -0,0 +1,431 @@
+/*
+ * modbus.c
+ *
+ * Created on: Jul 18, 2021
+ * Author: user
+ */
+
+#include "modbus.h"
+
+/*
+ * Global variables
+ */
+
+/* Modbus TX buffer; can be also used for RX in memory constrained systems (e.g. in main.c);
+ * NOTE if shared buffer is used for TX/RX, care must be taken to prevent writing into buffer
+ * during execution of modbus_process_message() */
+uint8_t modbus_buffer[MODBUS_MAX_RTU_FRAME_SIZE];
+
+/* MODBUS device address */
+uint8_t modbus_slave_address = MODBUS_DEFAULT_SLAVE_ADDRESS;
+
+/* Device ID struct */
+modbus_device_id_t *modbus_device_id = NULL;
+
+/*
+ * CRC16 functions
+ * see https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
+ * section 6.2.2
+ */
+
+/* CRC16 (without memory mapped values)
+ * taken from https://ctlsys.com/support/how_to_compute_the_modbus_rtu_message_crc/ */
+uint16_t modbus_CRC16(const uint8_t *buf, int len)
+{
+ uint16_t crc = 0xFFFF;
+
+ for (int pos = 0; pos < len; pos++) {
+ crc ^= (uint16_t)buf[pos]; // XOR byte into least sig. byte of crc
+
+ for (int i = 8; i != 0; i--) { // Loop over each bit
+ if ((crc & 0x0001) != 0) { // If the LSB is set
+ crc >>= 1; // Shift right and XOR 0xA001
+ crc ^= 0xA001;
+ } else { // Else LSB is not set
+ crc >>= 1; // Just shift right
+ }
+ }
+ }
+ // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
+ return crc;
+}
+
+/*
+ * Private functions
+ */
+
+static uint8_t modbus_fill_device_id_objects(uint8_t *buffer, modbus_transaction_t *transaction)
+{
+ /* we assume buffer is 256 - MODBUS_READ_DEVICE_ID_RESPONSE_HEADER_LEN = 252 bytes long */
+ /* find out how many objects we copy to buffer */
+ int len;
+ uint8_t object_index = transaction->object_id;
+ uint8_t object_count;
+ uint8_t more_follows = MODBUS_NO_MORE_FOLLOWS;
+ uint8_t next_object_id;
+ uint8_t last_object;
+ const uint8_t max_len = 256 - MODBUS_READ_DEVICE_ID_RESPONSE_HEADER_LEN;
+
+ /* last object index */
+ if (transaction->read_device_id_code == MODBUS_CONFORMITY_BASIC) {
+ last_object = MODBUS_BASIC_OBJECT_COUNT;
+ } else if (transaction->read_device_id_code == MODBUS_CONFORMITY_REGULAR) {
+ last_object = MODBUS_REGULAR_OBJECT_COUNT;
+ /* extended not implemented */
+// } else if (transaction->read_device_id_code == MODBUS_CONFORMITY_EXTENDED){
+// last_object = MODBUS_EXTENDED_OBJECT_COUNT;
+ } else {
+ /* fallback: regular */
+ last_object = MODBUS_REGULAR_OBJECT_COUNT;
+ }
+ last_object--; // we need index
+ /* copy as many objects as possible */
+ do {
+ /* copy object */
+ int object_len = strlen(modbus_device_id->object_id[object_index]);
+ if (len + object_len + 2 > max_len) {
+ more_follows = MODBUS_MORE_FOLLOWS;
+ next_object_id = object_index;
+ break;
+ }
+ /* offset is for "more follows", "next object id", "object count" */
+ buffer[MODBUS_READ_DEVICE_ID_RESPONSE_OFFSET + len++] = object_index;
+ buffer[MODBUS_READ_DEVICE_ID_RESPONSE_OFFSET + len++] = object_len;
+ /* note that string copied to buffer is not null-terminated */
+ strncpy((char*)(buffer + len), (char*)modbus_device_id->object_id[object_index++], object_len);
+ len += object_len;
+ object_count++;
+ } while (object_index < last_object);
+ buffer[0] = more_follows;
+ buffer[1] = next_object_id;
+ buffer[2] = object_count;
+ return MODBUS_READ_DEVICE_ID_RESPONSE_OFFSET + len;
+}
+
+/* here we assume buffer has minimal size of MODBUS_MAX_RTU_FRAME_SIZE;
+ * this function is private, so hopefully it's going to be ok */
+static int8_t modbus_transaction_to_buffer(uint8_t *buffer, uint8_t *msg_len, modbus_transaction_t *transaction)
+{
+ uint16_t crc16;
+ uint8_t byte_count;
+ uint8_t buffer_pos = 0;
+
+ // TODO use relative indices (increments) instead of absolute
+ buffer[buffer_pos++] = modbus_slave_address;
+ buffer[buffer_pos++] = transaction->function_code;
+ *msg_len = 5;
+
+ if (transaction->function_code & MODBUS_ERROR_FLAG) {
+ /* sending error reply */
+ buffer[buffer_pos++] = transaction->exception;
+ } else {
+ switch (transaction->function_code) {
+ case MODBUS_READ_HOLDING_REGISTERS:
+ case MODBUS_READ_INPUT_REGISTERS:
+ byte_count = transaction->register_count * 2;
+ buffer[buffer_pos++] = byte_count;
+ *msg_len = byte_count + 5;
+ for (int i = 0; i < transaction->register_count; i++) {
+ // TODO endianness handling
+ /* buffer16b is alias for both holding and input register buffers */
+ buffer[buffer_pos++] = transaction->buffer16b[i] >> 8;
+ buffer[buffer_pos++] = transaction->buffer16b[i] & 0xff;
+ }
+ break;
+ case MODBUS_WRITE_SINGLE_REGISTER:
+ buffer[buffer_pos++] = (uint8_t) (transaction->register_address >> 8);
+ buffer[buffer_pos++] = (uint8_t) transaction->register_address;
+ buffer[buffer_pos++] = (uint8_t) (transaction->holding_registers[0] >> 8);
+ buffer[buffer_pos++] = (uint8_t) transaction->holding_registers[0];
+ *msg_len = 8; /* includes 2 bytes for CRC */
+ break;
+ case MODBUS_WRITE_MULTIPLE_REGISTERS:
+ buffer[buffer_pos++] = (uint8_t) (transaction->register_address >> 8);
+ buffer[buffer_pos++] = (uint8_t) transaction->register_address;
+ buffer[buffer_pos++] = (uint8_t) (transaction->register_count >> 8);
+ buffer[buffer_pos++] = (uint8_t) transaction->register_count;
+ *msg_len = 8; /* includes 2 bytes for CRC */
+ break;
+ case MODBUS_READ_DEVICE_IDENTIFICATION:
+ /* MEI type */
+ buffer[buffer_pos++] = MODBUS_MEI;
+ /* read device id */
+ buffer[buffer_pos++] = transaction->read_device_id_code;
+ /* conformity level */
+ buffer[buffer_pos++] = modbus_device_id->conformity_level;
+ /* fill buffer with as many objects as possible */
+ *msg_len = modbus_fill_device_id_objects(buffer+buffer_pos, transaction);
+ *msg_len += 7; /* includes 2 bytes for CRC */
+ break;
+ }
+ }
+ crc16 = modbus_CRC16(buffer, buffer_pos); /* last two bytes is the checksum itself */
+ buffer[buffer_pos++] = crc16 & 0xff;
+ buffer[buffer_pos++] = crc16 >> 8;
+ return MODBUS_OK;
+}
+
+static int8_t modbus_process_device_id_request(const uint8_t *buffer, int len, modbus_transaction_t *transaction)
+{
+ uint8_t MEI_type;
+ uint8_t read_device_id_code;
+ uint8_t object_id;
+ uint8_t buffer_pos = 0;
+
+ if (transaction->broadcast == 1) {
+ /* Read device ID broadcast - invalid; ignore (master will get timeout) */
+ return MODBUS_ERROR;
+ }
+ if (modbus_device_id == NULL) {
+ /* modbus_device_id not initialized; user should use modbus_slave_init_device_id() first */
+ transaction->exception = MODBUS_EXCEPTION_ILLEGAL_DEVICE_ID_CODE;
+ return MODBUS_OK;
+ }
+ if (len < MODBUS_READ_DEVICE_ID_REQUEST_LEN) {
+ /* frame too short, ignore */
+ return MODBUS_ERROR;
+ }
+ /* next byte should be MEI = 0x0E */
+ MEI_type = buffer[buffer_pos++];
+ if (MEI_type != MODBUS_MEI) {
+ /* invalid MEI, ignore. I have no idea what MEI does, but it should always be 0x0E */
+ return MODBUS_ERROR;
+ }
+ /* next byte is read device id code */
+ read_device_id_code = buffer[buffer_pos++];
+ /* read device id code can only have values 1,2,3,4 */
+ if (read_device_id_code < 1 || read_device_id_code > 4) {
+ transaction->exception = MODBUS_EXCEPTION_ILLEGAL_DEVICE_ID_CODE;
+ return MODBUS_OK;
+ }
+ transaction->read_device_id_code = read_device_id_code;
+ /* next byte is object id */
+ object_id = buffer[buffer_pos++];
+ transaction->object_id = object_id;
+ if (object_id > MODBUS_DEVICE_ID_OBJECT_NUM) {
+ /* illegal object ID */
+ transaction->exception = MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
+ return MODBUS_OK;
+ }
+ /* Message processed */
+ return MODBUS_OK;
+}
+
+/* returns ERROR only when no response to master is needed */
+static int8_t modbus_process_read_write_request(const uint8_t *buffer, int len, modbus_transaction_t *transaction)
+{
+ uint8_t byte_count;
+ int8_t callback_result;
+ uint8_t buffer_pos = 0;
+
+ /* set starting register number */
+ switch (transaction->function_code) {
+ /* coils */
+ case MODBUS_READ_DO:
+ case MODBUS_WRITE_SINGLE_DO:
+ case MODBUS_WRITE_MULTIPLE_DO:
+ transaction->register_number = MODBUS_DO_START_NUMBER;
+ break;
+ /* discrete inputs */
+ case MODBUS_READ_DI:
+ transaction->register_number = MODBUS_DI_START_NUMBER;
+ break;
+ /* input registers */
+ case MODBUS_READ_AI:
+ transaction->register_number = MODBUS_AI_START_NUMBER;
+ break;
+ /* holding registers */
+ case MODBUS_READ_AO:
+ case MODBUS_WRITE_SINGLE_AO:
+ case MODBUS_WRITE_MULTIPLE_AO:
+ case MODBUS_READ_WRITE_MULTIPLE_REGISTERS:
+ transaction->register_number = MODBUS_AO_START_NUMBER;
+ break;
+ }
+
+ #define MODBUS_FLAG_WRITE 0x01
+ #define MODBUS_FLAG_SINGLE 0x02
+ uint8_t flags = 0x00;
+
+ /* process message */
+ switch (transaction->function_code) {
+ case MODBUS_WRITE_SINGLE_COIL:
+ case MODBUS_WRITE_SINGLE_REGISTER: /* holding register */
+ flags |= MODBUS_FLAG_SINGLE;
+ case MODBUS_WRITE_MULTIPLE_COILS:
+ case MODBUS_WRITE_MULTIPLE_REGISTERS:
+ flags |= MODBUS_FLAG_WRITE;
+ case MODBUS_READ_DISCRETE_INPUTS:
+ case MODBUS_READ_COILS:
+ case MODBUS_READ_INPUT_REGISTERS:
+ case MODBUS_READ_HOLDING_REGISTERS:
+ if (len < MODBUS_MINIMAL_READWRITE_LEN) {
+ /* buffer too short to contain everything we need */
+ return MODBUS_ERROR;
+ }
+ transaction->register_address = (buffer[buffer_pos] << 8) | buffer[buffer_pos + 1];
+ buffer += 2;
+ // TODO check length!
+ if (flags & MODBUS_FLAG_WRITE) {
+ if (flags & MODBUS_FLAG_SINGLE) {
+ transaction->holding_registers[0] = (buffer[buffer_pos] << 8) | buffer[buffer_pos + 1];
+ buffer_pos += 2;
+ } else {
+ /* Write multiple registers */
+ transaction->register_count = (buffer[buffer_pos] << 8) | buffer[buffer_pos + 1];
+ buffer_pos += 2;
+ if (len < MODBUS_MINIMAL_WRITE_MULTIPLE_LEN) {
+ return MODBUS_ERROR;
+ }
+ byte_count = buffer[buffer_pos++];
+ if (transaction->register_count > 123 || 2*transaction->register_count != byte_count) {
+ /* Max number of register is defined by Modbus_Application_Protocol_V1_1b, section 6.12 */
+ transaction->exception = MODBUS_EXCEPTION_ILLEGAL_REGISTER_QUANTITY;
+ } else {
+ if (len < MODBUS_MINIMAL_WRITE_MULTIPLE_LEN + byte_count) {
+ return MODBUS_ERROR;
+ }
+ for (uint8_t i = 0; i < transaction->register_count; i++) {
+ transaction->holding_registers[i] = (buffer[buffer_pos] << 8) | buffer[buffer_pos + 1];
+ buffer_pos += 2;
+ }
+ }
+ }
+ } else {
+ transaction->register_count = (buffer[buffer_pos] << 8) | buffer[buffer_pos + 1];
+ buffer_pos += 2;
+ if (
+ transaction->register_count < 1 ||
+ transaction->register_count > MODBUS_MAX_REGISTERS
+ ) {
+ transaction->exception = MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE;
+ }
+ }
+ // add offset to register number
+ transaction->register_number += transaction->register_address;
+ break;
+ default:
+ /* function code not known / not implemented, reply with
+ * ExceptionCode 1 */
+ transaction->exception = MODBUS_EXCEPTION_ILLEGAL_FUNCTION;
+ break;
+ }
+ /* data in modbus_buffer have been processed and buffer can be re-used for TX */
+ /* handle reply */
+ if (transaction->exception != 0) {
+ /* indicate error */
+ transaction->function_code |= MODBUS_ERROR_FLAG;
+ } else {
+ callback_result = modbus_slave_callback(transaction);
+ /* error handling */
+ if (callback_result != MODBUS_OK) {
+ transaction->function_code |= MODBUS_ERROR_FLAG;
+ if (callback_result == MODBUS_ERROR_FUNCTION_NOT_IMPLEMENTED) {
+ transaction->exception = MODBUS_EXCEPTION_ILLEGAL_FUNCTION;
+ } else if (callback_result == MODBUS_ERROR_REGISTER_NOT_IMPLEMENTED) {
+ transaction->exception = MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
+ }
+ }
+ }
+ return MODBUS_OK;
+}
+
+/*
+ * Public function definitions
+ */
+
+int8_t modbus_slave_set_address(uint8_t address)
+{
+ if (address == 0) {
+ /* address 0 is broadcast address */
+ return MODBUS_ERROR;
+ }
+ modbus_slave_address = address;
+ return MODBUS_OK;
+}
+
+
+int8_t modbus_slave_process_msg(const uint8_t *buffer, int len)
+{
+
+
+ /*
+ * TODO list:
+ *
+ * 1) check that errors and exceptions are handled according to Modbus_Application_Protocol_V1_1b.pdf
+ * 2) buffer overflow prevention: for each function code, check that buffer is long enough
+ */
+
+
+ /* transaction holds message context and content:
+ * it wraps all necessary buffers and variables */
+ modbus_transaction_t transaction;
+ uint8_t buffer_pos = 0;
+
+ if (len < MODBUS_MINIMAL_FRAME_LEN) {
+ /* frame too short; return error (no reply needed) */
+ return MODBUS_ERROR_FRAME_INVALID;
+ }
+ /* check CRC first */
+ uint16_t crc_received = (buffer[len - 1] << 8) | buffer[len - 2];
+ uint16_t crc_calculated = modbus_CRC16(buffer, len - 2);
+ if (crc_received != crc_calculated) {
+ /* CRC mismatch, return error (no reply needed) */
+ return MODBUS_ERROR_CRC;
+ }
+ /* check if address matches ours */
+ uint8_t address = buffer[buffer_pos++];
+ transaction.broadcast = (address == MODBUS_BROADCAST_ADDR);
+ if (address != modbus_slave_address && transaction.broadcast != 1) {
+ /* Message is not for us (no reply needed) */
+ return MODBUS_OK;
+ }
+ /* get function code */
+ transaction.function_code = buffer[buffer_pos++];
+ transaction.exception = 0;
+ uint8_t request_processing_result;
+ if (transaction.function_code == MODBUS_READ_DEVICE_IDENTIFICATION) {
+ /* Read device ID request is quite complicated, therefore it has its own processing function */
+ request_processing_result = modbus_process_device_id_request(buffer + buffer_pos, len - buffer_pos, &transaction);
+ } else {
+ /* process other requests: input register read, holding register read/write */
+ request_processing_result = modbus_process_read_write_request(buffer + buffer_pos, len - buffer_pos, &transaction);
+ }
+ uint8_t msg_len;
+ /* reply only if request was processed successfully and message was not broadcast */
+ if (request_processing_result == MODBUS_OK && transaction.broadcast == 0) {
+ modbus_transaction_to_buffer(modbus_buffer, &msg_len, &transaction);
+ /* send reply */
+ modbus_transmit_function(modbus_buffer, msg_len);
+ }
+ return MODBUS_OK;
+}
+
+int8_t modbus_slave_init_device_id(modbus_device_id_t *device_id)
+{
+ if (device_id == NULL) {
+ return MODBUS_ERROR;
+ }
+ /* at least basic category objects have to be implemented */
+ if ( device_id->object_name.VendorName == NULL ||
+ device_id->object_name.ProductCode == NULL ||
+ device_id->object_name.MajorMinorRevision == NULL
+ ) {
+ return MODBUS_ERROR;
+ }
+ /* set conformity level: currently only "basic" and "regular" is implemented */
+ if ( device_id->object_id[3] != NULL &&
+ device_id->object_id[4] != NULL &&
+ device_id->object_id[5] != NULL
+
+ ) {
+ /* strings are present in regular category (optional) */
+ device_id->conformity_level = MODBUS_CONFORMITY_REGULAR;
+ } else {
+ device_id->conformity_level = MODBUS_CONFORMITY_BASIC;
+ }
+ /* we support both stream and individual access to objects */
+ device_id->conformity_level |= MODBUS_DEVICE_ID_INDIVIDUAL_ACCESS_FLAG;
+ modbus_device_id = device_id;
+ return MODBUS_OK;
+}
diff --git a/fw/Core/Src/sht4x.c b/fw/Core/Src/sht4x.c
new file mode 100644
index 0000000..e17cdf9
--- /dev/null
+++ b/fw/Core/Src/sht4x.c
@@ -0,0 +1,67 @@
+/*
+ * sht4x.c
+ *
+ * Created on: Jun 8, 2021
+ * Author: user
+ */
+
+#include "sht4x.h"
+#include "main.h" /* for uart_disable_interrupts() */
+
+int8_t sht4x_send_cmd(sht4x_cmd_t cmd)
+{
+ return SHT4X_OK;
+}
+
+int8_t sht4x_read_data(uint8_t *buffer, int len)
+{
+ return SHT4X_OK;
+}
+
+int8_t sht4x_measure(int16_t *temperature, uint16_t *relative_humidity)
+{
+ uint8_t buffer[32];
+ int result;
+
+ /* disable interrupts to prevent modbus/i2c conflict */
+ // start measurement
+ buffer[0] = SHT4X_START_MEAS_HIGH_PRECISION;
+ uart_disable_interrupts();
+ result = i2c_transmit(SHT4X_I2C_ADDRESS<<1, buffer, 1);
+ uart_enable_interrupts();
+ if (result != I2C_OK) {
+ return SHT4X_ERROR;
+ }
+ LL_mDelay(10); /* 10 ms should be enough */
+ /* read out */
+ uart_disable_interrupts();
+ result = i2c_receive(SHT4X_I2C_ADDRESS<<1, buffer, 6);
+ uart_enable_interrupts();
+ 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];
+ uint8_t t_crc = buffer[2];
+ uint32_t rh_ticks = (buffer[3] << 8) + buffer[4];
+ uint8_t rh_crc = buffer[5];
+ /* check CRC-8 checksum */
+ uint8_t crc_correct = crc8_calculate(buffer, 2) == t_crc;
+ crc_correct &= crc8_calculate(buffer + 3, 2) == rh_crc;
+ if (!crc_correct) {
+ return SHT4X_CRC8_ERROR;
+ }
+ /* copy data to output variables */
+ int t_degC = -450 + 10 * 175 * t_ticks / 65535; /* temperature * 10 */
+ 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;
+}
diff --git a/fw/Core/Src/stm32l0xx_it.c b/fw/Core/Src/stm32l0xx_it.c
new file mode 100644
index 0000000..5eb65f3
--- /dev/null
+++ b/fw/Core/Src/stm32l0xx_it.c
@@ -0,0 +1,207 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32l0xx_it.c
+ * @brief Interrupt Service Routines.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "stm32l0xx_it.h"
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+#include "modbus.h"
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+uint16_t usart2_rx_message_index = 0;
+uint16_t usart2_rx_message_len = 0;
+uint8_t usart2_rx_done = 0;
+uint8_t usart2_rx_message_too_long = 0;
+
+uint8_t tim21_elapsed_period = 0;
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+void USART2_CharReception_Callback( void );
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* External variables --------------------------------------------------------*/
+
+/* USER CODE BEGIN EV */
+
+/* USER CODE END EV */
+
+/******************************************************************************/
+/* Cortex-M0+ Processor Interruption and Exception Handlers */
+/******************************************************************************/
+/**
+ * @brief This function handles Non maskable Interrupt.
+ */
+void NMI_Handler(void)
+{
+ /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
+
+ /* USER CODE END NonMaskableInt_IRQn 0 */
+ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
+ while (1)
+ {
+ }
+ /* USER CODE END NonMaskableInt_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Hard fault interrupt.
+ */
+void HardFault_Handler(void)
+{
+ /* USER CODE BEGIN HardFault_IRQn 0 */
+
+ /* USER CODE END HardFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_HardFault_IRQn 0 */
+ /* USER CODE END W1_HardFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles System service call via SWI instruction.
+ */
+void SVC_Handler(void)
+{
+ /* USER CODE BEGIN SVC_IRQn 0 */
+
+ /* USER CODE END SVC_IRQn 0 */
+ /* USER CODE BEGIN SVC_IRQn 1 */
+
+ /* USER CODE END SVC_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Pendable request for system service.
+ */
+void PendSV_Handler(void)
+{
+ /* USER CODE BEGIN PendSV_IRQn 0 */
+
+ /* USER CODE END PendSV_IRQn 0 */
+ /* USER CODE BEGIN PendSV_IRQn 1 */
+
+ /* USER CODE END PendSV_IRQn 1 */
+}
+
+/**
+ * @brief This function handles System tick timer.
+ */
+void SysTick_Handler(void)
+{
+ /* USER CODE BEGIN SysTick_IRQn 0 */
+
+ /* USER CODE END SysTick_IRQn 0 */
+
+ /* USER CODE BEGIN SysTick_IRQn 1 */
+ /* USER CODE END SysTick_IRQn 1 */
+}
+
+/******************************************************************************/
+/* STM32L0xx Peripheral Interrupt Handlers */
+/* Add here the Interrupt Handlers for the used peripherals. */
+/* For the available peripheral interrupt handler names, */
+/* please refer to the startup file (startup_stm32l0xx.s). */
+/******************************************************************************/
+
+/**
+ * @brief This function handles TIM21 global interrupt.
+ */
+void TIM21_IRQHandler(void)
+{
+ /* USER CODE BEGIN TIM21_IRQn 0 */
+ LL_TIM_ClearFlag_UPDATE(TIM21);
+ tim21_elapsed_period = 1;
+ /* USER CODE END TIM21_IRQn 0 */
+ /* USER CODE BEGIN TIM21_IRQn 1 */
+
+ /* USER CODE END TIM21_IRQn 1 */
+}
+
+/**
+ * @brief This function handles USART2 global interrupt / USART2 wake-up interrupt through EXTI line 26.
+ */
+void USART2_IRQHandler(void)
+{
+ /* USER CODE BEGIN USART2_IRQn 0 */
+ /* Check RXNE flag value in SR register */
+ if(LL_USART_IsActiveFlag_RXNE(USART2) && LL_USART_IsEnabledIT_RXNE(USART2))
+ {
+ /* RXNE flag will be cleared by reading of DR register (done in call) */
+ /* Call function in charge of handling Character reception */
+ USART2_CharReception_Callback();
+ }
+ /* USER CODE END USART2_IRQn 0 */
+ /* USER CODE BEGIN USART2_IRQn 1 */
+ /* If the IDLE flag is active */
+ if (LL_USART_IsActiveFlag_IDLE(USART2) && LL_USART_IsEnabledIT_IDLE(USART2))
+ {
+ /* Clear the IDLE flag */
+ LL_USART_ClearFlag_IDLE(USART2);
+
+ /* Reset the buffer index */
+ usart2_rx_message_len = usart2_rx_message_index;
+ usart2_rx_message_index = 0;
+ usart2_rx_done = 1;
+ if (usart2_rx_message_len > MODBUS_MAX_RTU_FRAME_SIZE)
+ {
+ usart2_rx_message_too_long = 1;
+ }
+ }
+ /* USER CODE END USART2_IRQn 1 */
+}
+
+/* USER CODE BEGIN 1 */
+void USART2_CharReception_Callback( void )
+{
+ uint16_t usart2_rx_bit = LL_USART_ReceiveData9(USART2);
+ if (usart2_rx_message_index < MODBUS_MAX_RTU_FRAME_SIZE)
+ {
+ modbus_buffer[usart2_rx_message_index] = (uint8_t)usart2_rx_bit;
+ }
+ usart2_rx_message_index++;
+}
+/* USER CODE END 1 */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/fw/Core/Src/syscalls.c b/fw/Core/Src/syscalls.c
new file mode 100644
index 0000000..4ec9584
--- /dev/null
+++ b/fw/Core/Src/syscalls.c
@@ -0,0 +1,159 @@
+/**
+ ******************************************************************************
+ * @file syscalls.c
+ * @author Auto-generated by STM32CubeIDE
+ * @brief STM32CubeIDE Minimal System calls file
+ *
+ * For more information about which c-functions
+ * need which of these lowlevel functions
+ * please consult the Newlib libc-manual
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* Variables */
+//#undef errno
+extern int errno;
+extern int __io_putchar(int ch) __attribute__((weak));
+extern int __io_getchar(void) __attribute__((weak));
+
+register char * stack_ptr asm("sp");
+
+char *__env[1] = { 0 };
+char **environ = __env;
+
+
+/* Functions */
+void initialise_monitor_handles()
+{
+}
+
+int _getpid(void)
+{
+ return 1;
+}
+
+int _kill(int pid, int sig)
+{
+ errno = EINVAL;
+ return -1;
+}
+
+void _exit (int status)
+{
+ _kill(status, -1);
+ while (1) {} /* Make sure we hang here */
+}
+
+__attribute__((weak)) int _read(int file, char *ptr, int len)
+{
+ int DataIdx;
+
+ for (DataIdx = 0; DataIdx < len; DataIdx++)
+ {
+ *ptr++ = __io_getchar();
+ }
+
+return len;
+}
+
+__attribute__((weak)) int _write(int file, char *ptr, int len)
+{
+ int DataIdx;
+
+ for (DataIdx = 0; DataIdx < len; DataIdx++)
+ {
+ __io_putchar(*ptr++);
+ }
+ return len;
+}
+
+int _close(int file)
+{
+ return -1;
+}
+
+
+int _fstat(int file, struct stat *st)
+{
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+int _isatty(int file)
+{
+ return 1;
+}
+
+int _lseek(int file, int ptr, int dir)
+{
+ return 0;
+}
+
+int _open(char *path, int flags, ...)
+{
+ /* Pretend like we always fail */
+ return -1;
+}
+
+int _wait(int *status)
+{
+ errno = ECHILD;
+ return -1;
+}
+
+int _unlink(char *name)
+{
+ errno = ENOENT;
+ return -1;
+}
+
+int _times(struct tms *buf)
+{
+ return -1;
+}
+
+int _stat(char *file, struct stat *st)
+{
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+int _link(char *old, char *new)
+{
+ errno = EMLINK;
+ return -1;
+}
+
+int _fork(void)
+{
+ errno = EAGAIN;
+ return -1;
+}
+
+int _execve(char *name, char **argv, char **env)
+{
+ errno = ENOMEM;
+ return -1;
+}
diff --git a/fw/Core/Src/sysmem.c b/fw/Core/Src/sysmem.c
new file mode 100644
index 0000000..d7cc52c
--- /dev/null
+++ b/fw/Core/Src/sysmem.c
@@ -0,0 +1,80 @@
+/**
+ ******************************************************************************
+ * @file sysmem.c
+ * @author Generated by STM32CubeIDE
+ * @brief STM32CubeIDE System Memory calls file
+ *
+ * For more information about which C functions
+ * need which of these lowlevel functions
+ * please consult the newlib libc manual
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include
+#include
+
+/**
+ * Pointer to the current high watermark of the heap usage
+ */
+static uint8_t *__sbrk_heap_end = NULL;
+
+/**
+ * @brief _sbrk() allocates memory to the newlib heap and is used by malloc
+ * and others from the C library
+ *
+ * @verbatim
+ * ############################################################################
+ * # .data # .bss # newlib heap # MSP stack #
+ * # # # # Reserved by _Min_Stack_Size #
+ * ############################################################################
+ * ^-- RAM start ^-- _end _estack, RAM end --^
+ * @endverbatim
+ *
+ * This implementation starts allocating at the '_end' linker symbol
+ * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
+ * The implementation considers '_estack' linker symbol to be RAM end
+ * NOTE: If the MSP stack, at any point during execution, grows larger than the
+ * reserved size, please increase the '_Min_Stack_Size'.
+ *
+ * @param incr Memory size
+ * @return Pointer to allocated memory
+ */
+void *_sbrk(ptrdiff_t incr)
+{
+ extern uint8_t _end; /* Symbol defined in the linker script */
+ extern uint8_t _estack; /* Symbol defined in the linker script */
+ extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
+ const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
+ const uint8_t *max_heap = (uint8_t *)stack_limit;
+ uint8_t *prev_heap_end;
+
+ /* Initialize heap end at first call */
+ if (NULL == __sbrk_heap_end)
+ {
+ __sbrk_heap_end = &_end;
+ }
+
+ /* Protect heap from growing into the reserved MSP stack */
+ if (__sbrk_heap_end + incr > max_heap)
+ {
+ errno = ENOMEM;
+ return (void *)-1;
+ }
+
+ prev_heap_end = __sbrk_heap_end;
+ __sbrk_heap_end += incr;
+
+ return (void *)prev_heap_end;
+}
diff --git a/fw/Core/Src/system_stm32l0xx.c b/fw/Core/Src/system_stm32l0xx.c
new file mode 100644
index 0000000..9189ed8
--- /dev/null
+++ b/fw/Core/Src/system_stm32l0xx.c
@@ -0,0 +1,275 @@
+/**
+ ******************************************************************************
+ * @file system_stm32l0xx.c
+ * @author MCD Application Team
+ * @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File.
+ *
+ * This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32l0xx.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright(c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32l0xx_system
+ * @{
+ */
+
+/** @addtogroup STM32L0xx_System_Private_Includes
+ * @{
+ */
+
+#include "stm32l0xx.h"
+
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (MSI_VALUE)
+ #define MSI_VALUE ((uint32_t)2097152U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* MSI_VALUE */
+
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32L0xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32L0xx_System_Private_Defines
+ * @{
+ */
+/************************* Miscellaneous Configuration ************************/
+
+/* Note: Following vector table addresses must be defined in line with linker
+ configuration. */
+/*!< Uncomment the following line if you need to relocate the vector table
+ anywhere in Flash or Sram, else the vector table is kept at the automatic
+ remap of boot address selected */
+/* #define USER_VECT_TAB_ADDRESS */
+
+#if defined(USER_VECT_TAB_ADDRESS)
+/*!< Uncomment the following line if you need to relocate your vector Table
+ in Sram else user remap will be done in Flash. */
+/* #define VECT_TAB_SRAM */
+#if defined(VECT_TAB_SRAM)
+#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
+ This value must be a multiple of 0x200. */
+#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+#else
+#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
+ This value must be a multiple of 0x200. */
+#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+#endif /* VECT_TAB_SRAM */
+#endif /* USER_VECT_TAB_ADDRESS */
+
+/******************************************************************************/
+/**
+ * @}
+ */
+
+/** @addtogroup STM32L0xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32L0xx_System_Private_Variables
+ * @{
+ */
+ /* This variable is updated in three ways:
+ 1) by calling CMSIS function SystemCoreClockUpdate()
+ 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
+ 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
+ Note: If you use this function to configure the system clock; then there
+ is no need to call the 2 first functions listed above, since SystemCoreClock
+ variable is updated automatically.
+ */
+ uint32_t SystemCoreClock = 2097152U; /* 32.768 kHz * 2^6 */
+ const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
+ const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
+ const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32L0xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32L0xx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system.
+ * @param None
+ * @retval None
+ */
+void SystemInit (void)
+{
+ /* Configure the Vector Table location add offset address ------------------*/
+#if defined (USER_VECT_TAB_ADDRESS)
+ SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#endif /* USER_VECT_TAB_ADDRESS */
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI
+ * value as defined by the MSI range.
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32l0xx_hal.h file (default value
+ * 16 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value
+ * 8 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate (void)
+{
+ uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00U: /* MSI used as system clock */
+ msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> RCC_ICSCR_MSIRANGE_Pos;
+ SystemCoreClock = (32768U * (1U << (msirange + 1U)));
+ break;
+ case 0x04U: /* HSI used as system clock */
+ if ((RCC->CR & RCC_CR_HSIDIVF) != 0U)
+ {
+ SystemCoreClock = HSI_VALUE / 4U;
+ }
+ else
+ {
+ SystemCoreClock = HSI_VALUE;
+ }
+ break;
+ case 0x08U: /* HSE used as system clock */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ default: /* PLL used as system clock */
+ /* Get PLL clock source and multiplication factor ----------------------*/
+ pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
+ plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
+ pllmul = PLLMulTable[(pllmul >> RCC_CFGR_PLLMUL_Pos)];
+ plldiv = (plldiv >> RCC_CFGR_PLLDIV_Pos) + 1U;
+
+ pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+
+ if (pllsource == 0x00U)
+ {
+ /* HSI oscillator clock selected as PLL clock entry */
+ if ((RCC->CR & RCC_CR_HSIDIVF) != 0U)
+ {
+ SystemCoreClock = (((HSI_VALUE / 4U) * pllmul) / plldiv);
+ }
+ else
+ {
+ SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv);
+ }
+ }
+ else
+ {
+ /* HSE selected as PLL clock entry */
+ SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv);
+ }
+ break;
+ }
+ /* Compute HCLK clock frequency --------------------------------------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
+ /* HCLK clock frequency */
+ SystemCoreClock >>= tmp;
+}
+
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/fw/Core/Startup/startup_stm32l031g6ux.s b/fw/Core/Startup/startup_stm32l031g6ux.s
new file mode 100644
index 0000000..62608af
--- /dev/null
+++ b/fw/Core/Startup/startup_stm32l031g6ux.s
@@ -0,0 +1,261 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32l031xx.s
+ * @author MCD Application Team
+ * @brief STM32L031xx Devices vector table for GCC toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M0+ processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m0plus
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr r0, =_estack
+ mov sp, r0 /* set stack pointer */
+
+/* Copy the data segment initializers from flash to SRAM */
+ ldr r0, =_sdata
+ ldr r1, =_edata
+ ldr r2, =_sidata
+ movs r3, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r4, [r2, r3]
+ str r4, [r0, r3]
+ adds r3, r3, #4
+
+LoopCopyDataInit:
+ adds r4, r0, r3
+ cmp r4, r1
+ bcc CopyDataInit
+
+/* Zero fill the bss segment. */
+ ldr r2, =_sbss
+ ldr r4, =_ebss
+ movs r3, #0
+ b LoopFillZerobss
+
+FillZerobss:
+ str r3, [r2]
+ adds r2, r2, #4
+
+LoopFillZerobss:
+ cmp r2, r4
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+
+LoopForever:
+ b LoopForever
+
+
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M0. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word 0
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word PVD_IRQHandler /* PVD through EXTI Line detection */
+ .word RTC_IRQHandler /* RTC through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_1_IRQHandler /* EXTI Line 0 and 1 */
+ .word EXTI2_3_IRQHandler /* EXTI Line 2 and 3 */
+ .word EXTI4_15_IRQHandler /* EXTI Line 4 to 15 */
+ .word 0 /* Reserved */
+ .word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
+ .word DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */
+ .word DMA1_Channel4_5_6_7_IRQHandler /* DMA1 Channel 4, Channel 5, Channel 6 and Channel 7*/
+ .word ADC1_COMP_IRQHandler /* ADC1, COMP1 and COMP2 */
+ .word LPTIM1_IRQHandler /* LPTIM1 */
+ .word 0 /* Reserved */
+ .word TIM2_IRQHandler /* TIM2 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word TIM21_IRQHandler /* TIM21 */
+ .word 0 /* Reserved */
+ .word TIM22_IRQHandler /* TIM22 */
+ .word I2C1_IRQHandler /* I2C1 */
+ .word 0 /* Reserved */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word USART2_IRQHandler /* USART2 */
+ .word LPUART1_IRQHandler /* LPUART1 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak RTC_IRQHandler
+ .thumb_set RTC_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_1_IRQHandler
+ .thumb_set EXTI0_1_IRQHandler,Default_Handler
+
+ .weak EXTI2_3_IRQHandler
+ .thumb_set EXTI2_3_IRQHandler,Default_Handler
+
+ .weak EXTI4_15_IRQHandler
+ .thumb_set EXTI4_15_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_3_IRQHandler
+ .thumb_set DMA1_Channel2_3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_5_6_7_IRQHandler
+ .thumb_set DMA1_Channel4_5_6_7_IRQHandler,Default_Handler
+
+ .weak ADC1_COMP_IRQHandler
+ .thumb_set ADC1_COMP_IRQHandler,Default_Handler
+
+ .weak LPTIM1_IRQHandler
+ .thumb_set LPTIM1_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM21_IRQHandler
+ .thumb_set TIM21_IRQHandler,Default_Handler
+
+ .weak TIM22_IRQHandler
+ .thumb_set TIM22_IRQHandler,Default_Handler
+
+ .weak I2C1_IRQHandler
+ .thumb_set I2C1_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak LPUART1_IRQHandler
+ .thumb_set LPUART1_IRQHandler,Default_Handler
+
+
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/fw/Debug/Core/Src/config.d b/fw/Debug/Core/Src/config.d
new file mode 100644
index 0000000..7f22991
--- /dev/null
+++ b/fw/Debug/Core/Src/config.d
@@ -0,0 +1,24 @@
+Core/Src/config.o: ../Core/Src/config.c ../Core/Inc/config.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h
+
+../Core/Inc/config.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
diff --git a/fw/Debug/Core/Src/config.o b/fw/Debug/Core/Src/config.o
new file mode 100644
index 0000000..bc1ea56
Binary files /dev/null and b/fw/Debug/Core/Src/config.o differ
diff --git a/fw/Debug/Core/Src/config.su b/fw/Debug/Core/Src/config.su
new file mode 100644
index 0000000..48bcb7f
--- /dev/null
+++ b/fw/Debug/Core/Src/config.su
@@ -0,0 +1,7 @@
+config.c:43:8:config_read 16 static
+config.c:70:8:config_write 16 static
+config.c:135:15:eeprom_lock 24 static
+config.c:165:15:eeprom_unlock 24 static
+config.c:198:15:eeprom_program_byte 16 static
+config.c:213:15:eeprom_program_halfword 16 static
+config.c:229:15:eeprom_program_word 16 static
diff --git a/fw/Debug/Core/Src/crc8.d b/fw/Debug/Core/Src/crc8.d
new file mode 100644
index 0000000..8c3a7ee
--- /dev/null
+++ b/fw/Debug/Core/Src/crc8.d
@@ -0,0 +1,3 @@
+Core/Src/crc8.o: ../Core/Src/crc8.c ../Core/Inc/crc8.h
+
+../Core/Inc/crc8.h:
diff --git a/fw/Debug/Core/Src/crc8.o b/fw/Debug/Core/Src/crc8.o
new file mode 100644
index 0000000..ed3b814
Binary files /dev/null and b/fw/Debug/Core/Src/crc8.o differ
diff --git a/fw/Debug/Core/Src/crc8.su b/fw/Debug/Core/Src/crc8.su
new file mode 100644
index 0000000..d2e1e30
--- /dev/null
+++ b/fw/Debug/Core/Src/crc8.su
@@ -0,0 +1 @@
+crc8.c:11:9:crc8_calculate 24 static
diff --git a/fw/Debug/Core/Src/i2c.d b/fw/Debug/Core/Src/i2c.d
new file mode 100644
index 0000000..73ca01a
--- /dev/null
+++ b/fw/Debug/Core/Src/i2c.d
@@ -0,0 +1,30 @@
+Core/Src/i2c.o: ../Core/Src/i2c.c ../Core/Inc/i2c.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h
+
+../Core/Inc/i2c.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h:
diff --git a/fw/Debug/Core/Src/i2c.o b/fw/Debug/Core/Src/i2c.o
new file mode 100644
index 0000000..087eb2e
Binary files /dev/null and b/fw/Debug/Core/Src/i2c.o differ
diff --git a/fw/Debug/Core/Src/i2c.su b/fw/Debug/Core/Src/i2c.su
new file mode 100644
index 0000000..72ebe84
--- /dev/null
+++ b/fw/Debug/Core/Src/i2c.su
@@ -0,0 +1,11 @@
+stm32l0xx_ll_i2c.h:1553:26:LL_I2C_IsActiveFlag_TXE 16 static
+stm32l0xx_ll_i2c.h:1579:26:LL_I2C_IsActiveFlag_RXNE 16 static
+stm32l0xx_ll_i2c.h:1618:26:LL_I2C_IsActiveFlag_STOP 16 static
+stm32l0xx_ll_i2c.h:1775:22:LL_I2C_ClearFlag_STOP 16 static
+stm32l0xx_ll_i2c.h:1787:22:LL_I2C_ClearFlag_TXE 16 static
+stm32l0xx_ll_i2c.h:2134:22:LL_I2C_HandleTransfer 24 static
+stm32l0xx_ll_i2c.h:2219:25:LL_I2C_ReceiveData8 16 static
+stm32l0xx_ll_i2c.h:2231:22:LL_I2C_TransmitData8 16 static
+i2c.c:13:8:i2c_init 16 static
+i2c.c:22:8:i2c_transmit 40 static
+i2c.c:50:8:i2c_receive 48 static
diff --git a/fw/Debug/Core/Src/ltr329.d b/fw/Debug/Core/Src/ltr329.d
new file mode 100644
index 0000000..3451003
--- /dev/null
+++ b/fw/Debug/Core/Src/ltr329.d
@@ -0,0 +1,83 @@
+Core/Src/ltr329.o: ../Core/Src/ltr329.c ../Core/Inc/ltr329.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h \
+ ../Core/Inc/i2c.h ../Core/Inc/main.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h \
+ ../Core/Inc/sht4x.h ../Core/Inc/crc8.h ../Core/Inc/ltr329.h \
+ ../Core/Inc/modbus.h ../Core/Inc/config.h
+
+../Core/Inc/ltr329.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h:
+
+../Core/Inc/i2c.h:
+
+../Core/Inc/main.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h:
+
+../Core/Inc/sht4x.h:
+
+../Core/Inc/crc8.h:
+
+../Core/Inc/ltr329.h:
+
+../Core/Inc/modbus.h:
+
+../Core/Inc/config.h:
diff --git a/fw/Debug/Core/Src/ltr329.o b/fw/Debug/Core/Src/ltr329.o
new file mode 100644
index 0000000..b1fb5f6
Binary files /dev/null and b/fw/Debug/Core/Src/ltr329.o differ
diff --git a/fw/Debug/Core/Src/ltr329.su b/fw/Debug/Core/Src/ltr329.su
new file mode 100644
index 0000000..8609a1a
--- /dev/null
+++ b/fw/Debug/Core/Src/ltr329.su
@@ -0,0 +1,8 @@
+ltr329.c:10:15:ltr329_read_register 40 static
+ltr329.c:38:15:ltr329_write_register 32 static
+ltr329.c:56:8:ltr329_write_settings 32 static
+ltr329.c:75:8:ltr329_read_settings 48 static
+ltr329.c:108:8:ltr329_sw_reset 24 static
+ltr329.c:120:8:ltr329_measure 24 static
+ltr329.c:150:8:ltr329_read_status_register 40 static
+ltr329.c:188:8:ltr329_read_device_info 32 static
diff --git a/fw/Debug/Core/Src/main.d b/fw/Debug/Core/Src/main.d
new file mode 100644
index 0000000..8e2f4fd
--- /dev/null
+++ b/fw/Debug/Core/Src/main.d
@@ -0,0 +1,80 @@
+Core/Src/main.o: ../Core/Src/main.c ../Core/Inc/main.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h \
+ ../Core/Inc/i2c.h ../Core/Inc/sht4x.h ../Core/Inc/crc8.h \
+ ../Core/Inc/ltr329.h ../Core/Inc/modbus.h ../Core/Inc/config.h
+
+../Core/Inc/main.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h:
+
+../Core/Inc/i2c.h:
+
+../Core/Inc/sht4x.h:
+
+../Core/Inc/crc8.h:
+
+../Core/Inc/ltr329.h:
+
+../Core/Inc/modbus.h:
+
+../Core/Inc/config.h:
diff --git a/fw/Debug/Core/Src/main.o b/fw/Debug/Core/Src/main.o
new file mode 100644
index 0000000..496c6ac
Binary files /dev/null and b/fw/Debug/Core/Src/main.o differ
diff --git a/fw/Debug/Core/Src/main.su b/fw/Debug/Core/Src/main.su
new file mode 100644
index 0000000..4939b09
--- /dev/null
+++ b/fw/Debug/Core/Src/main.su
@@ -0,0 +1,72 @@
+core_cm0plus.h:741:22:__NVIC_EnableIRQ 16 static
+core_cm0plus.h:848:22:__NVIC_SetPriority 24 static
+core_cm0plus.h:983:34:__NVIC_SystemReset 8 static,ignoring_inline_asm
+stm32l0xx_ll_i2c.h:430:22:LL_I2C_Enable 16 static
+stm32l0xx_ll_i2c.h:645:22:LL_I2C_EnableClockStretching 16 static
+stm32l0xx_ll_i2c.h:765:22:LL_I2C_DisableGeneralCall 16 static
+stm32l0xx_ll_i2c.h:876:22:LL_I2C_SetOwnAddress2 24 static
+stm32l0xx_ll_i2c.h:898:22:LL_I2C_DisableOwnAddress2 16 static
+stm32l0xx_ll_i2c.h:1880:22:LL_I2C_EnableAutoEndMode 16 static
+stm32l0xx_ll_iwdg.h:142:22:LL_IWDG_Enable 16 static
+stm32l0xx_ll_iwdg.h:153:22:LL_IWDG_ReloadCounter 16 static
+stm32l0xx_ll_iwdg.h:164:22:LL_IWDG_EnableWriteAccess 16 static
+stm32l0xx_ll_iwdg.h:194:22:LL_IWDG_SetPrescaler 16 static
+stm32l0xx_ll_iwdg.h:224:22:LL_IWDG_SetReloadCounter 16 static
+stm32l0xx_ll_iwdg.h:312:26:LL_IWDG_IsReady 16 static
+stm32l0xx_ll_rcc.h:782:22:LL_RCC_HSI_Enable 8 static
+stm32l0xx_ll_rcc.h:802:26:LL_RCC_HSI_IsReady 8 static
+stm32l0xx_ll_rcc.h:893:22:LL_RCC_HSI_SetCalibTrimming 16 static
+stm32l0xx_ll_rcc.h:1125:22:LL_RCC_LSI_Enable 8 static
+stm32l0xx_ll_rcc.h:1145:26:LL_RCC_LSI_IsReady 8 static
+stm32l0xx_ll_rcc.h:1275:22:LL_RCC_SetSysClkSource 16 static
+stm32l0xx_ll_rcc.h:1289:26:LL_RCC_GetSysClkSource 8 static
+stm32l0xx_ll_rcc.h:1309:22:LL_RCC_SetAHBPrescaler 16 static
+stm32l0xx_ll_rcc.h:1325:22:LL_RCC_SetAPB1Prescaler 16 static
+stm32l0xx_ll_rcc.h:1341:22:LL_RCC_SetAPB2Prescaler 16 static
+stm32l0xx_ll_rcc.h:1481:22:LL_RCC_SetUSARTClockSource 16 static
+stm32l0xx_ll_rcc.h:1515:22:LL_RCC_SetI2CClockSource 16 static
+stm32l0xx_ll_rcc.h:1784:22:LL_RCC_PLL_Enable 8 static
+stm32l0xx_ll_rcc.h:1805:26:LL_RCC_PLL_IsReady 8 static
+stm32l0xx_ll_rcc.h:1834:22:LL_RCC_PLL_ConfigDomain_SYS 24 static
+stm32l0xx_ll_bus.h:440:22:LL_APB1_GRP1_EnableClock 24 static
+stm32l0xx_ll_bus.h:786:22:LL_APB2_GRP1_EnableClock 24 static
+stm32l0xx_ll_bus.h:987:22:LL_IOP_GRP1_EnableClock 24 static
+stm32l0xx_ll_system.h:912:22:LL_FLASH_SetLatency 16 static
+stm32l0xx_ll_system.h:924:26:LL_FLASH_GetLatency 8 static
+stm32l0xx_ll_pwr.h:272:22:LL_PWR_SetRegulVoltageScaling 16 static
+stm32l0xx_ll_tim.h:910:22:LL_TIM_EnableCounter 16 static
+stm32l0xx_ll_tim.h:1090:22:LL_TIM_EnableARRPreload 16 static
+stm32l0xx_ll_tim.h:2228:22:LL_TIM_SetClockSource 16 static
+stm32l0xx_ll_tim.h:2274:22:LL_TIM_SetTriggerOutput 16 static
+stm32l0xx_ll_tim.h:2340:22:LL_TIM_DisableMasterSlaveMode 16 static
+stm32l0xx_ll_tim.h:2808:22:LL_TIM_EnableIT_UPDATE 16 static
+stm32l0xx_ll_usart.h:536:22:LL_USART_Enable 16 static
+stm32l0xx_ll_usart.h:550:22:LL_USART_Disable 16 static
+stm32l0xx_ll_usart.h:649:22:LL_USART_EnableDirectionRx 32 static,ignoring_inline_asm
+stm32l0xx_ll_usart.h:671:22:LL_USART_EnableDirectionTx 32 static,ignoring_inline_asm
+stm32l0xx_ll_usart.h:1608:22:LL_USART_SetBaudRate 32 static
+stm32l0xx_ll_usart.h:1640:26:LL_USART_GetBaudRate 32 static
+stm32l0xx_ll_usart.h:2140:22:LL_USART_SetDEDeassertionTime 16 static
+stm32l0xx_ll_usart.h:2167:22:LL_USART_SetDEAssertionTime 16 static
+stm32l0xx_ll_usart.h:2193:22:LL_USART_EnableDEMode 16 static
+stm32l0xx_ll_usart.h:2235:22:LL_USART_SetDESignalPolarity 16 static
+stm32l0xx_ll_usart.h:2288:22:LL_USART_ConfigAsyncMode 16 static
+stm32l0xx_ll_usart.h:2630:26:LL_USART_IsActiveFlag_TXE 16 static
+stm32l0xx_ll_usart.h:2985:22:LL_USART_EnableIT_IDLE 32 static,ignoring_inline_asm
+stm32l0xx_ll_usart.h:2996:22:LL_USART_EnableIT_RXNE 32 static,ignoring_inline_asm
+stm32l0xx_ll_usart.h:3145:22:LL_USART_DisableIT_IDLE 32 static,ignoring_inline_asm
+stm32l0xx_ll_usart.h:3156:22:LL_USART_DisableIT_RXNE 32 static,ignoring_inline_asm
+stm32l0xx_ll_usart.h:3639:22:LL_USART_TransmitData9 16 static
+main.c:135:5:main 32 static
+main.c:316:6:SystemClock_Config 8 static
+main.c:369:13:MX_I2C1_Init 72 static
+main.c:432:13:MX_IWDG_Init 8 static
+main.c:462:13:MX_TIM21_Init 24 static
+main.c:501:13:MX_USART2_UART_Init 72 static
+main.c:586:13:MX_GPIO_Init 8 static
+main.c:595:6:USART2_TX_Buffer 24 static,ignoring_inline_asm
+main.c:606:8:uart_disable_interrupts 8 static
+main.c:615:8:uart_enable_interrupts 8 static
+main.c:624:8:modbus_slave_callback 32 static
+main.c:709:8:modbus_transmit_function 16 static
+main.c:721:6:Error_Handler 8 static,ignoring_inline_asm
diff --git a/fw/Debug/Core/Src/modbus.d b/fw/Debug/Core/Src/modbus.d
new file mode 100644
index 0000000..0071433
--- /dev/null
+++ b/fw/Debug/Core/Src/modbus.d
@@ -0,0 +1,3 @@
+Core/Src/modbus.o: ../Core/Src/modbus.c ../Core/Inc/modbus.h
+
+../Core/Inc/modbus.h:
diff --git a/fw/Debug/Core/Src/modbus.o b/fw/Debug/Core/Src/modbus.o
new file mode 100644
index 0000000..cf2f3fa
Binary files /dev/null and b/fw/Debug/Core/Src/modbus.o differ
diff --git a/fw/Debug/Core/Src/modbus.su b/fw/Debug/Core/Src/modbus.su
new file mode 100644
index 0000000..25823df
--- /dev/null
+++ b/fw/Debug/Core/Src/modbus.su
@@ -0,0 +1,8 @@
+modbus.c:33:10:modbus_CRC16 32 static
+modbus.c:57:16:modbus_fill_device_id_objects 40 static
+modbus.c:107:15:modbus_transaction_to_buffer 56 static
+modbus.c:168:15:modbus_process_device_id_request 32 static
+modbus.c:215:15:modbus_process_read_write_request 40 static
+modbus.c:337:8:modbus_slave_set_address 16 static
+modbus.c:348:8:modbus_slave_process_msg 312 static
+modbus.c:404:8:modbus_slave_init_device_id 16 static
diff --git a/fw/Debug/Core/Src/rgbled.su b/fw/Debug/Core/Src/rgbled.su
new file mode 100644
index 0000000..eb03236
--- /dev/null
+++ b/fw/Debug/Core/Src/rgbled.su
@@ -0,0 +1,9 @@
+stm32l0xx_ll_tim.h:1687:22:LL_TIM_OC_SetCompareCH1 16 static
+stm32l0xx_ll_tim.h:1701:22:LL_TIM_OC_SetCompareCH2 16 static
+stm32l0xx_ll_tim.h:1715:22:LL_TIM_OC_SetCompareCH3 16 static
+stm32l0xx_ll_tim.h:1729:22:LL_TIM_OC_SetCompareCH4 16 static
+rgbled.c:13:8:rgbled_init 16 static
+rgbled.c:23:8:rgbled_set_color 32 static
+rgbled.c:57:8:rgbled_set_intensity 16 static
+rgbled.c:65:8:rgbled_get_intensity 16 static
+rgbled.c:73:8:rgbled_off 8 static
diff --git a/fw/Debug/Core/Src/scd4x.su b/fw/Debug/Core/Src/scd4x.su
new file mode 100644
index 0000000..71202f8
--- /dev/null
+++ b/fw/Debug/Core/Src/scd4x.su
@@ -0,0 +1,7 @@
+scd4x.c:11:8:scd4x_send_cmd 56 static
+scd4x.c:28:8:scd4x_get_serial 40 static
+scd4x.c:41:8:scd4x_read_data 16 static
+scd4x.c:46:8:scd4x_start_periodic_measurement 8 static
+scd4x.c:51:8:scd4x_stop_periodic_measurement 8 static
+scd4x.c:56:8:scd4x_perform_factory_reset 8 static
+scd4x.c:61:8:scd4x_read_measurement 112 static
diff --git a/fw/Debug/Core/Src/sensirion_gas_index_algorithm.su b/fw/Debug/Core/Src/sensirion_gas_index_algorithm.su
new file mode 100644
index 0000000..8b6c496
--- /dev/null
+++ b/fw/Debug/Core/Src/sensirion_gas_index_algorithm.su
@@ -0,0 +1,29 @@
+sensirion_gas_index_algorithm.c:44:23:fix16_from_int 16 static
+sensirion_gas_index_algorithm.c:48:23:fix16_cast_to_int 16 static
+sensirion_gas_index_algorithm.c:64:16:fix16_mul 72 static
+sensirion_gas_index_algorithm.c:119:16:fix16_div 40 static
+sensirion_gas_index_algorithm.c:188:16:fix16_sqrt 32 static
+sensirion_gas_index_algorithm.c:245:16:fix16_exp 32 static
+sensirion_gas_index_algorithm.c:321:6:GasIndexAlgorithm_init 16 static
+sensirion_gas_index_algorithm.c:353:6:GasIndexAlgorithm_reset 16 static
+sensirion_gas_index_algorithm.c:360:13:GasIndexAlgorithm__init_instances 24 static
+sensirion_gas_index_algorithm.c:380:6:GasIndexAlgorithm_get_states 24 static
+sensirion_gas_index_algorithm.c:388:6:GasIndexAlgorithm_set_states 32 static
+sensirion_gas_index_algorithm.c:400:6:GasIndexAlgorithm_set_tuning_parameters 24 static
+sensirion_gas_index_algorithm.c:416:6:GasIndexAlgorithm_get_tuning_parameters 24 static
+sensirion_gas_index_algorithm.c:433:6:GasIndexAlgorithm_process 32 static
+sensirion_gas_index_algorithm.c:477:13:GasIndexAlgorithm__mean_variance_estimator__set_parameters 16 static
+sensirion_gas_index_algorithm.c:523:13:GasIndexAlgorithm__mean_variance_estimator__set_states 24 static
+sensirion_gas_index_algorithm.c:533:16:GasIndexAlgorithm__mean_variance_estimator__get_std 16 static
+sensirion_gas_index_algorithm.c:539:16:GasIndexAlgorithm__mean_variance_estimator__get_mean 16 static
+sensirion_gas_index_algorithm.c:546:13:GasIndexAlgorithm__mean_variance_estimator__is_initialized 16 static
+sensirion_gas_index_algorithm.c:552:13:GasIndexAlgorithm__mean_variance_estimator___calculate_gamma 64 static
+sensirion_gas_index_algorithm.c:647:13:GasIndexAlgorithm__mean_variance_estimator__process 48 static
+sensirion_gas_index_algorithm.c:711:1:GasIndexAlgorithm__mean_variance_estimator___sigmoid__set_parameters 24 static
+sensirion_gas_index_algorithm.c:718:16:GasIndexAlgorithm__mean_variance_estimator___sigmoid__process 24 static
+sensirion_gas_index_algorithm.c:734:13:GasIndexAlgorithm__mox_model__set_parameters 24 static
+sensirion_gas_index_algorithm.c:742:1:GasIndexAlgorithm__mox_model__process 16 static
+sensirion_gas_index_algorithm.c:758:13:GasIndexAlgorithm__sigmoid_scaled__set_parameters 24 static
+sensirion_gas_index_algorithm.c:768:1:GasIndexAlgorithm__sigmoid_scaled__process 32 static
+sensirion_gas_index_algorithm.c:804:13:GasIndexAlgorithm__adaptive_lowpass__set_parameters 16 static
+sensirion_gas_index_algorithm.c:817:1:GasIndexAlgorithm__adaptive_lowpass__process 40 static
diff --git a/fw/Debug/Core/Src/sgp40.su b/fw/Debug/Core/Src/sgp40.su
new file mode 100644
index 0000000..d4b9482
--- /dev/null
+++ b/fw/Debug/Core/Src/sgp40.su
@@ -0,0 +1,7 @@
+sgp40.c:10:8:sgp40_send_cmd 56 static
+sgp40.c:27:8:sgp40_measure_raw_signal 64 static
+sgp40.c:66:8:sgp40_measure_raw_signal_compensated 72 static
+sgp40.c:106:8:SGP40_execute_self_test 48 static
+sgp40.c:133:8:SGP40_get_serial_number 56 static
+sgp40.c:162:8:SGP40_turn_heater_off 8 static
+sgp40.c:166:8:SGP40_soft_reset 8 static
diff --git a/fw/Debug/Core/Src/sgp4x.su b/fw/Debug/Core/Src/sgp4x.su
new file mode 100644
index 0000000..ddd8a5f
--- /dev/null
+++ b/fw/Debug/Core/Src/sgp4x.su
@@ -0,0 +1,7 @@
+sgp4x.c:10:8:sgp4x_send_cmd 56 static
+sgp4x.c:27:8:sgp4x_measure_raw_signal 64 static
+sgp4x.c:67:8:sgp4x_measure_raw_signal_compensated 72 static
+sgp4x.c:107:8:sgp4x_execute_self_test 48 static
+sgp4x.c:134:8:sgp4x_get_serial_number 56 static
+sgp4x.c:163:8:sgp4x_turn_heater_off 8 static
+sgp4x.c:167:8:sgp4x_soft_reset 8 static
diff --git a/fw/Debug/Core/Src/sht4x.d b/fw/Debug/Core/Src/sht4x.d
new file mode 100644
index 0000000..90a7801
--- /dev/null
+++ b/fw/Debug/Core/Src/sht4x.d
@@ -0,0 +1,83 @@
+Core/Src/sht4x.o: ../Core/Src/sht4x.c ../Core/Inc/sht4x.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h \
+ ../Core/Inc/i2c.h ../Core/Inc/crc8.h ../Core/Inc/main.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h \
+ ../Core/Inc/sht4x.h ../Core/Inc/ltr329.h ../Core/Inc/modbus.h \
+ ../Core/Inc/config.h
+
+../Core/Inc/sht4x.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h:
+
+../Core/Inc/i2c.h:
+
+../Core/Inc/crc8.h:
+
+../Core/Inc/main.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h:
+
+../Core/Inc/sht4x.h:
+
+../Core/Inc/ltr329.h:
+
+../Core/Inc/modbus.h:
+
+../Core/Inc/config.h:
diff --git a/fw/Debug/Core/Src/sht4x.o b/fw/Debug/Core/Src/sht4x.o
new file mode 100644
index 0000000..f59a513
Binary files /dev/null and b/fw/Debug/Core/Src/sht4x.o differ
diff --git a/fw/Debug/Core/Src/sht4x.su b/fw/Debug/Core/Src/sht4x.su
new file mode 100644
index 0000000..4624627
--- /dev/null
+++ b/fw/Debug/Core/Src/sht4x.su
@@ -0,0 +1,3 @@
+sht4x.c:11:8:sht4x_send_cmd 16 static
+sht4x.c:16:8:sht4x_read_data 16 static
+sht4x.c:21:8:sht4x_measure 96 static
diff --git a/fw/Debug/Core/Src/sps30.su b/fw/Debug/Core/Src/sps30.su
new file mode 100644
index 0000000..97ea19e
--- /dev/null
+++ b/fw/Debug/Core/Src/sps30.su
@@ -0,0 +1,10 @@
+sps30.c:10:8:sps30_send_cmd 56 static
+sps30.c:27:8:sps30_start_measurement 16 static
+sps30.c:46:8:sps30_stop_measurement 8 static
+sps30.c:51:8:sps30_read_measured_values 88 static
+sps30.c:99:8:sps30_sleep 8 static
+sps30.c:104:8:sps30_wake_up 8 static
+sps30.c:109:8:sps30_start_fan_cleaning 8 static
+sps30.c:114:8:sps30_reset 8 static
+sps30.c:119:8:sps30_read_status_register 16 static
+sps30.c:140:8:sps30_read_firmware_version 32 static
diff --git a/fw/Debug/Core/Src/stm32l0xx_it.d b/fw/Debug/Core/Src/stm32l0xx_it.d
new file mode 100644
index 0000000..1576e0d
--- /dev/null
+++ b/fw/Debug/Core/Src/stm32l0xx_it.d
@@ -0,0 +1,85 @@
+Core/Src/stm32l0xx_it.o: ../Core/Src/stm32l0xx_it.c ../Core/Inc/main.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h \
+ ../Core/Inc/i2c.h ../Core/Inc/sht4x.h ../Core/Inc/crc8.h \
+ ../Core/Inc/ltr329.h ../Core/Inc/modbus.h ../Core/Inc/config.h \
+ ../Core/Inc/stm32l0xx_it.h ../Core/Inc/modbus.h
+
+../Core/Inc/main.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_iwdg.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_crs.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_cortex.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h:
+
+../Core/Inc/i2c.h:
+
+../Core/Inc/sht4x.h:
+
+../Core/Inc/crc8.h:
+
+../Core/Inc/ltr329.h:
+
+../Core/Inc/modbus.h:
+
+../Core/Inc/config.h:
+
+../Core/Inc/stm32l0xx_it.h:
+
+../Core/Inc/modbus.h:
diff --git a/fw/Debug/Core/Src/stm32l0xx_it.o b/fw/Debug/Core/Src/stm32l0xx_it.o
new file mode 100644
index 0000000..d21bf48
Binary files /dev/null and b/fw/Debug/Core/Src/stm32l0xx_it.o differ
diff --git a/fw/Debug/Core/Src/stm32l0xx_it.su b/fw/Debug/Core/Src/stm32l0xx_it.su
new file mode 100644
index 0000000..081cea6
--- /dev/null
+++ b/fw/Debug/Core/Src/stm32l0xx_it.su
@@ -0,0 +1,15 @@
+stm32l0xx_ll_tim.h:2577:22:LL_TIM_ClearFlag_UPDATE 16 static
+stm32l0xx_ll_usart.h:2597:26:LL_USART_IsActiveFlag_IDLE 16 static
+stm32l0xx_ll_usart.h:2608:26:LL_USART_IsActiveFlag_RXNE 16 static
+stm32l0xx_ll_usart.h:2867:22:LL_USART_ClearFlag_IDLE 16 static
+stm32l0xx_ll_usart.h:3305:26:LL_USART_IsEnabledIT_IDLE 16 static
+stm32l0xx_ll_usart.h:3316:26:LL_USART_IsEnabledIT_RXNE 16 static
+stm32l0xx_ll_usart.h:3615:26:LL_USART_ReceiveData9 16 static
+stm32l0xx_it.c:76:6:NMI_Handler 8 static
+stm32l0xx_it.c:91:6:HardFault_Handler 8 static
+stm32l0xx_it.c:106:6:SVC_Handler 8 static
+stm32l0xx_it.c:119:6:PendSV_Handler 8 static
+stm32l0xx_it.c:132:6:SysTick_Handler 8 static
+stm32l0xx_it.c:152:6:TIM21_IRQHandler 8 static
+stm32l0xx_it.c:166:6:USART2_IRQHandler 8 static
+stm32l0xx_it.c:197:6:USART2_CharReception_Callback 24 static
diff --git a/fw/Debug/Core/Src/subdir.mk b/fw/Debug/Core/Src/subdir.mk
new file mode 100644
index 0000000..29a9eb4
--- /dev/null
+++ b/fw/Debug/Core/Src/subdir.mk
@@ -0,0 +1,57 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (9-2020-q2-update)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+C_SRCS += \
+../Core/Src/config.c \
+../Core/Src/crc8.c \
+../Core/Src/i2c.c \
+../Core/Src/ltr329.c \
+../Core/Src/main.c \
+../Core/Src/modbus.c \
+../Core/Src/sht4x.c \
+../Core/Src/stm32l0xx_it.c \
+../Core/Src/syscalls.c \
+../Core/Src/sysmem.c \
+../Core/Src/system_stm32l0xx.c
+
+OBJS += \
+./Core/Src/config.o \
+./Core/Src/crc8.o \
+./Core/Src/i2c.o \
+./Core/Src/ltr329.o \
+./Core/Src/main.o \
+./Core/Src/modbus.o \
+./Core/Src/sht4x.o \
+./Core/Src/stm32l0xx_it.o \
+./Core/Src/syscalls.o \
+./Core/Src/sysmem.o \
+./Core/Src/system_stm32l0xx.o
+
+C_DEPS += \
+./Core/Src/config.d \
+./Core/Src/crc8.d \
+./Core/Src/i2c.d \
+./Core/Src/ltr329.d \
+./Core/Src/main.d \
+./Core/Src/modbus.d \
+./Core/Src/sht4x.d \
+./Core/Src/stm32l0xx_it.d \
+./Core/Src/syscalls.d \
+./Core/Src/sysmem.d \
+./Core/Src/system_stm32l0xx.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Core/Src/%.o: ../Core/Src/%.c Core/Src/subdir.mk
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m0plus -std=gnu11 -g3 -DDEBUG -DSTM32L031xx -DUSE_FULL_LL_DRIVER -DHSE_VALUE=8000000 -DHSE_STARTUP_TIMEOUT=100 -DLSE_STARTUP_TIMEOUT=5000 -DLSE_VALUE=32768 -DMSI_VALUE=2097000 -DHSI_VALUE=16000000 -DLSI_VALUE=37000 -DVDD_VALUE=3300 -DPREFETCH_ENABLE=0 -DINSTRUCTION_CACHE_ENABLE=1 -DDATA_CACHE_ENABLE=1 -c -I../Core/Inc -I../Drivers/STM32L0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32L0xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@"
+
+clean: clean-Core-2f-Src
+
+clean-Core-2f-Src:
+ -$(RM) ./Core/Src/config.d ./Core/Src/config.o ./Core/Src/crc8.d ./Core/Src/crc8.o ./Core/Src/i2c.d ./Core/Src/i2c.o ./Core/Src/ltr329.d ./Core/Src/ltr329.o ./Core/Src/main.d ./Core/Src/main.o ./Core/Src/modbus.d ./Core/Src/modbus.o ./Core/Src/sht4x.d ./Core/Src/sht4x.o ./Core/Src/stm32l0xx_it.d ./Core/Src/stm32l0xx_it.o ./Core/Src/syscalls.d ./Core/Src/syscalls.o ./Core/Src/sysmem.d ./Core/Src/sysmem.o ./Core/Src/system_stm32l0xx.d ./Core/Src/system_stm32l0xx.o
+
+.PHONY: clean-Core-2f-Src
+
diff --git a/fw/Debug/Core/Src/syscalls.d b/fw/Debug/Core/Src/syscalls.d
new file mode 100644
index 0000000..8667c70
--- /dev/null
+++ b/fw/Debug/Core/Src/syscalls.d
@@ -0,0 +1 @@
+Core/Src/syscalls.o: ../Core/Src/syscalls.c
diff --git a/fw/Debug/Core/Src/syscalls.o b/fw/Debug/Core/Src/syscalls.o
new file mode 100644
index 0000000..35c51de
Binary files /dev/null and b/fw/Debug/Core/Src/syscalls.o differ
diff --git a/fw/Debug/Core/Src/syscalls.su b/fw/Debug/Core/Src/syscalls.su
new file mode 100644
index 0000000..2a6e0d7
--- /dev/null
+++ b/fw/Debug/Core/Src/syscalls.su
@@ -0,0 +1,18 @@
+syscalls.c:48:6:initialise_monitor_handles 8 static
+syscalls.c:52:5:_getpid 8 static
+syscalls.c:57:5:_kill 16 static
+syscalls.c:63:6:_exit 16 static
+syscalls.c:69:27:_read 32 static
+syscalls.c:81:27:_write 32 static
+syscalls.c:92:5:_close 16 static
+syscalls.c:98:5:_fstat 16 static
+syscalls.c:104:5:_isatty 16 static
+syscalls.c:109:5:_lseek 24 static
+syscalls.c:114:5:_open 20 static
+syscalls.c:120:5:_wait 16 static
+syscalls.c:126:5:_unlink 16 static
+syscalls.c:132:5:_times 16 static
+syscalls.c:137:5:_stat 16 static
+syscalls.c:143:5:_link 16 static
+syscalls.c:149:5:_fork 8 static
+syscalls.c:155:5:_execve 24 static
diff --git a/fw/Debug/Core/Src/sysmem.d b/fw/Debug/Core/Src/sysmem.d
new file mode 100644
index 0000000..74fecf9
--- /dev/null
+++ b/fw/Debug/Core/Src/sysmem.d
@@ -0,0 +1 @@
+Core/Src/sysmem.o: ../Core/Src/sysmem.c
diff --git a/fw/Debug/Core/Src/sysmem.o b/fw/Debug/Core/Src/sysmem.o
new file mode 100644
index 0000000..08ad8e4
Binary files /dev/null and b/fw/Debug/Core/Src/sysmem.o differ
diff --git a/fw/Debug/Core/Src/sysmem.su b/fw/Debug/Core/Src/sysmem.su
new file mode 100644
index 0000000..4474c68
--- /dev/null
+++ b/fw/Debug/Core/Src/sysmem.su
@@ -0,0 +1 @@
+sysmem.c:54:7:_sbrk 32 static
diff --git a/fw/Debug/Core/Src/system_stm32l0xx.d b/fw/Debug/Core/Src/system_stm32l0xx.d
new file mode 100644
index 0000000..74b8b33
--- /dev/null
+++ b/fw/Debug/Core/Src/system_stm32l0xx.d
@@ -0,0 +1,22 @@
+Core/Src/system_stm32l0xx.o: ../Core/Src/system_stm32l0xx.c \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
diff --git a/fw/Debug/Core/Src/system_stm32l0xx.o b/fw/Debug/Core/Src/system_stm32l0xx.o
new file mode 100644
index 0000000..a8b0e8f
Binary files /dev/null and b/fw/Debug/Core/Src/system_stm32l0xx.o differ
diff --git a/fw/Debug/Core/Src/system_stm32l0xx.su b/fw/Debug/Core/Src/system_stm32l0xx.su
new file mode 100644
index 0000000..abf8ac4
--- /dev/null
+++ b/fw/Debug/Core/Src/system_stm32l0xx.su
@@ -0,0 +1,2 @@
+system_stm32l0xx.c:154:6:SystemInit 8 static
+system_stm32l0xx.c:200:6:SystemCoreClockUpdate 32 static
diff --git a/fw/Debug/Core/Startup/startup_stm32l031g6ux.d b/fw/Debug/Core/Startup/startup_stm32l031g6ux.d
new file mode 100644
index 0000000..7d3851e
--- /dev/null
+++ b/fw/Debug/Core/Startup/startup_stm32l031g6ux.d
@@ -0,0 +1,2 @@
+Core/Startup/startup_stm32l031g6ux.o: \
+ ../Core/Startup/startup_stm32l031g6ux.s
diff --git a/fw/Debug/Core/Startup/startup_stm32l031g6ux.o b/fw/Debug/Core/Startup/startup_stm32l031g6ux.o
new file mode 100644
index 0000000..6346957
Binary files /dev/null and b/fw/Debug/Core/Startup/startup_stm32l031g6ux.o differ
diff --git a/fw/Debug/Core/Startup/subdir.mk b/fw/Debug/Core/Startup/subdir.mk
new file mode 100644
index 0000000..7ce5abc
--- /dev/null
+++ b/fw/Debug/Core/Startup/subdir.mk
@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (9-2020-q2-update)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+S_SRCS += \
+../Core/Startup/startup_stm32l031g6ux.s
+
+OBJS += \
+./Core/Startup/startup_stm32l031g6ux.o
+
+S_DEPS += \
+./Core/Startup/startup_stm32l031g6ux.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Core/Startup/%.o: ../Core/Startup/%.s Core/Startup/subdir.mk
+ arm-none-eabi-gcc -mcpu=cortex-m0plus -g3 -DDEBUG -c -x assembler-with-cpp -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" "$<"
+
+clean: clean-Core-2f-Startup
+
+clean-Core-2f-Startup:
+ -$(RM) ./Core/Startup/startup_stm32l031g6ux.d ./Core/Startup/startup_stm32l031g6ux.o
+
+.PHONY: clean-Core-2f-Startup
+
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.d
new file mode 100644
index 0000000..574bbb2
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.d
@@ -0,0 +1,29 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_dma.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.o
new file mode 100644
index 0000000..edee53c
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.su
new file mode 100644
index 0000000..b001bd0
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.su
@@ -0,0 +1,17 @@
+stm32l0xx_ll_dma.h:580:22:LL_DMA_ConfigTransfer 24 static
+stm32l0xx_ll_dma.h:933:22:LL_DMA_SetDataLength 24 static
+stm32l0xx_ll_dma.h:1018:22:LL_DMA_SetMemoryAddress 24 static
+stm32l0xx_ll_dma.h:1040:22:LL_DMA_SetPeriphAddress 24 static
+stm32l0xx_ll_dma.h:1207:22:LL_DMA_SetPeriphRequest 24 static
+stm32l0xx_ll_dma.h:1593:22:LL_DMA_ClearFlag_GI1 16 static
+stm32l0xx_ll_dma.h:1604:22:LL_DMA_ClearFlag_GI2 16 static
+stm32l0xx_ll_dma.h:1615:22:LL_DMA_ClearFlag_GI3 16 static
+stm32l0xx_ll_dma.h:1626:22:LL_DMA_ClearFlag_GI4 16 static
+stm32l0xx_ll_dma.h:1637:22:LL_DMA_ClearFlag_GI5 16 static
+stm32l0xx_ll_dma.h:1649:22:LL_DMA_ClearFlag_GI6 16 static
+stm32l0xx_ll_dma.h:1662:22:LL_DMA_ClearFlag_GI7 16 static
+stm32l0xx_ll_bus.h:301:22:LL_AHB1_GRP1_ForceReset 16 static
+stm32l0xx_ll_bus.h:326:22:LL_AHB1_GRP1_ReleaseReset 16 static
+stm32l0xx_ll_dma.c:150:13:LL_DMA_DeInit 24 static
+stm32l0xx_ll_dma.c:275:13:LL_DMA_Init 24 static
+stm32l0xx_ll_dma.c:343:6:LL_DMA_StructInit 16 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.d
new file mode 100644
index 0000000..f44d767
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.d
@@ -0,0 +1,26 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_exti.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.o
new file mode 100644
index 0000000..c18abf9
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.su
new file mode 100644
index 0000000..bad8ae9
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.su
@@ -0,0 +1,11 @@
+stm32l0xx_ll_exti.h:274:22:LL_EXTI_EnableIT_0_31 16 static
+stm32l0xx_ll_exti.h:322:22:LL_EXTI_DisableIT_0_31 16 static
+stm32l0xx_ll_exti.h:425:22:LL_EXTI_EnableEvent_0_31 16 static
+stm32l0xx_ll_exti.h:472:22:LL_EXTI_DisableEvent_0_31 16 static
+stm32l0xx_ll_exti.h:572:22:LL_EXTI_EnableRisingTrig_0_31 16 static
+stm32l0xx_ll_exti.h:618:22:LL_EXTI_DisableRisingTrig_0_31 16 static
+stm32l0xx_ll_exti.h:710:22:LL_EXTI_EnableFallingTrig_0_31 16 static
+stm32l0xx_ll_exti.h:754:22:LL_EXTI_DisableFallingTrig_0_31 16 static
+stm32l0xx_ll_exti.c:80:10:LL_EXTI_DeInit 8 static
+stm32l0xx_ll_exti.c:105:10:LL_EXTI_Init 24 static
+stm32l0xx_ll_exti.c:186:6:LL_EXTI_StructInit 16 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.d
new file mode 100644
index 0000000..4250a7b
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.d
@@ -0,0 +1,29 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_gpio.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.o
new file mode 100644
index 0000000..7a68888
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.su
new file mode 100644
index 0000000..85319e8
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.su
@@ -0,0 +1,11 @@
+stm32l0xx_ll_gpio.h:270:22:LL_GPIO_SetPinMode 24 static
+stm32l0xx_ll_gpio.h:338:22:LL_GPIO_SetPinOutputType 24 static
+stm32l0xx_ll_gpio.h:409:22:LL_GPIO_SetPinSpeed 24 static
+stm32l0xx_ll_gpio.h:478:22:LL_GPIO_SetPinPull 24 static
+stm32l0xx_ll_gpio.h:541:22:LL_GPIO_SetAFPin_0_7 24 static
+stm32l0xx_ll_gpio.h:602:22:LL_GPIO_SetAFPin_8_15 24 static
+stm32l0xx_ll_bus.h:1064:22:LL_IOP_GRP1_ForceReset 16 static
+stm32l0xx_ll_bus.h:1089:22:LL_IOP_GRP1_ReleaseReset 16 static
+stm32l0xx_ll_gpio.c:96:13:LL_GPIO_DeInit 24 static
+stm32l0xx_ll_gpio.c:157:13:LL_GPIO_Init 24 static
+stm32l0xx_ll_gpio.c:231:6:LL_GPIO_StructInit 16 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.d
new file mode 100644
index 0000000..9e60e6a
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.d
@@ -0,0 +1,29 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_i2c.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.o
new file mode 100644
index 0000000..e2ec0d4
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.su
new file mode 100644
index 0000000..e88c568
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.su
@@ -0,0 +1,14 @@
+stm32l0xx_ll_i2c.h:430:22:LL_I2C_Enable 16 static
+stm32l0xx_ll_i2c.h:444:22:LL_I2C_Disable 16 static
+stm32l0xx_ll_i2c.h:476:22:LL_I2C_ConfigFilters 24 static
+stm32l0xx_ll_i2c.h:820:22:LL_I2C_SetOwnAddress1 24 static
+stm32l0xx_ll_i2c.h:831:22:LL_I2C_EnableOwnAddress1 16 static
+stm32l0xx_ll_i2c.h:842:22:LL_I2C_DisableOwnAddress1 16 static
+stm32l0xx_ll_i2c.h:923:22:LL_I2C_SetTiming 16 static
+stm32l0xx_ll_i2c.h:997:22:LL_I2C_SetMode 16 static
+stm32l0xx_ll_i2c.h:1978:22:LL_I2C_AcknowledgeNextData 16 static
+stm32l0xx_ll_bus.h:595:22:LL_APB1_GRP1_ForceReset 16 static
+stm32l0xx_ll_bus.h:646:22:LL_APB1_GRP1_ReleaseReset 16 static
+stm32l0xx_ll_i2c.c:87:13:LL_I2C_DeInit 24 static
+stm32l0xx_ll_i2c.c:139:13:LL_I2C_Init 16 static
+stm32l0xx_ll_i2c.c:207:6:LL_I2C_StructInit 16 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.d
new file mode 100644
index 0000000..5fb7fe7
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.d
@@ -0,0 +1,29 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.o
new file mode 100644
index 0000000..c2f918b
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.su
new file mode 100644
index 0000000..c2f6d7c
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.su
@@ -0,0 +1,3 @@
+stm32l0xx_ll_bus.h:595:22:LL_APB1_GRP1_ForceReset 16 static
+stm32l0xx_ll_bus.h:646:22:LL_APB1_GRP1_ReleaseReset 16 static
+stm32l0xx_ll_pwr.c:56:13:LL_PWR_DeInit 8 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.d
new file mode 100644
index 0000000..347b2da
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.d
@@ -0,0 +1,26 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.o
new file mode 100644
index 0000000..5d04881
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.su
new file mode 100644
index 0000000..384afc3
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.su
@@ -0,0 +1,35 @@
+stm32l0xx_ll_rcc.h:705:22:LL_RCC_HSE_DisableBypass 8 static
+stm32l0xx_ll_rcc.h:802:26:LL_RCC_HSI_IsReady 8 static
+stm32l0xx_ll_rcc.h:893:22:LL_RCC_HSI_SetCalibTrimming 16 static
+stm32l0xx_ll_rcc.h:1097:26:LL_RCC_LSE_IsReady 8 static
+stm32l0xx_ll_rcc.h:1145:26:LL_RCC_LSI_IsReady 8 static
+stm32l0xx_ll_rcc.h:1163:22:LL_RCC_MSI_Enable 8 static
+stm32l0xx_ll_rcc.h:1183:26:LL_RCC_MSI_IsReady 8 static
+stm32l0xx_ll_rcc.h:1201:22:LL_RCC_MSI_SetRange 16 static
+stm32l0xx_ll_rcc.h:1218:26:LL_RCC_MSI_GetRange 8 static
+stm32l0xx_ll_rcc.h:1242:22:LL_RCC_MSI_SetCalibTrimming 16 static
+stm32l0xx_ll_rcc.h:1289:26:LL_RCC_GetSysClkSource 8 static
+stm32l0xx_ll_rcc.h:1360:26:LL_RCC_GetAHBPrescaler 8 static
+stm32l0xx_ll_rcc.h:1375:26:LL_RCC_GetAPB1Prescaler 8 static
+stm32l0xx_ll_rcc.h:1390:26:LL_RCC_GetAPB2Prescaler 8 static
+stm32l0xx_ll_rcc.h:1586:26:LL_RCC_GetUSARTClockSource 16 static
+stm32l0xx_ll_rcc.h:1604:26:LL_RCC_GetLPUARTClockSource 16 static
+stm32l0xx_ll_rcc.h:1625:26:LL_RCC_GetI2CClockSource 16 static
+stm32l0xx_ll_rcc.h:1641:26:LL_RCC_GetLPTIMClockSource 16 static
+stm32l0xx_ll_rcc.h:1805:26:LL_RCC_PLL_IsReady 8 static
+stm32l0xx_ll_rcc.h:1859:26:LL_RCC_PLL_GetMainSource 8 static
+stm32l0xx_ll_rcc.h:1878:26:LL_RCC_PLL_GetMultiplicator 8 static
+stm32l0xx_ll_rcc.h:1891:26:LL_RCC_PLL_GetDivider 8 static
+stm32l0xx_ll_rcc.h:2097:26:LL_RCC_IsActiveFlag_HSIDIV 8 static
+stm32l0xx_ll_rcc.h:2189:22:LL_RCC_ClearResetFlags 8 static
+stm32l0xx_ll_rcc.c:112:13:LL_RCC_DeInit 16 static,ignoring_inline_asm
+stm32l0xx_ll_rcc.c:222:6:LL_RCC_GetSystemClocksFreq 16 static
+stm32l0xx_ll_rcc.c:247:10:LL_RCC_GetUSARTClockFreq 24 static
+stm32l0xx_ll_rcc.c:344:10:LL_RCC_GetI2CClockFreq 24 static
+stm32l0xx_ll_rcc.c:423:10:LL_RCC_GetLPUARTClockFreq 24 static
+stm32l0xx_ll_rcc.c:474:10:LL_RCC_GetLPTIMClockFreq 24 static
+stm32l0xx_ll_rcc.c:579:17:RCC_GetSystemClockFreq 16 static
+stm32l0xx_ll_rcc.c:622:17:RCC_GetHCLKClockFreq 16 static
+stm32l0xx_ll_rcc.c:633:17:RCC_GetPCLK1ClockFreq 16 static
+stm32l0xx_ll_rcc.c:644:17:RCC_GetPCLK2ClockFreq 16 static
+stm32l0xx_ll_rcc.c:654:17:RCC_PLL_GetFreqDomain_SYS 24 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.d
new file mode 100644
index 0000000..c2f6a0c
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.d
@@ -0,0 +1,29 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_tim.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.o
new file mode 100644
index 0000000..67c10da
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.su
new file mode 100644
index 0000000..b2c127e
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.su
@@ -0,0 +1,29 @@
+stm32l0xx_ll_tim.h:1201:22:LL_TIM_SetPrescaler 16 static
+stm32l0xx_ll_tim.h:1226:22:LL_TIM_SetAutoReload 16 static
+stm32l0xx_ll_tim.h:1687:22:LL_TIM_OC_SetCompareCH1 16 static
+stm32l0xx_ll_tim.h:1701:22:LL_TIM_OC_SetCompareCH2 16 static
+stm32l0xx_ll_tim.h:1715:22:LL_TIM_OC_SetCompareCH3 16 static
+stm32l0xx_ll_tim.h:1729:22:LL_TIM_OC_SetCompareCH4 16 static
+stm32l0xx_ll_tim.h:2245:22:LL_TIM_SetEncoderMode 16 static
+stm32l0xx_ll_tim.h:3218:22:LL_TIM_GenerateEvent_UPDATE 16 static
+stm32l0xx_ll_bus.h:595:22:LL_APB1_GRP1_ForceReset 16 static
+stm32l0xx_ll_bus.h:646:22:LL_APB1_GRP1_ReleaseReset 16 static
+stm32l0xx_ll_bus.h:873:22:LL_APB2_GRP1_ForceReset 16 static
+stm32l0xx_ll_bus.h:900:22:LL_APB2_GRP1_ReleaseReset 16 static
+stm32l0xx_ll_tim.c:146:13:LL_TIM_DeInit 24 static
+stm32l0xx_ll_tim.c:205:6:LL_TIM_StructInit 16 static
+stm32l0xx_ll_tim.c:223:13:LL_TIM_Init 24 static
+stm32l0xx_ll_tim.c:268:6:LL_TIM_OC_StructInit 16 static
+stm32l0xx_ll_tim.c:291:13:LL_TIM_OC_Init 40 static
+stm32l0xx_ll_tim.c:323:6:LL_TIM_IC_StructInit 16 static
+stm32l0xx_ll_tim.c:346:13:LL_TIM_IC_Init 40 static
+stm32l0xx_ll_tim.c:377:6:LL_TIM_ENCODER_StructInit 16 static
+stm32l0xx_ll_tim.c:400:13:LL_TIM_ENCODER_Init 24 static
+stm32l0xx_ll_tim.c:476:20:OC1Config 32 static
+stm32l0xx_ll_tim.c:535:20:OC2Config 32 static
+stm32l0xx_ll_tim.c:594:20:OC3Config 32 static
+stm32l0xx_ll_tim.c:653:20:OC4Config 32 static
+stm32l0xx_ll_tim.c:713:20:IC1Config 16 static
+stm32l0xx_ll_tim.c:746:20:IC2Config 16 static
+stm32l0xx_ll_tim.c:779:20:IC3Config 16 static
+stm32l0xx_ll_tim.c:812:20:IC4Config 16 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.d
new file mode 100644
index 0000000..f9ac5af
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.d
@@ -0,0 +1,32 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_usart.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_bus.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.o
new file mode 100644
index 0000000..0adb160
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.su
new file mode 100644
index 0000000..1e696af
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.su
@@ -0,0 +1,12 @@
+stm32l0xx_ll_usart.h:561:26:LL_USART_IsEnabled 16 static
+stm32l0xx_ll_usart.h:1016:22:LL_USART_DisableSCLKOutput 16 static
+stm32l0xx_ll_usart.h:1045:22:LL_USART_SetStopBitsLength 16 static
+stm32l0xx_ll_usart.h:1470:22:LL_USART_SetHWFlowCtrl 16 static
+stm32l0xx_ll_usart.h:1608:22:LL_USART_SetBaudRate 32 static
+stm32l0xx_ll_bus.h:595:22:LL_APB1_GRP1_ForceReset 16 static
+stm32l0xx_ll_bus.h:646:22:LL_APB1_GRP1_ReleaseReset 16 static
+stm32l0xx_ll_usart.c:116:13:LL_USART_DeInit 24 static
+stm32l0xx_ll_usart.c:187:13:LL_USART_Init 24 static
+stm32l0xx_ll_usart.c:303:6:LL_USART_StructInit 16 static
+stm32l0xx_ll_usart.c:329:13:LL_USART_ClockInit 24 static
+stm32l0xx_ll_usart.c:387:6:LL_USART_ClockStructInit 16 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.d b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.d
new file mode 100644
index 0000000..f0cea2f
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.d
@@ -0,0 +1,35 @@
+Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.o: \
+ ../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h \
+ ../Drivers/CMSIS/Include/core_cm0plus.h \
+ ../Drivers/CMSIS/Include/cmsis_version.h \
+ ../Drivers/CMSIS/Include/cmsis_compiler.h \
+ ../Drivers/CMSIS/Include/cmsis_gcc.h \
+ ../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h \
+ ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_rcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l0xx.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/stm32l031xx.h:
+
+../Drivers/CMSIS/Include/core_cm0plus.h:
+
+../Drivers/CMSIS/Include/cmsis_version.h:
+
+../Drivers/CMSIS/Include/cmsis_compiler.h:
+
+../Drivers/CMSIS/Include/cmsis_gcc.h:
+
+../Drivers/CMSIS/Device/ST/STM32L0xx/Include/system_stm32l0xx.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_utils.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_system.h:
+
+../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_ll_pwr.h:
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.o b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.o
new file mode 100644
index 0000000..9de46cf
Binary files /dev/null and b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.o differ
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.su b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.su
new file mode 100644
index 0000000..77b5e99
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.su
@@ -0,0 +1,27 @@
+stm32l0xx_ll_rcc.h:695:22:LL_RCC_HSE_EnableBypass 8 static
+stm32l0xx_ll_rcc.h:705:22:LL_RCC_HSE_DisableBypass 8 static
+stm32l0xx_ll_rcc.h:715:22:LL_RCC_HSE_Enable 8 static
+stm32l0xx_ll_rcc.h:735:26:LL_RCC_HSE_IsReady 8 static
+stm32l0xx_ll_rcc.h:782:22:LL_RCC_HSI_Enable 8 static
+stm32l0xx_ll_rcc.h:802:26:LL_RCC_HSI_IsReady 8 static
+stm32l0xx_ll_rcc.h:1275:22:LL_RCC_SetSysClkSource 16 static
+stm32l0xx_ll_rcc.h:1289:26:LL_RCC_GetSysClkSource 8 static
+stm32l0xx_ll_rcc.h:1309:22:LL_RCC_SetAHBPrescaler 16 static
+stm32l0xx_ll_rcc.h:1325:22:LL_RCC_SetAPB1Prescaler 16 static
+stm32l0xx_ll_rcc.h:1341:22:LL_RCC_SetAPB2Prescaler 16 static
+stm32l0xx_ll_rcc.h:1784:22:LL_RCC_PLL_Enable 8 static
+stm32l0xx_ll_rcc.h:1805:26:LL_RCC_PLL_IsReady 8 static
+stm32l0xx_ll_rcc.h:1834:22:LL_RCC_PLL_ConfigDomain_SYS 24 static
+stm32l0xx_ll_utils.h:220:22:LL_InitTick 16 static
+stm32l0xx_ll_system.h:912:22:LL_FLASH_SetLatency 16 static
+stm32l0xx_ll_system.h:924:26:LL_FLASH_GetLatency 8 static
+stm32l0xx_ll_pwr.h:285:26:LL_PWR_GetRegulVoltageScaling 8 static
+stm32l0xx_ll_utils.c:147:6:LL_Init1msTick 16 static
+stm32l0xx_ll_utils.c:163:6:LL_mDelay 24 static
+stm32l0xx_ll_utils.c:225:6:LL_SetSystemCoreClock 16 static
+stm32l0xx_ll_utils.c:239:13:LL_SetFlashLatency 32 static
+stm32l0xx_ll_utils.c:338:13:LL_PLL_ConfigSystemClock_HSI 32 static
+stm32l0xx_ll_utils.c:397:13:LL_PLL_ConfigSystemClock_HSE 40 static
+stm32l0xx_ll_utils.c:467:17:UTILS_GetPLLOutputFrequency 24 static
+stm32l0xx_ll_utils.c:497:20:UTILS_PLL_IsBusy 16 static
+stm32l0xx_ll_utils.c:521:20:UTILS_EnablePLLAndSwitchSystem 32 static
diff --git a/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/subdir.mk b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/subdir.mk
new file mode 100644
index 0000000..eab64fa
--- /dev/null
+++ b/fw/Debug/Drivers/STM32L0xx_HAL_Driver/Src/subdir.mk
@@ -0,0 +1,51 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (9-2020-q2-update)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+C_SRCS += \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.c \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.c \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.c \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.c \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.c \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.c \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.c \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.c \
+../Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.c
+
+OBJS += \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.o \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.o \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.o \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.o \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.o \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.o \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.o \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.o \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.o
+
+C_DEPS += \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.d \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.d \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.d \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.d \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.d \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.d \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.d \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.d \
+./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Drivers/STM32L0xx_HAL_Driver/Src/%.o: ../Drivers/STM32L0xx_HAL_Driver/Src/%.c Drivers/STM32L0xx_HAL_Driver/Src/subdir.mk
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m0plus -std=gnu11 -g3 -DDEBUG -DSTM32L031xx -DUSE_FULL_LL_DRIVER -DHSE_VALUE=8000000 -DHSE_STARTUP_TIMEOUT=100 -DLSE_STARTUP_TIMEOUT=5000 -DLSE_VALUE=32768 -DMSI_VALUE=2097000 -DHSI_VALUE=16000000 -DLSI_VALUE=37000 -DVDD_VALUE=3300 -DPREFETCH_ENABLE=0 -DINSTRUCTION_CACHE_ENABLE=1 -DDATA_CACHE_ENABLE=1 -c -I../Core/Inc -I../Drivers/STM32L0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32L0xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@"
+
+clean: clean-Drivers-2f-STM32L0xx_HAL_Driver-2f-Src
+
+clean-Drivers-2f-STM32L0xx_HAL_Driver-2f-Src:
+ -$(RM) ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.o ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.o ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.o ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.o ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.o ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.o ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.o ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.o ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.d ./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.o
+
+.PHONY: clean-Drivers-2f-STM32L0xx_HAL_Driver-2f-Src
+
diff --git a/fw/Debug/makefile b/fw/Debug/makefile
new file mode 100644
index 0000000..b242be0
--- /dev/null
+++ b/fw/Debug/makefile
@@ -0,0 +1,99 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (9-2020-q2-update)
+################################################################################
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include Drivers/STM32L0xx_HAL_Driver/Src/subdir.mk
+-include Core/Startup/subdir.mk
+-include Core/Src/subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(S_DEPS)),)
+-include $(S_DEPS)
+endif
+ifneq ($(strip $(S_UPPER_DEPS)),)
+-include $(S_UPPER_DEPS)
+endif
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+OPTIONAL_TOOL_DEPS := \
+$(wildcard ../makefile.defs) \
+$(wildcard ../makefile.init) \
+$(wildcard ../makefile.targets) \
+
+
+BUILD_ARTIFACT_NAME := rht_wired_sensor
+BUILD_ARTIFACT_EXTENSION := elf
+BUILD_ARTIFACT_PREFIX :=
+BUILD_ARTIFACT := $(BUILD_ARTIFACT_PREFIX)$(BUILD_ARTIFACT_NAME)$(if $(BUILD_ARTIFACT_EXTENSION),.$(BUILD_ARTIFACT_EXTENSION),)
+
+# Add inputs and outputs from these tool invocations to the build variables
+EXECUTABLES += \
+rht_wired_sensor.elf \
+
+SIZE_OUTPUT += \
+default.size.stdout \
+
+OBJDUMP_LIST += \
+rht_wired_sensor.list \
+
+OBJCOPY_BIN += \
+rht_wired_sensor.bin \
+
+
+# All Target
+all: main-build
+
+# Main-build Target
+main-build: rht_wired_sensor.elf secondary-outputs
+
+# Tool invocations
+rht_wired_sensor.elf: $(OBJS) $(USER_OBJS) /home/david/VelesLabs/Smart\ Household/wired_sensors/RHT_Wired_Sensor/fw/STM32L031G6UX_FLASH.ld makefile objects.list $(OPTIONAL_TOOL_DEPS)
+ arm-none-eabi-gcc -o "rht_wired_sensor.elf" @"objects.list" $(USER_OBJS) $(LIBS) -mcpu=cortex-m0plus -T"/home/david/VelesLabs/Smart Household/wired_sensors/RHT_Wired_Sensor/fw/STM32L031G6UX_FLASH.ld" --specs=nosys.specs -Wl,-Map="rht_wired_sensor.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
+ @echo 'Finished building target: $@'
+ @echo ' '
+
+default.size.stdout: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+ arm-none-eabi-size $(EXECUTABLES)
+ @echo 'Finished building: $@'
+ @echo ' '
+
+rht_wired_sensor.list: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+ arm-none-eabi-objdump -h -S $(EXECUTABLES) > "rht_wired_sensor.list"
+ @echo 'Finished building: $@'
+ @echo ' '
+
+rht_wired_sensor.bin: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+ arm-none-eabi-objcopy -O binary $(EXECUTABLES) "rht_wired_sensor.bin"
+ @echo 'Finished building: $@'
+ @echo ' '
+
+# Other Targets
+clean:
+ -$(RM) default.size.stdout rht_wired_sensor.bin rht_wired_sensor.elf rht_wired_sensor.list
+ -@echo ' '
+
+secondary-outputs: $(SIZE_OUTPUT) $(OBJDUMP_LIST) $(OBJCOPY_BIN)
+
+fail-specified-linker-script-missing:
+ @echo 'Error: Cannot find the specified linker script. Check the linker settings in the build configuration.'
+ @exit 2
+
+warn-no-linker-script-specified:
+ @echo 'Warning: No linker script specified. Check the linker settings in the build configuration.'
+
+.PHONY: all clean dependents main-build fail-specified-linker-script-missing warn-no-linker-script-specified
+
+-include ../makefile.targets
diff --git a/fw/Debug/objects.list b/fw/Debug/objects.list
new file mode 100644
index 0000000..b27f206
--- /dev/null
+++ b/fw/Debug/objects.list
@@ -0,0 +1,21 @@
+"./Core/Src/config.o"
+"./Core/Src/crc8.o"
+"./Core/Src/i2c.o"
+"./Core/Src/ltr329.o"
+"./Core/Src/main.o"
+"./Core/Src/modbus.o"
+"./Core/Src/sht4x.o"
+"./Core/Src/stm32l0xx_it.o"
+"./Core/Src/syscalls.o"
+"./Core/Src/sysmem.o"
+"./Core/Src/system_stm32l0xx.o"
+"./Core/Startup/startup_stm32l031g6ux.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_dma.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_exti.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_gpio.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_i2c.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_pwr.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_rcc.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_tim.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_usart.o"
+"./Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_ll_utils.o"
diff --git a/fw/Debug/objects.mk b/fw/Debug/objects.mk
new file mode 100644
index 0000000..e12976d
--- /dev/null
+++ b/fw/Debug/objects.mk
@@ -0,0 +1,9 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (9-2020-q2-update)
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
diff --git a/fw/Debug/rht_wired_sensor.bin b/fw/Debug/rht_wired_sensor.bin
new file mode 100755
index 0000000..19602bb
Binary files /dev/null and b/fw/Debug/rht_wired_sensor.bin differ
diff --git a/fw/Debug/rht_wired_sensor.elf b/fw/Debug/rht_wired_sensor.elf
new file mode 100755
index 0000000..f4755bc
Binary files /dev/null and b/fw/Debug/rht_wired_sensor.elf differ
diff --git a/fw/Debug/rht_wired_sensor.list b/fw/Debug/rht_wired_sensor.list
new file mode 100644
index 0000000..90472dc
--- /dev/null
+++ b/fw/Debug/rht_wired_sensor.list
@@ -0,0 +1,10342 @@
+
+rht_wired_sensor.elf: file format elf32-littlearm
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 .isr_vector 000000c0 08000000 08000000 00010000 2**0
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+ 1 .text 00003b08 080000c0 080000c0 000100c0 2**2
+ CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 2 .rodata 000000f4 08003bc8 08003bc8 00013bc8 2**2
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+ 3 .ARM.extab 00000000 08003cbc 08003cbc 00020008 2**0
+ CONTENTS
+ 4 .ARM 00000000 08003cbc 08003cbc 00020008 2**0
+ CONTENTS
+ 5 .preinit_array 00000000 08003cbc 08003cbc 00020008 2**0
+ CONTENTS, ALLOC, LOAD, DATA
+ 6 .init_array 00000004 08003cbc 08003cbc 00013cbc 2**2
+ CONTENTS, ALLOC, LOAD, DATA
+ 7 .fini_array 00000004 08003cc0 08003cc0 00013cc0 2**2
+ CONTENTS, ALLOC, LOAD, DATA
+ 8 .data 00000008 20000000 08003cc4 00020000 2**2
+ CONTENTS, ALLOC, LOAD, DATA
+ 9 .bss 0000017c 20000008 08003ccc 00020008 2**2
+ ALLOC
+ 10 ._user_heap_stack 00000604 20000184 08003ccc 00020184 2**0
+ ALLOC
+ 11 .ARM.attributes 00000028 00000000 00000000 00020008 2**0
+ CONTENTS, READONLY
+ 12 .debug_info 0000a894 00000000 00000000 00020030 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 13 .debug_abbrev 00001f3c 00000000 00000000 0002a8c4 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 14 .debug_aranges 00000988 00000000 00000000 0002c800 2**3
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 15 .debug_ranges 00000890 00000000 00000000 0002d188 2**3
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 16 .debug_macro 0000dc07 00000000 00000000 0002da18 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 17 .debug_line 00007bf1 00000000 00000000 0003b61f 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 18 .debug_str 00044c4f 00000000 00000000 00043210 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 19 .comment 00000053 00000000 00000000 00087e5f 2**0
+ CONTENTS, READONLY
+ 20 .debug_frame 000020e4 00000000 00000000 00087eb4 2**2
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+
+Disassembly of section .text:
+
+080000c0 <__do_global_dtors_aux>:
+ 80000c0: b510 push {r4, lr}
+ 80000c2: 4c06 ldr r4, [pc, #24] ; (80000dc <__do_global_dtors_aux+0x1c>)
+ 80000c4: 7823 ldrb r3, [r4, #0]
+ 80000c6: 2b00 cmp r3, #0
+ 80000c8: d107 bne.n 80000da <__do_global_dtors_aux+0x1a>
+ 80000ca: 4b05 ldr r3, [pc, #20] ; (80000e0 <__do_global_dtors_aux+0x20>)
+ 80000cc: 2b00 cmp r3, #0
+ 80000ce: d002 beq.n 80000d6 <__do_global_dtors_aux+0x16>
+ 80000d0: 4804 ldr r0, [pc, #16] ; (80000e4 <__do_global_dtors_aux+0x24>)
+ 80000d2: e000 b.n 80000d6 <__do_global_dtors_aux+0x16>
+ 80000d4: bf00 nop
+ 80000d6: 2301 movs r3, #1
+ 80000d8: 7023 strb r3, [r4, #0]
+ 80000da: bd10 pop {r4, pc}
+ 80000dc: 20000008 .word 0x20000008
+ 80000e0: 00000000 .word 0x00000000
+ 80000e4: 08003bb0 .word 0x08003bb0
+
+080000e8 :
+ 80000e8: 4b04 ldr r3, [pc, #16] ; (80000fc )
+ 80000ea: b510 push {r4, lr}
+ 80000ec: 2b00 cmp r3, #0
+ 80000ee: d003 beq.n 80000f8
+ 80000f0: 4903 ldr r1, [pc, #12] ; (8000100 )
+ 80000f2: 4804 ldr r0, [pc, #16] ; (8000104 )
+ 80000f4: e000 b.n 80000f8
+ 80000f6: bf00 nop
+ 80000f8: bd10 pop {r4, pc}
+ 80000fa: 46c0 nop ; (mov r8, r8)
+ 80000fc: 00000000 .word 0x00000000
+ 8000100: 2000000c .word 0x2000000c
+ 8000104: 08003bb0 .word 0x08003bb0
+
+08000108 :
+ 8000108: 2300 movs r3, #0
+ 800010a: 5cc2 ldrb r2, [r0, r3]
+ 800010c: 3301 adds r3, #1
+ 800010e: 2a00 cmp r2, #0
+ 8000110: d1fb bne.n 800010a
+ 8000112: 1e58 subs r0, r3, #1
+ 8000114: 4770 bx lr
+ ...
+
+08000118 <__udivsi3>:
+ 8000118: 2200 movs r2, #0
+ 800011a: 0843 lsrs r3, r0, #1
+ 800011c: 428b cmp r3, r1
+ 800011e: d374 bcc.n 800020a <__udivsi3+0xf2>
+ 8000120: 0903 lsrs r3, r0, #4
+ 8000122: 428b cmp r3, r1
+ 8000124: d35f bcc.n 80001e6 <__udivsi3+0xce>
+ 8000126: 0a03 lsrs r3, r0, #8
+ 8000128: 428b cmp r3, r1
+ 800012a: d344 bcc.n 80001b6 <__udivsi3+0x9e>
+ 800012c: 0b03 lsrs r3, r0, #12
+ 800012e: 428b cmp r3, r1
+ 8000130: d328 bcc.n 8000184 <__udivsi3+0x6c>
+ 8000132: 0c03 lsrs r3, r0, #16
+ 8000134: 428b cmp r3, r1
+ 8000136: d30d bcc.n 8000154 <__udivsi3+0x3c>
+ 8000138: 22ff movs r2, #255 ; 0xff
+ 800013a: 0209 lsls r1, r1, #8
+ 800013c: ba12 rev r2, r2
+ 800013e: 0c03 lsrs r3, r0, #16
+ 8000140: 428b cmp r3, r1
+ 8000142: d302 bcc.n 800014a <__udivsi3+0x32>
+ 8000144: 1212 asrs r2, r2, #8
+ 8000146: 0209 lsls r1, r1, #8
+ 8000148: d065 beq.n 8000216 <__udivsi3+0xfe>
+ 800014a: 0b03 lsrs r3, r0, #12
+ 800014c: 428b cmp r3, r1
+ 800014e: d319 bcc.n 8000184 <__udivsi3+0x6c>
+ 8000150: e000 b.n 8000154 <__udivsi3+0x3c>
+ 8000152: 0a09 lsrs r1, r1, #8
+ 8000154: 0bc3 lsrs r3, r0, #15
+ 8000156: 428b cmp r3, r1
+ 8000158: d301 bcc.n 800015e <__udivsi3+0x46>
+ 800015a: 03cb lsls r3, r1, #15
+ 800015c: 1ac0 subs r0, r0, r3
+ 800015e: 4152 adcs r2, r2
+ 8000160: 0b83 lsrs r3, r0, #14
+ 8000162: 428b cmp r3, r1
+ 8000164: d301 bcc.n 800016a <__udivsi3+0x52>
+ 8000166: 038b lsls r3, r1, #14
+ 8000168: 1ac0 subs r0, r0, r3
+ 800016a: 4152 adcs r2, r2
+ 800016c: 0b43 lsrs r3, r0, #13
+ 800016e: 428b cmp r3, r1
+ 8000170: d301 bcc.n 8000176 <__udivsi3+0x5e>
+ 8000172: 034b lsls r3, r1, #13
+ 8000174: 1ac0 subs r0, r0, r3
+ 8000176: 4152 adcs r2, r2
+ 8000178: 0b03 lsrs r3, r0, #12
+ 800017a: 428b cmp r3, r1
+ 800017c: d301 bcc.n 8000182 <__udivsi3+0x6a>
+ 800017e: 030b lsls r3, r1, #12
+ 8000180: 1ac0 subs r0, r0, r3
+ 8000182: 4152 adcs r2, r2
+ 8000184: 0ac3 lsrs r3, r0, #11
+ 8000186: 428b cmp r3, r1
+ 8000188: d301 bcc.n 800018e <__udivsi3+0x76>
+ 800018a: 02cb lsls r3, r1, #11
+ 800018c: 1ac0 subs r0, r0, r3
+ 800018e: 4152 adcs r2, r2
+ 8000190: 0a83 lsrs r3, r0, #10
+ 8000192: 428b cmp r3, r1
+ 8000194: d301 bcc.n 800019a <__udivsi3+0x82>
+ 8000196: 028b lsls r3, r1, #10
+ 8000198: 1ac0 subs r0, r0, r3
+ 800019a: 4152 adcs r2, r2
+ 800019c: 0a43 lsrs r3, r0, #9
+ 800019e: 428b cmp r3, r1
+ 80001a0: d301 bcc.n 80001a6 <__udivsi3+0x8e>
+ 80001a2: 024b lsls r3, r1, #9
+ 80001a4: 1ac0 subs r0, r0, r3
+ 80001a6: 4152 adcs r2, r2
+ 80001a8: 0a03 lsrs r3, r0, #8
+ 80001aa: 428b cmp r3, r1
+ 80001ac: d301 bcc.n 80001b2 <__udivsi3+0x9a>
+ 80001ae: 020b lsls r3, r1, #8
+ 80001b0: 1ac0 subs r0, r0, r3
+ 80001b2: 4152 adcs r2, r2
+ 80001b4: d2cd bcs.n 8000152 <__udivsi3+0x3a>
+ 80001b6: 09c3 lsrs r3, r0, #7
+ 80001b8: 428b cmp r3, r1
+ 80001ba: d301 bcc.n 80001c0 <__udivsi3+0xa8>
+ 80001bc: 01cb lsls r3, r1, #7
+ 80001be: 1ac0 subs r0, r0, r3
+ 80001c0: 4152 adcs r2, r2
+ 80001c2: 0983 lsrs r3, r0, #6
+ 80001c4: 428b cmp r3, r1
+ 80001c6: d301 bcc.n 80001cc <__udivsi3+0xb4>
+ 80001c8: 018b lsls r3, r1, #6
+ 80001ca: 1ac0 subs r0, r0, r3
+ 80001cc: 4152 adcs r2, r2
+ 80001ce: 0943 lsrs r3, r0, #5
+ 80001d0: 428b cmp r3, r1
+ 80001d2: d301 bcc.n 80001d8 <__udivsi3+0xc0>
+ 80001d4: 014b lsls r3, r1, #5
+ 80001d6: 1ac0 subs r0, r0, r3
+ 80001d8: 4152 adcs r2, r2
+ 80001da: 0903 lsrs r3, r0, #4
+ 80001dc: 428b cmp r3, r1
+ 80001de: d301 bcc.n 80001e4 <__udivsi3+0xcc>
+ 80001e0: 010b lsls r3, r1, #4
+ 80001e2: 1ac0 subs r0, r0, r3
+ 80001e4: 4152 adcs r2, r2
+ 80001e6: 08c3 lsrs r3, r0, #3
+ 80001e8: 428b cmp r3, r1
+ 80001ea: d301 bcc.n 80001f0 <__udivsi3+0xd8>
+ 80001ec: 00cb lsls r3, r1, #3
+ 80001ee: 1ac0 subs r0, r0, r3
+ 80001f0: 4152 adcs r2, r2
+ 80001f2: 0883 lsrs r3, r0, #2
+ 80001f4: 428b cmp r3, r1
+ 80001f6: d301 bcc.n 80001fc <__udivsi3+0xe4>
+ 80001f8: 008b lsls r3, r1, #2
+ 80001fa: 1ac0 subs r0, r0, r3
+ 80001fc: 4152 adcs r2, r2
+ 80001fe: 0843 lsrs r3, r0, #1
+ 8000200: 428b cmp r3, r1
+ 8000202: d301 bcc.n 8000208 <__udivsi3+0xf0>
+ 8000204: 004b lsls r3, r1, #1
+ 8000206: 1ac0 subs r0, r0, r3
+ 8000208: 4152 adcs r2, r2
+ 800020a: 1a41 subs r1, r0, r1
+ 800020c: d200 bcs.n 8000210 <__udivsi3+0xf8>
+ 800020e: 4601 mov r1, r0
+ 8000210: 4152 adcs r2, r2
+ 8000212: 4610 mov r0, r2
+ 8000214: 4770 bx lr
+ 8000216: e7ff b.n 8000218 <__udivsi3+0x100>
+ 8000218: b501 push {r0, lr}
+ 800021a: 2000 movs r0, #0
+ 800021c: f000 f8f0 bl 8000400 <__aeabi_idiv0>
+ 8000220: bd02 pop {r1, pc}
+ 8000222: 46c0 nop ; (mov r8, r8)
+
+08000224 <__aeabi_uidivmod>:
+ 8000224: 2900 cmp r1, #0
+ 8000226: d0f7 beq.n 8000218 <__udivsi3+0x100>
+ 8000228: e776 b.n 8000118 <__udivsi3>
+ 800022a: 4770 bx lr
+
+0800022c <__divsi3>:
+ 800022c: 4603 mov r3, r0
+ 800022e: 430b orrs r3, r1
+ 8000230: d47f bmi.n 8000332 <__divsi3+0x106>
+ 8000232: 2200 movs r2, #0
+ 8000234: 0843 lsrs r3, r0, #1
+ 8000236: 428b cmp r3, r1
+ 8000238: d374 bcc.n 8000324 <__divsi3+0xf8>
+ 800023a: 0903 lsrs r3, r0, #4
+ 800023c: 428b cmp r3, r1
+ 800023e: d35f bcc.n 8000300 <__divsi3+0xd4>
+ 8000240: 0a03 lsrs r3, r0, #8
+ 8000242: 428b cmp r3, r1
+ 8000244: d344 bcc.n 80002d0 <__divsi3+0xa4>
+ 8000246: 0b03 lsrs r3, r0, #12
+ 8000248: 428b cmp r3, r1
+ 800024a: d328 bcc.n 800029e <__divsi3+0x72>
+ 800024c: 0c03 lsrs r3, r0, #16
+ 800024e: 428b cmp r3, r1
+ 8000250: d30d bcc.n 800026e <__divsi3+0x42>
+ 8000252: 22ff movs r2, #255 ; 0xff
+ 8000254: 0209 lsls r1, r1, #8
+ 8000256: ba12 rev r2, r2
+ 8000258: 0c03 lsrs r3, r0, #16
+ 800025a: 428b cmp r3, r1
+ 800025c: d302 bcc.n 8000264 <__divsi3+0x38>
+ 800025e: 1212 asrs r2, r2, #8
+ 8000260: 0209 lsls r1, r1, #8
+ 8000262: d065 beq.n 8000330 <__divsi3+0x104>
+ 8000264: 0b03 lsrs r3, r0, #12
+ 8000266: 428b cmp r3, r1
+ 8000268: d319 bcc.n 800029e <__divsi3+0x72>
+ 800026a: e000 b.n 800026e <__divsi3+0x42>
+ 800026c: 0a09 lsrs r1, r1, #8
+ 800026e: 0bc3 lsrs r3, r0, #15
+ 8000270: 428b cmp r3, r1
+ 8000272: d301 bcc.n 8000278 <__divsi3+0x4c>
+ 8000274: 03cb lsls r3, r1, #15
+ 8000276: 1ac0 subs r0, r0, r3
+ 8000278: 4152 adcs r2, r2
+ 800027a: 0b83 lsrs r3, r0, #14
+ 800027c: 428b cmp r3, r1
+ 800027e: d301 bcc.n 8000284 <__divsi3+0x58>
+ 8000280: 038b lsls r3, r1, #14
+ 8000282: 1ac0 subs r0, r0, r3
+ 8000284: 4152 adcs r2, r2
+ 8000286: 0b43 lsrs r3, r0, #13
+ 8000288: 428b cmp r3, r1
+ 800028a: d301 bcc.n 8000290 <__divsi3+0x64>
+ 800028c: 034b lsls r3, r1, #13
+ 800028e: 1ac0 subs r0, r0, r3
+ 8000290: 4152 adcs r2, r2
+ 8000292: 0b03 lsrs r3, r0, #12
+ 8000294: 428b cmp r3, r1
+ 8000296: d301 bcc.n 800029c <__divsi3+0x70>
+ 8000298: 030b lsls r3, r1, #12
+ 800029a: 1ac0 subs r0, r0, r3
+ 800029c: 4152 adcs r2, r2
+ 800029e: 0ac3 lsrs r3, r0, #11
+ 80002a0: 428b cmp r3, r1
+ 80002a2: d301 bcc.n 80002a8 <__divsi3+0x7c>
+ 80002a4: 02cb lsls r3, r1, #11
+ 80002a6: 1ac0 subs r0, r0, r3
+ 80002a8: 4152 adcs r2, r2
+ 80002aa: 0a83 lsrs r3, r0, #10
+ 80002ac: 428b cmp r3, r1
+ 80002ae: d301 bcc.n 80002b4 <__divsi3+0x88>
+ 80002b0: 028b lsls r3, r1, #10
+ 80002b2: 1ac0 subs r0, r0, r3
+ 80002b4: 4152 adcs r2, r2
+ 80002b6: 0a43 lsrs r3, r0, #9
+ 80002b8: 428b cmp r3, r1
+ 80002ba: d301 bcc.n 80002c0 <__divsi3+0x94>
+ 80002bc: 024b lsls r3, r1, #9
+ 80002be: 1ac0 subs r0, r0, r3
+ 80002c0: 4152 adcs r2, r2
+ 80002c2: 0a03 lsrs r3, r0, #8
+ 80002c4: 428b cmp r3, r1
+ 80002c6: d301 bcc.n 80002cc <__divsi3+0xa0>
+ 80002c8: 020b lsls r3, r1, #8
+ 80002ca: 1ac0 subs r0, r0, r3
+ 80002cc: 4152 adcs r2, r2
+ 80002ce: d2cd bcs.n 800026c <__divsi3+0x40>
+ 80002d0: 09c3 lsrs r3, r0, #7
+ 80002d2: 428b cmp r3, r1
+ 80002d4: d301 bcc.n 80002da <__divsi3+0xae>
+ 80002d6: 01cb lsls r3, r1, #7
+ 80002d8: 1ac0 subs r0, r0, r3
+ 80002da: 4152 adcs r2, r2
+ 80002dc: 0983 lsrs r3, r0, #6
+ 80002de: 428b cmp r3, r1
+ 80002e0: d301 bcc.n 80002e6 <__divsi3+0xba>
+ 80002e2: 018b lsls r3, r1, #6
+ 80002e4: 1ac0 subs r0, r0, r3
+ 80002e6: 4152 adcs r2, r2
+ 80002e8: 0943 lsrs r3, r0, #5
+ 80002ea: 428b cmp r3, r1
+ 80002ec: d301 bcc.n 80002f2 <__divsi3+0xc6>
+ 80002ee: 014b lsls r3, r1, #5
+ 80002f0: 1ac0 subs r0, r0, r3
+ 80002f2: 4152 adcs r2, r2
+ 80002f4: 0903 lsrs r3, r0, #4
+ 80002f6: 428b cmp r3, r1
+ 80002f8: d301 bcc.n 80002fe <__divsi3+0xd2>
+ 80002fa: 010b lsls r3, r1, #4
+ 80002fc: 1ac0 subs r0, r0, r3
+ 80002fe: 4152 adcs r2, r2
+ 8000300: 08c3 lsrs r3, r0, #3
+ 8000302: 428b cmp r3, r1
+ 8000304: d301 bcc.n 800030a <__divsi3+0xde>
+ 8000306: 00cb lsls r3, r1, #3
+ 8000308: 1ac0 subs r0, r0, r3
+ 800030a: 4152 adcs r2, r2
+ 800030c: 0883 lsrs r3, r0, #2
+ 800030e: 428b cmp r3, r1
+ 8000310: d301 bcc.n 8000316 <__divsi3+0xea>
+ 8000312: 008b lsls r3, r1, #2
+ 8000314: 1ac0 subs r0, r0, r3
+ 8000316: 4152 adcs r2, r2
+ 8000318: 0843 lsrs r3, r0, #1
+ 800031a: 428b cmp r3, r1
+ 800031c: d301 bcc.n 8000322 <__divsi3+0xf6>
+ 800031e: 004b lsls r3, r1, #1
+ 8000320: 1ac0 subs r0, r0, r3
+ 8000322: 4152 adcs r2, r2
+ 8000324: 1a41 subs r1, r0, r1
+ 8000326: d200 bcs.n 800032a <__divsi3+0xfe>
+ 8000328: 4601 mov r1, r0
+ 800032a: 4152 adcs r2, r2
+ 800032c: 4610 mov r0, r2
+ 800032e: 4770 bx lr
+ 8000330: e05d b.n 80003ee <__divsi3+0x1c2>
+ 8000332: 0fca lsrs r2, r1, #31
+ 8000334: d000 beq.n 8000338 <__divsi3+0x10c>
+ 8000336: 4249 negs r1, r1
+ 8000338: 1003 asrs r3, r0, #32
+ 800033a: d300 bcc.n 800033e <__divsi3+0x112>
+ 800033c: 4240 negs r0, r0
+ 800033e: 4053 eors r3, r2
+ 8000340: 2200 movs r2, #0
+ 8000342: 469c mov ip, r3
+ 8000344: 0903 lsrs r3, r0, #4
+ 8000346: 428b cmp r3, r1
+ 8000348: d32d bcc.n 80003a6 <__divsi3+0x17a>
+ 800034a: 0a03 lsrs r3, r0, #8
+ 800034c: 428b cmp r3, r1
+ 800034e: d312 bcc.n 8000376 <__divsi3+0x14a>
+ 8000350: 22fc movs r2, #252 ; 0xfc
+ 8000352: 0189 lsls r1, r1, #6
+ 8000354: ba12 rev r2, r2
+ 8000356: 0a03 lsrs r3, r0, #8
+ 8000358: 428b cmp r3, r1
+ 800035a: d30c bcc.n 8000376 <__divsi3+0x14a>
+ 800035c: 0189 lsls r1, r1, #6
+ 800035e: 1192 asrs r2, r2, #6
+ 8000360: 428b cmp r3, r1
+ 8000362: d308 bcc.n 8000376 <__divsi3+0x14a>
+ 8000364: 0189 lsls r1, r1, #6
+ 8000366: 1192 asrs r2, r2, #6
+ 8000368: 428b cmp r3, r1
+ 800036a: d304 bcc.n 8000376 <__divsi3+0x14a>
+ 800036c: 0189 lsls r1, r1, #6
+ 800036e: d03a beq.n 80003e6 <__divsi3+0x1ba>
+ 8000370: 1192 asrs r2, r2, #6
+ 8000372: e000 b.n 8000376 <__divsi3+0x14a>
+ 8000374: 0989 lsrs r1, r1, #6
+ 8000376: 09c3 lsrs r3, r0, #7
+ 8000378: 428b cmp r3, r1
+ 800037a: d301 bcc.n 8000380 <__divsi3+0x154>
+ 800037c: 01cb lsls r3, r1, #7
+ 800037e: 1ac0 subs r0, r0, r3
+ 8000380: 4152 adcs r2, r2
+ 8000382: 0983 lsrs r3, r0, #6
+ 8000384: 428b cmp r3, r1
+ 8000386: d301 bcc.n 800038c <__divsi3+0x160>
+ 8000388: 018b lsls r3, r1, #6
+ 800038a: 1ac0 subs r0, r0, r3
+ 800038c: 4152 adcs r2, r2
+ 800038e: 0943 lsrs r3, r0, #5
+ 8000390: 428b cmp r3, r1
+ 8000392: d301 bcc.n 8000398 <__divsi3+0x16c>
+ 8000394: 014b lsls r3, r1, #5
+ 8000396: 1ac0 subs r0, r0, r3
+ 8000398: 4152 adcs r2, r2
+ 800039a: 0903 lsrs r3, r0, #4
+ 800039c: 428b cmp r3, r1
+ 800039e: d301 bcc.n 80003a4 <__divsi3+0x178>
+ 80003a0: 010b lsls r3, r1, #4
+ 80003a2: 1ac0 subs r0, r0, r3
+ 80003a4: 4152 adcs r2, r2
+ 80003a6: 08c3 lsrs r3, r0, #3
+ 80003a8: 428b cmp r3, r1
+ 80003aa: d301 bcc.n 80003b0 <__divsi3+0x184>
+ 80003ac: 00cb lsls r3, r1, #3
+ 80003ae: 1ac0 subs r0, r0, r3
+ 80003b0: 4152 adcs r2, r2
+ 80003b2: 0883 lsrs r3, r0, #2
+ 80003b4: 428b cmp r3, r1
+ 80003b6: d301 bcc.n 80003bc <__divsi3+0x190>
+ 80003b8: 008b lsls r3, r1, #2
+ 80003ba: 1ac0 subs r0, r0, r3
+ 80003bc: 4152 adcs r2, r2
+ 80003be: d2d9 bcs.n 8000374 <__divsi3+0x148>
+ 80003c0: 0843 lsrs r3, r0, #1
+ 80003c2: 428b cmp r3, r1
+ 80003c4: d301 bcc.n 80003ca <__divsi3+0x19e>
+ 80003c6: 004b lsls r3, r1, #1
+ 80003c8: 1ac0 subs r0, r0, r3
+ 80003ca: 4152 adcs r2, r2
+ 80003cc: 1a41 subs r1, r0, r1
+ 80003ce: d200 bcs.n 80003d2 <__divsi3+0x1a6>
+ 80003d0: 4601 mov r1, r0
+ 80003d2: 4663 mov r3, ip
+ 80003d4: 4152 adcs r2, r2
+ 80003d6: 105b asrs r3, r3, #1
+ 80003d8: 4610 mov r0, r2
+ 80003da: d301 bcc.n 80003e0 <__divsi3+0x1b4>
+ 80003dc: 4240 negs r0, r0
+ 80003de: 2b00 cmp r3, #0
+ 80003e0: d500 bpl.n 80003e4 <__divsi3+0x1b8>
+ 80003e2: 4249 negs r1, r1
+ 80003e4: 4770 bx lr
+ 80003e6: 4663 mov r3, ip
+ 80003e8: 105b asrs r3, r3, #1
+ 80003ea: d300 bcc.n 80003ee <__divsi3+0x1c2>
+ 80003ec: 4240 negs r0, r0
+ 80003ee: b501 push {r0, lr}
+ 80003f0: 2000 movs r0, #0
+ 80003f2: f000 f805 bl 8000400 <__aeabi_idiv0>
+ 80003f6: bd02 pop {r1, pc}
+
+080003f8 <__aeabi_idivmod>:
+ 80003f8: 2900 cmp r1, #0
+ 80003fa: d0f8 beq.n 80003ee <__divsi3+0x1c2>
+ 80003fc: e716 b.n 800022c <__divsi3>
+ 80003fe: 4770 bx lr
+
+08000400 <__aeabi_idiv0>:
+ 8000400: 4770 bx lr
+ 8000402: 46c0 nop ; (mov r8, r8)
+
+08000404 :
+/* Function to write four bytes to the EEPROM */
+/* IMPORTANT: EEPROM must be unlocked first */
+static int8_t eeprom_program_word(uint32_t addr, uint32_t ee_data);
+
+int8_t config_read(config_t *config)
+{
+ 8000404: b580 push {r7, lr}
+ 8000406: b082 sub sp, #8
+ 8000408: af00 add r7, sp, #0
+ 800040a: 6078 str r0, [r7, #4]
+ config->modbus_addr = *(uint16_t *) (CONFIG_EEPROM_ADDR_MODBUS_ADDR);
+ 800040c: 4b1d ldr r3, [pc, #116] ; (8000484 )
+ 800040e: 881a ldrh r2, [r3, #0]
+ 8000410: 687b ldr r3, [r7, #4]
+ 8000412: 819a strh r2, [r3, #12]
+ config->baudrate_index = *(uint16_t *) (CONFIG_EEPROM_ADDR_BAUDRATE_INDEX);
+ 8000414: 4b1c ldr r3, [pc, #112] ; (8000488 )
+ 8000416: 881b ldrh r3, [r3, #0]
+ 8000418: 001a movs r2, r3
+ 800041a: 687b ldr r3, [r7, #4]
+ 800041c: 611a str r2, [r3, #16]
+ config->led_on = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ON);
+ 800041e: 4b1b ldr r3, [pc, #108] ; (800048c )
+ 8000420: 881b ldrh r3, [r3, #0]
+ 8000422: b2da uxtb r2, r3
+ 8000424: 687b ldr r3, [r7, #4]
+ 8000426: 701a strb r2, [r3, #0]
+ config->led_brightness = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_BRIGHTNESS);
+ 8000428: 4b19 ldr r3, [pc, #100] ; (8000490 )
+ 800042a: 881a ldrh r2, [r3, #0]
+ 800042c: 687b ldr r3, [r7, #4]
+ 800042e: 805a strh r2, [r3, #2]
+ config->led_smooth = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_SMOOTH);
+ 8000430: 4b18 ldr r3, [pc, #96] ; (8000494 )
+ 8000432: 881b ldrh r3, [r3, #0]
+ 8000434: b2da uxtb r2, r3
+ 8000436: 687b ldr r3, [r7, #4]
+ 8000438: 711a strb r2, [r3, #4]
+ config->led_co2_alert_limit1 = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ALERT1);
+ 800043a: 4b17 ldr r3, [pc, #92] ; (8000498 )
+ 800043c: 881a ldrh r2, [r3, #0]
+ 800043e: 687b ldr r3, [r7, #4]
+ 8000440: 80da strh r2, [r3, #6]
+ config->led_co2_alert_limit2 = *(uint16_t *) (CONFIG_EEPROM_ADDR_LED_ALERT2);
+ 8000442: 4b16 ldr r3, [pc, #88] ; (800049c )
+ 8000444: 881a ldrh r2, [r3, #0]
+ 8000446: 687b ldr r3, [r7, #4]
+ 8000448: 811a strh r2, [r3, #8]
+ config->scd4x_t_offset = *(int16_t *) (CONFIG_EEPROM_ADDR_SCD4x_T_OFFSET);
+ 800044a: 4b15 ldr r3, [pc, #84] ; (80004a0 )
+ 800044c: 2200 movs r2, #0
+ 800044e: 5e9a ldrsh r2, [r3, r2]
+ 8000450: 687b ldr r3, [r7, #4]
+ 8000452: 815a strh r2, [r3, #10]
+ * LED ON
+ * LED SMOOTH
+ * SCD4x T OFFSET
+ * BAUDRATE INDEX
+ * those can be 0 */
+ if ((config->modbus_addr == EEPROM_EMPTY_BYTE) ||
+ 8000454: 687b ldr r3, [r7, #4]
+ 8000456: 899b ldrh r3, [r3, #12]
+ 8000458: 2b00 cmp r3, #0
+ 800045a: d00b beq.n 8000474
+ (config->led_co2_alert_limit1 == EEPROM_EMPTY_BYTE) ||
+ 800045c: 687b ldr r3, [r7, #4]
+ 800045e: 88db ldrh r3, [r3, #6]
+ if ((config->modbus_addr == EEPROM_EMPTY_BYTE) ||
+ 8000460: 2b00 cmp r3, #0
+ 8000462: d007 beq.n 8000474
+ (config->led_co2_alert_limit2 == EEPROM_EMPTY_BYTE) ||
+ 8000464: 687b ldr r3, [r7, #4]
+ 8000466: 891b ldrh r3, [r3, #8]
+ (config->led_co2_alert_limit1 == EEPROM_EMPTY_BYTE) ||
+ 8000468: 2b00 cmp r3, #0
+ 800046a: d003 beq.n 8000474
+ (config->led_brightness == EEPROM_EMPTY_BYTE))
+ 800046c: 687b ldr r3, [r7, #4]
+ 800046e: 885b ldrh r3, [r3, #2]
+ (config->led_co2_alert_limit2 == EEPROM_EMPTY_BYTE) ||
+ 8000470: 2b00 cmp r3, #0
+ 8000472: d102 bne.n 800047a
+ {
+ return CONFIG_ERROR;
+ 8000474: 2301 movs r3, #1
+ 8000476: 425b negs r3, r3
+ 8000478: e000 b.n 800047c
+ }
+ return CONFIG_OK;
+ 800047a: 2300 movs r3, #0
+}
+ 800047c: 0018 movs r0, r3
+ 800047e: 46bd mov sp, r7
+ 8000480: b002 add sp, #8
+ 8000482: bd80 pop {r7, pc}
+ 8000484: 08080000 .word 0x08080000
+ 8000488: 08080002 .word 0x08080002
+ 800048c: 08080004 .word 0x08080004
+ 8000490: 08080006 .word 0x08080006
+ 8000494: 08080008 .word 0x08080008
+ 8000498: 0808000a .word 0x0808000a
+ 800049c: 0808000c .word 0x0808000c
+ 80004a0: 0808000e .word 0x0808000e
+
+080004a4 :
+
+int8_t config_write(config_t *config)
+{
+ 80004a4: b580 push {r7, lr}
+ 80004a6: b082 sub sp, #8
+ 80004a8: af00 add r7, sp, #0
+ 80004aa: 6078 str r0, [r7, #4]
+ /* Unlock the EEPROM */
+ if (eeprom_unlock() != EEPROM_OK)
+ 80004ac: f000 f8cc bl 8000648
+ 80004b0: 1e03 subs r3, r0, #0
+ 80004b2: d002 beq.n 80004ba
+ {
+ return EEPROM_UNLOCK_ERROR;
+ 80004b4: 2302 movs r3, #2
+ 80004b6: 425b negs r3, r3
+ 80004b8: e070 b.n 800059c
+ }
+ /* Reset the ERASE and DATA bits in the FLASH_PECR register to disable any residual erase */
+ FLASH->PECR = FLASH->PECR & ~(FLASH_PECR_ERASE | FLASH_PECR_DATA);
+ 80004ba: 4b3a ldr r3, [pc, #232] ; (80005a4 )
+ 80004bc: 685a ldr r2, [r3, #4]
+ 80004be: 4b39 ldr r3, [pc, #228] ; (80005a4 )
+ 80004c0: 4939 ldr r1, [pc, #228] ; (80005a8 )
+ 80004c2: 400a ands r2, r1
+ 80004c4: 605a str r2, [r3, #4]
+
+ /* Write MODBUS ADDRESS */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_MODBUS_ADDR, config->modbus_addr) != EEPROM_OK)
+ 80004c6: 687b ldr r3, [r7, #4]
+ 80004c8: 899b ldrh r3, [r3, #12]
+ 80004ca: 4a38 ldr r2, [pc, #224] ; (80005ac )
+ 80004cc: 0019 movs r1, r3
+ 80004ce: 0010 movs r0, r2
+ 80004d0: f000 f928 bl 8000724
+ 80004d4: 1e03 subs r3, r0, #0
+ 80004d6: d002 beq.n 80004de
+ {
+ return EEPROM_WRITE_ERROR;
+ 80004d8: 2304 movs r3, #4
+ 80004da: 425b negs r3, r3
+ 80004dc: e05e b.n 800059c
+ }
+ /* Write BAUDRATE */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_BAUDRATE_INDEX, config->baudrate_index) != EEPROM_OK)
+ 80004de: 687b ldr r3, [r7, #4]
+ 80004e0: 691b ldr r3, [r3, #16]
+ 80004e2: b29b uxth r3, r3
+ 80004e4: 4a32 ldr r2, [pc, #200] ; (80005b0 )
+ 80004e6: 0019 movs r1, r3
+ 80004e8: 0010 movs r0, r2
+ 80004ea: f000 f91b bl 8000724
+ 80004ee: 1e03 subs r3, r0, #0
+ 80004f0: d002 beq.n 80004f8
+ {
+ return EEPROM_WRITE_ERROR;
+ 80004f2: 2304 movs r3, #4
+ 80004f4: 425b negs r3, r3
+ 80004f6: e051 b.n 800059c
+ }
+
+ /* Write LED ON */
+ if (eeprom_program_byte(CONFIG_EEPROM_ADDR_LED_ON, config->led_on) != EEPROM_OK)
+ 80004f8: 687b ldr r3, [r7, #4]
+ 80004fa: 781b ldrb r3, [r3, #0]
+ 80004fc: 4a2d ldr r2, [pc, #180] ; (80005b4 )
+ 80004fe: 0019 movs r1, r3
+ 8000500: 0010 movs r0, r2
+ 8000502: f000 f8e7 bl 80006d4
+ 8000506: 1e03 subs r3, r0, #0
+ 8000508: d002 beq.n 8000510
+ {
+ return EEPROM_WRITE_ERROR;
+ 800050a: 2304 movs r3, #4
+ 800050c: 425b negs r3, r3
+ 800050e: e045 b.n 800059c
+ }
+
+ /* Write LED BRIGHTNESS */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_BRIGHTNESS, config->led_brightness) != EEPROM_OK)
+ 8000510: 687b ldr r3, [r7, #4]
+ 8000512: 885b ldrh r3, [r3, #2]
+ 8000514: 4a28 ldr r2, [pc, #160] ; (80005b8 )
+ 8000516: 0019 movs r1, r3
+ 8000518: 0010 movs r0, r2
+ 800051a: f000 f903 bl 8000724
+ 800051e: 1e03 subs r3, r0, #0
+ 8000520: d002 beq.n 8000528
+ {
+ return EEPROM_WRITE_ERROR;
+ 8000522: 2304 movs r3, #4
+ 8000524: 425b negs r3, r3
+ 8000526: e039 b.n 800059c
+ }
+
+ /* Write LED SMOOTH */
+ if (eeprom_program_byte(CONFIG_EEPROM_ADDR_LED_SMOOTH, config->led_smooth) != EEPROM_OK)
+ 8000528: 687b ldr r3, [r7, #4]
+ 800052a: 791b ldrb r3, [r3, #4]
+ 800052c: 4a23 ldr r2, [pc, #140] ; (80005bc )
+ 800052e: 0019 movs r1, r3
+ 8000530: 0010 movs r0, r2
+ 8000532: f000 f8cf bl 80006d4
+ 8000536: 1e03 subs r3, r0, #0
+ 8000538: d002 beq.n 8000540
+ {
+ return EEPROM_WRITE_ERROR;
+ 800053a: 2304 movs r3, #4
+ 800053c: 425b negs r3, r3
+ 800053e: e02d b.n 800059c
+ }
+
+ /* Write LED CO2 ALERT LIMIT 1 */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT1, config->led_co2_alert_limit1) != EEPROM_OK)
+ 8000540: 687b ldr r3, [r7, #4]
+ 8000542: 88db ldrh r3, [r3, #6]
+ 8000544: 4a1e ldr r2, [pc, #120] ; (80005c0 )
+ 8000546: 0019 movs r1, r3
+ 8000548: 0010 movs r0, r2
+ 800054a: f000 f8eb bl 8000724
+ 800054e: 1e03 subs r3, r0, #0
+ 8000550: d002 beq.n 8000558
+ {
+ return EEPROM_WRITE_ERROR;
+ 8000552: 2304 movs r3, #4
+ 8000554: 425b negs r3, r3
+ 8000556: e021 b.n 800059c
+ }
+
+ /* Write LED CO2 ALERT LIMIT 2 */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_LED_ALERT2, config->led_co2_alert_limit2) != EEPROM_OK)
+ 8000558: 687b ldr r3, [r7, #4]
+ 800055a: 891b ldrh r3, [r3, #8]
+ 800055c: 4a19 ldr r2, [pc, #100] ; (80005c4 )
+ 800055e: 0019 movs r1, r3
+ 8000560: 0010 movs r0, r2
+ 8000562: f000 f8df bl 8000724
+ 8000566: 1e03 subs r3, r0, #0
+ 8000568: d002 beq.n 8000570
+ {
+ return EEPROM_WRITE_ERROR;
+ 800056a: 2304 movs r3, #4
+ 800056c: 425b negs r3, r3
+ 800056e: e015 b.n 800059c
+ }
+
+ /* Write LED SCD4x TEMPERATURE OFFSET */
+ if (eeprom_program_halfword(CONFIG_EEPROM_ADDR_SCD4x_T_OFFSET, config->scd4x_t_offset) != EEPROM_OK)
+ 8000570: 687b ldr r3, [r7, #4]
+ 8000572: 220a movs r2, #10
+ 8000574: 5e9b ldrsh r3, [r3, r2]
+ 8000576: b29b uxth r3, r3
+ 8000578: 4a13 ldr r2, [pc, #76] ; (80005c8 )
+ 800057a: 0019 movs r1, r3
+ 800057c: 0010 movs r0, r2
+ 800057e: f000 f8d1 bl 8000724
+ 8000582: 1e03 subs r3, r0, #0
+ 8000584: d002 beq.n 800058c
+ {
+ return EEPROM_WRITE_ERROR;
+ 8000586: 2304 movs r3, #4
+ 8000588: 425b negs r3, r3
+ 800058a: e007 b.n 800059c
+ }
+
+ /* Lock EEPROM*/
+ if (eeprom_lock() != EEPROM_OK)
+ 800058c: f000 f81e bl 80005cc
+ 8000590: 1e03 subs r3, r0, #0
+ 8000592: d002 beq.n 800059a
+ {
+ return EEPROM_LOCK_ERROR;
+ 8000594: 2303 movs r3, #3
+ 8000596: 425b negs r3, r3
+ 8000598: e000 b.n 800059c
+ }
+ return CONFIG_OK;
+ 800059a: 2300 movs r3, #0
+}
+ 800059c: 0018 movs r0, r3
+ 800059e: 46bd mov sp, r7
+ 80005a0: b002 add sp, #8
+ 80005a2: bd80 pop {r7, pc}
+ 80005a4: 40022000 .word 0x40022000
+ 80005a8: fffffdef .word 0xfffffdef
+ 80005ac: 08080000 .word 0x08080000
+ 80005b0: 08080002 .word 0x08080002
+ 80005b4: 08080004 .word 0x08080004
+ 80005b8: 08080006 .word 0x08080006
+ 80005bc: 08080008 .word 0x08080008
+ 80005c0: 0808000a .word 0x0808000a
+ 80005c4: 0808000c .word 0x0808000c
+ 80005c8: 0808000e .word 0x0808000e
+
+080005cc :
+
+static int8_t eeprom_lock(void)
+{
+ 80005cc: b580 push {r7, lr}
+ 80005ce: b084 sub sp, #16
+ 80005d0: af00 add r7, sp, #0
+ uint32_t tick_start = SysTick->VAL;
+ 80005d2: 4b19 ldr r3, [pc, #100] ; (8000638 )
+ 80005d4: 689b ldr r3, [r3, #8]
+ 80005d6: 60bb str r3, [r7, #8]
+ while ((FLASH->SR & FLASH_SR_BSY) != 0) /* Wait for FLASH to be free */
+ 80005d8: e017 b.n 800060a
+ {
+ /* Timeout test */
+ /* The maximum writing time is 3.94ms (half-word) */
+ uint32_t tick_last = SysTick->VAL;
+ 80005da: 4b17 ldr r3, [pc, #92] ; (8000638 )
+ 80005dc: 689b ldr r3, [r3, #8]
+ 80005de: 607b str r3, [r7, #4]
+ uint32_t tick_diff;
+ if (tick_start <= tick_last)
+ 80005e0: 68ba ldr r2, [r7, #8]
+ 80005e2: 687b ldr r3, [r7, #4]
+ 80005e4: 429a cmp r2, r3
+ 80005e6: d804 bhi.n 80005f2
+ {
+ tick_diff = tick_last - tick_start;
+ 80005e8: 687a ldr r2, [r7, #4]
+ 80005ea: 68bb ldr r3, [r7, #8]
+ 80005ec: 1ad3 subs r3, r2, r3
+ 80005ee: 60fb str r3, [r7, #12]
+ 80005f0: e004 b.n 80005fc
+ } else
+ {
+ tick_diff = (0xFFFFFFFF - tick_last) + tick_start;
+ 80005f2: 68ba ldr r2, [r7, #8]
+ 80005f4: 687b ldr r3, [r7, #4]
+ 80005f6: 1ad3 subs r3, r2, r3
+ 80005f8: 3b01 subs r3, #1
+ 80005fa: 60fb str r3, [r7, #12]
+ }
+
+ /* If the time difference is more than 5ms */
+ if (tick_diff >= (uint32_t)((uint32_t)SYSTICK_FREQ_HZ*(uint32_t)EEPROM_TIMEOUT_MAX_MS_INV))
+ 80005fc: 68fb ldr r3, [r7, #12]
+ 80005fe: 4a0f ldr r2, [pc, #60] ; (800063c )
+ 8000600: 4293 cmp r3, r2
+ 8000602: d902 bls.n 800060a
+ {
+ return EEPROM_LOCK_ERROR;
+ 8000604: 2303 movs r3, #3
+ 8000606: 425b negs r3, r3
+ 8000608: e011 b.n 800062e
+ while ((FLASH->SR & FLASH_SR_BSY) != 0) /* Wait for FLASH to be free */
+ 800060a: 4b0d ldr r3, [pc, #52] ; (8000640 )
+ 800060c: 699b ldr r3, [r3, #24]
+ 800060e: 2201 movs r2, #1
+ 8000610: 4013 ands r3, r2
+ 8000612: d1e2 bne.n 80005da
+ }
+ }
+
+ FLASH->PECR = FLASH->PECR & ~(FLASH_PECR_ERRIE | FLASH_PECR_EOPIE); /* disable flash interrupts */
+ 8000614: 4b0a ldr r3, [pc, #40] ; (8000640 )
+ 8000616: 685a ldr r2, [r3, #4]
+ 8000618: 4b09 ldr r3, [pc, #36] ; (8000640 )
+ 800061a: 490a ldr r1, [pc, #40] ; (8000644 )
+ 800061c: 400a ands r2, r1
+ 800061e: 605a str r2, [r3, #4]
+ FLASH->PECR = FLASH->PECR | FLASH_PECR_PELOCK; /* Lock memory with PELOCK */
+ 8000620: 4b07 ldr r3, [pc, #28] ; (8000640 )
+ 8000622: 685a ldr r2, [r3, #4]
+ 8000624: 4b06 ldr r3, [pc, #24] ; (8000640 )
+ 8000626: 2101 movs r1, #1
+ 8000628: 430a orrs r2, r1
+ 800062a: 605a str r2, [r3, #4]
+
+ return EEPROM_OK;
+ 800062c: 2300 movs r3, #0
+}
+ 800062e: 0018 movs r0, r3
+ 8000630: 46bd mov sp, r7
+ 8000632: b004 add sp, #16
+ 8000634: bd80 pop {r7, pc}
+ 8000636: 46c0 nop ; (mov r8, r8)
+ 8000638: e000e010 .word 0xe000e010
+ 800063c: 8f0d17ff .word 0x8f0d17ff
+ 8000640: 40022000 .word 0x40022000
+ 8000644: fffcffff .word 0xfffcffff
+
+08000648 :
+
+static int8_t eeprom_unlock(void)
+{
+ 8000648: b580 push {r7, lr}
+ 800064a: b084 sub sp, #16
+ 800064c: af00 add r7, sp, #0
+ uint32_t tick_start = SysTick->VAL;
+ 800064e: 4b1c ldr r3, [pc, #112] ; (80006c0 )
+ 8000650: 689b ldr r3, [r3, #8]
+ 8000652: 60bb str r3, [r7, #8]
+ while ((FLASH->SR & FLASH_SR_BSY) != 0) /* Wait for FLASH to be free */
+ 8000654: e017 b.n 8000686
+ {
+ /* Timeout test */
+ /* The maximum writing time is 3.94ms (half-word) */
+ uint32_t tick_last = SysTick->VAL;
+ 8000656: 4b1a ldr r3, [pc, #104] ; (80006c0 )
+ 8000658: 689b ldr r3, [r3, #8]
+ 800065a: 607b str r3, [r7, #4]
+ uint32_t tick_diff;
+ if (tick_start <= tick_last)
+ 800065c: 68ba ldr r2, [r7, #8]
+ 800065e: 687b ldr r3, [r7, #4]
+ 8000660: 429a cmp r2, r3
+ 8000662: d804 bhi.n 800066e
+ {
+ tick_diff = tick_last - tick_start;
+ 8000664: 687a ldr r2, [r7, #4]
+ 8000666: 68bb ldr r3, [r7, #8]
+ 8000668: 1ad3 subs r3, r2, r3
+ 800066a: 60fb str r3, [r7, #12]
+ 800066c: e004 b.n 8000678
+ } else
+ {
+ tick_diff = (0xFFFFFFFF - tick_last) + tick_start;
+ 800066e: 68ba ldr r2, [r7, #8]
+ 8000670: 687b ldr r3, [r7, #4]
+ 8000672: 1ad3 subs r3, r2, r3
+ 8000674: 3b01 subs r3, #1
+ 8000676: 60fb str r3, [r7, #12]
+ }
+
+ /* If the time difference is more than 5ms */
+ if (tick_diff >= (uint32_t)((uint32_t)SYSTICK_FREQ_HZ*(uint32_t)EEPROM_TIMEOUT_MAX_MS_INV))
+ 8000678: 68fb ldr r3, [r7, #12]
+ 800067a: 4a12 ldr r2, [pc, #72] ; (80006c4 )
+ 800067c: 4293 cmp r3, r2
+ 800067e: d902 bls.n 8000686
+ {
+ return EEPROM_UNLOCK_ERROR;
+ 8000680: 2302 movs r3, #2
+ 8000682: 425b negs r3, r3
+ 8000684: e017 b.n 80006b6
+ while ((FLASH->SR & FLASH_SR_BSY) != 0) /* Wait for FLASH to be free */
+ 8000686: 4b10 ldr r3, [pc, #64] ; (80006c8 )
+ 8000688: 699b ldr r3, [r3, #24]
+ 800068a: 2201 movs r2, #1
+ 800068c: 4013 ands r3, r2
+ 800068e: d1e2 bne.n 8000656
+ }
+ }
+ if ((FLASH->PECR & FLASH_PECR_PELOCK) != 0) /* If PELOCK is locked */
+ 8000690: 4b0d ldr r3, [pc, #52] ; (80006c8 )
+ 8000692: 685b ldr r3, [r3, #4]
+ 8000694: 2201 movs r2, #1
+ 8000696: 4013 ands r3, r2
+ 8000698: d005 beq.n 80006a6
+ {
+ /* Unlock PELOCK */
+ FLASH->PEKEYR = FLASH_PEKEY1; /* PEKEY1 */
+ 800069a: 4b0b ldr r3, [pc, #44] ; (80006c8 )
+ 800069c: 4a0b ldr r2, [pc, #44] ; (80006cc )
+ 800069e: 60da str r2, [r3, #12]
+ FLASH->PEKEYR = FLASH_PEKEY2; /* PEKEY2 */
+ 80006a0: 4b09 ldr r3, [pc, #36] ; (80006c8 )
+ 80006a2: 4a0b ldr r2, [pc, #44] ; (80006d0 )
+ 80006a4: 60da str r2, [r3, #12]
+ }
+ FLASH->PECR = FLASH->PECR | (FLASH_PECR_ERRIE | FLASH_PECR_EOPIE); /* enable flash interrupts */
+ 80006a6: 4b08 ldr r3, [pc, #32] ; (80006c8 )
+ 80006a8: 685a ldr r2, [r3, #4]
+ 80006aa: 4b07 ldr r3, [pc, #28] ; (80006c8 )
+ 80006ac: 21c0 movs r1, #192 ; 0xc0
+ 80006ae: 0289 lsls r1, r1, #10
+ 80006b0: 430a orrs r2, r1
+ 80006b2: 605a str r2, [r3, #4]
+ return EEPROM_OK;
+ 80006b4: 2300 movs r3, #0
+}
+ 80006b6: 0018 movs r0, r3
+ 80006b8: 46bd mov sp, r7
+ 80006ba: b004 add sp, #16
+ 80006bc: bd80 pop {r7, pc}
+ 80006be: 46c0 nop ; (mov r8, r8)
+ 80006c0: e000e010 .word 0xe000e010
+ 80006c4: 8f0d17ff .word 0x8f0d17ff
+ 80006c8: 40022000 .word 0x40022000
+ 80006cc: 89abcdef .word 0x89abcdef
+ 80006d0: 02030405 .word 0x02030405
+
+080006d4 :
+
+static int8_t eeprom_program_byte(uint32_t addr, uint8_t ee_data)
+{
+ 80006d4: b580 push {r7, lr}
+ 80006d6: b082 sub sp, #8
+ 80006d8: af00 add r7, sp, #0
+ 80006da: 6078 str r0, [r7, #4]
+ 80006dc: 000a movs r2, r1
+ 80006de: 1cfb adds r3, r7, #3
+ 80006e0: 701a strb r2, [r3, #0]
+ if ((EEPROM_ADDR_START <= addr) && (addr <= EEPROM_ADDR_END - 1))
+ 80006e2: 687b ldr r3, [r7, #4]
+ 80006e4: 4a0d ldr r2, [pc, #52] ; (800071c )
+ 80006e6: 4293 cmp r3, r2
+ 80006e8: d912 bls.n 8000710
+ 80006ea: 687b ldr r3, [r7, #4]
+ 80006ec: 4a0c ldr r2, [pc, #48] ; (8000720 )
+ 80006ee: 4293 cmp r3, r2
+ 80006f0: d80e bhi.n 8000710
+ {
+ *(uint8_t *)(addr) = ee_data; /* write data to EEPROM */
+ 80006f2: 687b ldr r3, [r7, #4]
+ 80006f4: 1cfa adds r2, r7, #3
+ 80006f6: 7812 ldrb r2, [r2, #0]
+ 80006f8: 701a strb r2, [r3, #0]
+ if (*(uint8_t *)(addr) != ee_data)
+ 80006fa: 687b ldr r3, [r7, #4]
+ 80006fc: 781b ldrb r3, [r3, #0]
+ 80006fe: 1cfa adds r2, r7, #3
+ 8000700: 7812 ldrb r2, [r2, #0]
+ 8000702: 429a cmp r2, r3
+ 8000704: d002 beq.n 800070c
+ {
+ return EEPROM_WRITE_ERROR;
+ 8000706: 2304 movs r3, #4
+ 8000708: 425b negs r3, r3
+ 800070a: e003 b.n 8000714
+ }
+ return EEPROM_OK;
+ 800070c: 2300 movs r3, #0
+ 800070e: e001 b.n 8000714
+ } else
+ {
+ return EEPROM_ADDR_ERROR;
+ 8000710: 2305 movs r3, #5
+ 8000712: 425b negs r3, r3
+ }
+}
+ 8000714: 0018 movs r0, r3
+ 8000716: 46bd mov sp, r7
+ 8000718: b002 add sp, #8
+ 800071a: bd80 pop {r7, pc}
+ 800071c: 0807ffff .word 0x0807ffff
+ 8000720: 080803fe .word 0x080803fe
+
+08000724 :
+static int8_t eeprom_program_halfword(uint32_t addr, uint16_t ee_data)
+{
+ 8000724: b580 push {r7, lr}
+ 8000726: b082 sub sp, #8
+ 8000728: af00 add r7, sp, #0
+ 800072a: 6078 str r0, [r7, #4]
+ 800072c: 000a movs r2, r1
+ 800072e: 1cbb adds r3, r7, #2
+ 8000730: 801a strh r2, [r3, #0]
+ if ((EEPROM_ADDR_START <= addr) && (addr <= EEPROM_ADDR_END - 2))
+ 8000732: 687b ldr r3, [r7, #4]
+ 8000734: 4a0d ldr r2, [pc, #52] ; (800076c )
+ 8000736: 4293 cmp r3, r2
+ 8000738: d912 bls.n 8000760
+ 800073a: 687b ldr r3, [r7, #4]
+ 800073c: 4a0c ldr r2, [pc, #48] ; (8000770 )
+ 800073e: 4293 cmp r3, r2
+ 8000740: d80e bhi.n 8000760
+ {
+ *(uint16_t *)(addr) = ee_data; /* write data to EEPROM */
+ 8000742: 687b ldr r3, [r7, #4]
+ 8000744: 1cba adds r2, r7, #2
+ 8000746: 8812 ldrh r2, [r2, #0]
+ 8000748: 801a strh r2, [r3, #0]
+ if (*(uint16_t *)(addr) != ee_data)
+ 800074a: 687b ldr r3, [r7, #4]
+ 800074c: 881b ldrh r3, [r3, #0]
+ 800074e: 1cba adds r2, r7, #2
+ 8000750: 8812 ldrh r2, [r2, #0]
+ 8000752: 429a cmp r2, r3
+ 8000754: d002 beq.n 800075c
+ {
+ return EEPROM_WRITE_ERROR;
+ 8000756: 2304 movs r3, #4
+ 8000758: 425b negs r3, r3
+ 800075a: e003 b.n 8000764
+ }
+ return EEPROM_OK;
+ 800075c: 2300 movs r3, #0
+ 800075e: e001 b.n 8000764
+ } else
+ {
+ return EEPROM_ADDR_ERROR;
+ 8000760: 2305 movs r3, #5
+ 8000762: 425b negs r3, r3
+ }
+}
+ 8000764: 0018 movs r0, r3
+ 8000766: 46bd mov sp, r7
+ 8000768: b002 add sp, #8
+ 800076a: bd80 pop {r7, pc}
+ 800076c: 0807ffff .word 0x0807ffff
+ 8000770: 080803fd .word 0x080803fd
+
+08000774 :
+
+#include "crc8.h"
+
+/* Stolen from Sensirion SCD4x datasheet, section 3.11 */
+uint8_t crc8_calculate(const uint8_t *data, uint16_t count)
+{
+ 8000774: b580 push {r7, lr}
+ 8000776: b084 sub sp, #16
+ 8000778: af00 add r7, sp, #0
+ 800077a: 6078 str r0, [r7, #4]
+ 800077c: 000a movs r2, r1
+ 800077e: 1cbb adds r3, r7, #2
+ 8000780: 801a strh r2, [r3, #0]
+ uint16_t current_byte;
+ uint8_t crc = CRC8_INIT;
+ 8000782: 230d movs r3, #13
+ 8000784: 18fb adds r3, r7, r3
+ 8000786: 22ff movs r2, #255 ; 0xff
+ 8000788: 701a strb r2, [r3, #0]
+ uint8_t crc_bit;
+ /* calculates 8-Bit checksum with given polynomial */
+ for (current_byte = 0; current_byte < count; ++current_byte) {
+ 800078a: 230e movs r3, #14
+ 800078c: 18fb adds r3, r7, r3
+ 800078e: 2200 movs r2, #0
+ 8000790: 801a strh r2, [r3, #0]
+ 8000792: e037 b.n 8000804
+ crc ^= (data[current_byte]);
+ 8000794: 230e movs r3, #14
+ 8000796: 18fb adds r3, r7, r3
+ 8000798: 881b ldrh r3, [r3, #0]
+ 800079a: 687a ldr r2, [r7, #4]
+ 800079c: 18d3 adds r3, r2, r3
+ 800079e: 7819 ldrb r1, [r3, #0]
+ 80007a0: 220d movs r2, #13
+ 80007a2: 18bb adds r3, r7, r2
+ 80007a4: 18ba adds r2, r7, r2
+ 80007a6: 7812 ldrb r2, [r2, #0]
+ 80007a8: 404a eors r2, r1
+ 80007aa: 701a strb r2, [r3, #0]
+ for(crc_bit = 8; crc_bit > 0; --crc_bit) {
+ 80007ac: 230c movs r3, #12
+ 80007ae: 18fb adds r3, r7, r3
+ 80007b0: 2208 movs r2, #8
+ 80007b2: 701a strb r2, [r3, #0]
+ 80007b4: e01b b.n 80007ee
+ if (crc & 0x80) {
+ 80007b6: 210d movs r1, #13
+ 80007b8: 187b adds r3, r7, r1
+ 80007ba: 781b ldrb r3, [r3, #0]
+ 80007bc: b25b sxtb r3, r3
+ 80007be: 2b00 cmp r3, #0
+ 80007c0: da09 bge.n 80007d6
+ crc =(crc << 1) ^ CRC8_POLYNOMIAL;
+ 80007c2: 187b adds r3, r7, r1
+ 80007c4: 781b ldrb r3, [r3, #0]
+ 80007c6: 005b lsls r3, r3, #1
+ 80007c8: b25b sxtb r3, r3
+ 80007ca: 2231 movs r2, #49 ; 0x31
+ 80007cc: 4053 eors r3, r2
+ 80007ce: b25a sxtb r2, r3
+ 80007d0: 187b adds r3, r7, r1
+ 80007d2: 701a strb r2, [r3, #0]
+ 80007d4: e005 b.n 80007e2
+ } else {
+ crc = (crc << 1);
+ 80007d6: 230d movs r3, #13
+ 80007d8: 18fa adds r2, r7, r3
+ 80007da: 18fb adds r3, r7, r3
+ 80007dc: 781b ldrb r3, [r3, #0]
+ 80007de: 18db adds r3, r3, r3
+ 80007e0: 7013 strb r3, [r2, #0]
+ for(crc_bit = 8; crc_bit > 0; --crc_bit) {
+ 80007e2: 220c movs r2, #12
+ 80007e4: 18bb adds r3, r7, r2
+ 80007e6: 18ba adds r2, r7, r2
+ 80007e8: 7812 ldrb r2, [r2, #0]
+ 80007ea: 3a01 subs r2, #1
+ 80007ec: 701a strb r2, [r3, #0]
+ 80007ee: 230c movs r3, #12
+ 80007f0: 18fb adds r3, r7, r3
+ 80007f2: 781b ldrb r3, [r3, #0]
+ 80007f4: 2b00 cmp r3, #0
+ 80007f6: d1de bne.n 80007b6
+ for (current_byte = 0; current_byte < count; ++current_byte) {
+ 80007f8: 220e movs r2, #14
+ 80007fa: 18bb adds r3, r7, r2
+ 80007fc: 18ba adds r2, r7, r2
+ 80007fe: 8812 ldrh r2, [r2, #0]
+ 8000800: 3201 adds r2, #1
+ 8000802: 801a strh r2, [r3, #0]
+ 8000804: 230e movs r3, #14
+ 8000806: 18fa adds r2, r7, r3
+ 8000808: 1cbb adds r3, r7, #2
+ 800080a: 8812 ldrh r2, [r2, #0]
+ 800080c: 881b ldrh r3, [r3, #0]
+ 800080e: 429a cmp r2, r3
+ 8000810: d3c0 bcc.n 8000794
+ }
+ }
+ }
+ return crc;
+ 8000812: 230d movs r3, #13
+ 8000814: 18fb adds r3, r7, r3
+ 8000816: 781b ldrb r3, [r3, #0]
+}
+ 8000818: 0018 movs r0, r3
+ 800081a: 46bd mov sp, r7
+ 800081c: b004 add sp, #16
+ 800081e: bd80 pop {r7, pc}
+
+08000820 :
+ * @rmtoll ISR TXE LL_I2C_IsActiveFlag_TXE
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_TXE(I2C_TypeDef *I2Cx)
+{
+ 8000820: b580 push {r7, lr}
+ 8000822: b082 sub sp, #8
+ 8000824: af00 add r7, sp, #0
+ 8000826: 6078 str r0, [r7, #4]
+ return ((READ_BIT(I2Cx->ISR, I2C_ISR_TXE) == (I2C_ISR_TXE)) ? 1UL : 0UL);
+ 8000828: 687b ldr r3, [r7, #4]
+ 800082a: 699b ldr r3, [r3, #24]
+ 800082c: 2201 movs r2, #1
+ 800082e: 4013 ands r3, r2
+ 8000830: 2b01 cmp r3, #1
+ 8000832: d101 bne.n 8000838
+ 8000834: 2301 movs r3, #1
+ 8000836: e000 b.n 800083a
+ 8000838: 2300 movs r3, #0
+}
+ 800083a: 0018 movs r0, r3
+ 800083c: 46bd mov sp, r7
+ 800083e: b002 add sp, #8
+ 8000840: bd80 pop {r7, pc}
+
+08000842 :
+ * @rmtoll ISR RXNE LL_I2C_IsActiveFlag_RXNE
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_RXNE(I2C_TypeDef *I2Cx)
+{
+ 8000842: b580 push {r7, lr}
+ 8000844: b082 sub sp, #8
+ 8000846: af00 add r7, sp, #0
+ 8000848: 6078 str r0, [r7, #4]
+ return ((READ_BIT(I2Cx->ISR, I2C_ISR_RXNE) == (I2C_ISR_RXNE)) ? 1UL : 0UL);
+ 800084a: 687b ldr r3, [r7, #4]
+ 800084c: 699b ldr r3, [r3, #24]
+ 800084e: 2204 movs r2, #4
+ 8000850: 4013 ands r3, r2
+ 8000852: 2b04 cmp r3, #4
+ 8000854: d101 bne.n 800085a
+ 8000856: 2301 movs r3, #1
+ 8000858: e000 b.n 800085c
+ 800085a: 2300 movs r3, #0
+}
+ 800085c: 0018 movs r0, r3
+ 800085e: 46bd mov sp, r7
+ 8000860: b002 add sp, #8
+ 8000862: bd80 pop {r7, pc}
+
+08000864 :
+ * @rmtoll ISR STOPF LL_I2C_IsActiveFlag_STOP
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_STOP(I2C_TypeDef *I2Cx)
+{
+ 8000864: b580 push {r7, lr}
+ 8000866: b082 sub sp, #8
+ 8000868: af00 add r7, sp, #0
+ 800086a: 6078 str r0, [r7, #4]
+ return ((READ_BIT(I2Cx->ISR, I2C_ISR_STOPF) == (I2C_ISR_STOPF)) ? 1UL : 0UL);
+ 800086c: 687b ldr r3, [r7, #4]
+ 800086e: 699b ldr r3, [r3, #24]
+ 8000870: 2220 movs r2, #32
+ 8000872: 4013 ands r3, r2
+ 8000874: 2b20 cmp r3, #32
+ 8000876: d101 bne.n 800087c
+ 8000878: 2301 movs r3, #1
+ 800087a: e000 b.n 800087e
+ 800087c: 2300 movs r3, #0
+}
+ 800087e: 0018 movs r0, r3
+ 8000880: 46bd mov sp, r7
+ 8000882: b002 add sp, #8
+ 8000884: bd80 pop {r7, pc}
+
+08000886 :
+ * @rmtoll ICR STOPCF LL_I2C_ClearFlag_STOP
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_STOP(I2C_TypeDef *I2Cx)
+{
+ 8000886: b580 push {r7, lr}
+ 8000888: b082 sub sp, #8
+ 800088a: af00 add r7, sp, #0
+ 800088c: 6078 str r0, [r7, #4]
+ SET_BIT(I2Cx->ICR, I2C_ICR_STOPCF);
+ 800088e: 687b ldr r3, [r7, #4]
+ 8000890: 69db ldr r3, [r3, #28]
+ 8000892: 2220 movs r2, #32
+ 8000894: 431a orrs r2, r3
+ 8000896: 687b ldr r3, [r7, #4]
+ 8000898: 61da str r2, [r3, #28]
+}
+ 800089a: 46c0 nop ; (mov r8, r8)
+ 800089c: 46bd mov sp, r7
+ 800089e: b002 add sp, #8
+ 80008a0: bd80 pop {r7, pc}
+
+080008a2 :
+ * @rmtoll ISR TXE LL_I2C_ClearFlag_TXE
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_TXE(I2C_TypeDef *I2Cx)
+{
+ 80008a2: b580 push {r7, lr}
+ 80008a4: b082 sub sp, #8
+ 80008a6: af00 add r7, sp, #0
+ 80008a8: 6078 str r0, [r7, #4]
+ WRITE_REG(I2Cx->ISR, I2C_ISR_TXE);
+ 80008aa: 687b ldr r3, [r7, #4]
+ 80008ac: 2201 movs r2, #1
+ 80008ae: 619a str r2, [r3, #24]
+}
+ 80008b0: 46c0 nop ; (mov r8, r8)
+ 80008b2: 46bd mov sp, r7
+ 80008b4: b002 add sp, #8
+ 80008b6: bd80 pop {r7, pc}
+
+080008b8 :
+ * @arg @ref LL_I2C_GENERATE_RESTART_10BIT_WRITE
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_HandleTransfer(I2C_TypeDef *I2Cx, uint32_t SlaveAddr, uint32_t SlaveAddrSize,
+ uint32_t TransferSize, uint32_t EndMode, uint32_t Request)
+{
+ 80008b8: b580 push {r7, lr}
+ 80008ba: b084 sub sp, #16
+ 80008bc: af00 add r7, sp, #0
+ 80008be: 60f8 str r0, [r7, #12]
+ 80008c0: 60b9 str r1, [r7, #8]
+ 80008c2: 607a str r2, [r7, #4]
+ 80008c4: 603b str r3, [r7, #0]
+ MODIFY_REG(I2Cx->CR2, I2C_CR2_SADD | I2C_CR2_ADD10 |
+ 80008c6: 68fb ldr r3, [r7, #12]
+ 80008c8: 685b ldr r3, [r3, #4]
+ 80008ca: 69fa ldr r2, [r7, #28]
+ 80008cc: 0d51 lsrs r1, r2, #21
+ 80008ce: 2280 movs r2, #128 ; 0x80
+ 80008d0: 00d2 lsls r2, r2, #3
+ 80008d2: 400a ands r2, r1
+ 80008d4: 490a ldr r1, [pc, #40] ; (8000900 )
+ 80008d6: 430a orrs r2, r1
+ 80008d8: 43d2 mvns r2, r2
+ 80008da: 401a ands r2, r3
+ 80008dc: 68b9 ldr r1, [r7, #8]
+ 80008de: 687b ldr r3, [r7, #4]
+ 80008e0: 4319 orrs r1, r3
+ 80008e2: 683b ldr r3, [r7, #0]
+ 80008e4: 041b lsls r3, r3, #16
+ 80008e6: 4319 orrs r1, r3
+ 80008e8: 69bb ldr r3, [r7, #24]
+ 80008ea: 4319 orrs r1, r3
+ 80008ec: 69fb ldr r3, [r7, #28]
+ 80008ee: 430b orrs r3, r1
+ 80008f0: 431a orrs r2, r3
+ 80008f2: 68fb ldr r3, [r7, #12]
+ 80008f4: 605a str r2, [r3, #4]
+ (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) |
+ I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_RELOAD |
+ I2C_CR2_NBYTES | I2C_CR2_AUTOEND | I2C_CR2_HEAD10R,
+ SlaveAddr | SlaveAddrSize | (TransferSize << I2C_CR2_NBYTES_Pos) | EndMode | Request);
+}
+ 80008f6: 46c0 nop ; (mov r8, r8)
+ 80008f8: 46bd mov sp, r7
+ 80008fa: b004 add sp, #16
+ 80008fc: bd80 pop {r7, pc}
+ 80008fe: 46c0 nop ; (mov r8, r8)
+ 8000900: 03ff7bff .word 0x03ff7bff
+
+08000904 :
+ * @rmtoll RXDR RXDATA LL_I2C_ReceiveData8
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x00 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint8_t LL_I2C_ReceiveData8(I2C_TypeDef *I2Cx)
+{
+ 8000904: b580 push {r7, lr}
+ 8000906: b082 sub sp, #8
+ 8000908: af00 add r7, sp, #0
+ 800090a: 6078 str r0, [r7, #4]
+ return (uint8_t)(READ_BIT(I2Cx->RXDR, I2C_RXDR_RXDATA));
+ 800090c: 687b ldr r3, [r7, #4]
+ 800090e: 6a5b ldr r3, [r3, #36] ; 0x24
+ 8000910: b2db uxtb r3, r3
+}
+ 8000912: 0018 movs r0, r3
+ 8000914: 46bd mov sp, r7
+ 8000916: b002 add sp, #8
+ 8000918: bd80 pop {r7, pc}
+
+0800091a :
+ * @param I2Cx I2C Instance.
+ * @param Data Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_TransmitData8(I2C_TypeDef *I2Cx, uint8_t Data)
+{
+ 800091a: b580 push {r7, lr}
+ 800091c: b082 sub sp, #8
+ 800091e: af00 add r7, sp, #0
+ 8000920: 6078 str r0, [r7, #4]
+ 8000922: 000a movs r2, r1
+ 8000924: 1cfb adds r3, r7, #3
+ 8000926: 701a strb r2, [r3, #0]
+ WRITE_REG(I2Cx->TXDR, Data);
+ 8000928: 1cfb adds r3, r7, #3
+ 800092a: 781a ldrb r2, [r3, #0]
+ 800092c: 687b ldr r3, [r7, #4]
+ 800092e: 629a str r2, [r3, #40] ; 0x28
+}
+ 8000930: 46c0 nop ; (mov r8, r8)
+ 8000932: 46bd mov sp, r7
+ 8000934: b002 add sp, #8
+ 8000936: bd80 pop {r7, pc}
+
+08000938 :
+#include "stm32l0xx_ll_usart.h"
+
+static i2c_context_t *i2c_context;
+
+int8_t i2c_init(i2c_context_t *context)
+{
+ 8000938: b580 push {r7, lr}
+ 800093a: b082 sub sp, #8
+ 800093c: af00 add r7, sp, #0
+ 800093e: 6078 str r0, [r7, #4]
+ if (context == NULL) {
+ 8000940: 687b ldr r3, [r7, #4]
+ 8000942: 2b00 cmp r3, #0
+ 8000944: d102 bne.n 800094c
+ return I2C_ERROR;
+ 8000946: 2301 movs r3, #1
+ 8000948: 425b negs r3, r3
+ 800094a: e003 b.n 8000954
+ }
+ i2c_context = context;
+ 800094c: 4b03 ldr r3, [pc, #12] ; (800095c )
+ 800094e: 687a ldr r2, [r7, #4]
+ 8000950: 601a str r2, [r3, #0]
+ return I2C_OK;
+ 8000952: 2300 movs r3, #0
+}
+ 8000954: 0018 movs r0, r3
+ 8000956: 46bd mov sp, r7
+ 8000958: b002 add sp, #8
+ 800095a: bd80 pop {r7, pc}
+ 800095c: 20000024 .word 0x20000024
+
+08000960 :
+
+int8_t i2c_transmit(uint8_t address, uint8_t *buffer, int len)
+{
+ 8000960: b580 push {r7, lr}
+ 8000962: b088 sub sp, #32
+ 8000964: af02 add r7, sp, #8
+ 8000966: 60b9 str r1, [r7, #8]
+ 8000968: 607a str r2, [r7, #4]
+ 800096a: 210f movs r1, #15
+ 800096c: 187b adds r3, r7, r1
+ 800096e: 1c02 adds r2, r0, #0
+ 8000970: 701a strb r2, [r3, #0]
+ LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len,
+ 8000972: 4b25 ldr r3, [pc, #148] ; (8000a08 )
+ 8000974: 681b ldr r3, [r3, #0]
+ 8000976: 6818 ldr r0, [r3, #0]
+ 8000978: 187b adds r3, r7, r1
+ 800097a: 7819 ldrb r1, [r3, #0]
+ 800097c: 687a ldr r2, [r7, #4]
+ 800097e: 4b23 ldr r3, [pc, #140] ; (8000a0c )
+ 8000980: 9301 str r3, [sp, #4]
+ 8000982: 2380 movs r3, #128 ; 0x80
+ 8000984: 049b lsls r3, r3, #18
+ 8000986: 9300 str r3, [sp, #0]
+ 8000988: 0013 movs r3, r2
+ 800098a: 2200 movs r2, #0
+ 800098c: f7ff ff94 bl 80008b8
+ LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
+ int i = 0;
+ 8000990: 2300 movs r3, #0
+ 8000992: 617b str r3, [r7, #20]
+ /* 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)) {
+ 8000994: e018 b.n 80009c8
+ if (LL_I2C_IsActiveFlag_TXE(i2c_context->i2c)) {
+ 8000996: 4b1c ldr r3, [pc, #112] ; (8000a08 )
+ 8000998: 681b ldr r3, [r3, #0]
+ 800099a: 681b ldr r3, [r3, #0]
+ 800099c: 0018 movs r0, r3
+ 800099e: f7ff ff3f bl 8000820
+ 80009a2: 1e03 subs r3, r0, #0
+ 80009a4: d010 beq.n 80009c8
+ if (i < len) {
+ 80009a6: 697a ldr r2, [r7, #20]
+ 80009a8: 687b ldr r3, [r7, #4]
+ 80009aa: 429a cmp r2, r3
+ 80009ac: da0c bge.n 80009c8
+ LL_I2C_TransmitData8(i2c_context->i2c, buffer[i++]);
+ 80009ae: 4b16 ldr r3, [pc, #88] ; (8000a08 )
+ 80009b0: 681b ldr r3, [r3, #0]
+ 80009b2: 6818 ldr r0, [r3, #0]
+ 80009b4: 697b ldr r3, [r7, #20]
+ 80009b6: 1c5a adds r2, r3, #1
+ 80009b8: 617a str r2, [r7, #20]
+ 80009ba: 001a movs r2, r3
+ 80009bc: 68bb ldr r3, [r7, #8]
+ 80009be: 189b adds r3, r3, r2
+ 80009c0: 781b ldrb r3, [r3, #0]
+ 80009c2: 0019 movs r1, r3
+ 80009c4: f7ff ffa9 bl 800091a
+ while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
+ 80009c8: 4b0f ldr r3, [pc, #60] ; (8000a08 )
+ 80009ca: 681b ldr r3, [r3, #0]
+ 80009cc: 681b ldr r3, [r3, #0]
+ 80009ce: 0018 movs r0, r3
+ 80009d0: f7ff ff48 bl 8000864
+ 80009d4: 1e03 subs r3, r0, #0
+ 80009d6: d0de beq.n 8000996
+ }
+ }
+ }
+ LL_I2C_ClearFlag_STOP(i2c_context->i2c);
+ 80009d8: 4b0b ldr r3, [pc, #44] ; (8000a08 )
+ 80009da: 681b ldr r3, [r3, #0]
+ 80009dc: 681b ldr r3, [r3, #0]
+ 80009de: 0018 movs r0, r3
+ 80009e0: f7ff ff51 bl 8000886
+ LL_I2C_ClearFlag_TXE(i2c_context->i2c);
+ 80009e4: 4b08 ldr r3, [pc, #32] ; (8000a08 )
+ 80009e6: 681b ldr r3, [r3, #0]
+ 80009e8: 681b ldr r3, [r3, #0]
+ 80009ea: 0018 movs r0, r3
+ 80009ec: f7ff ff59 bl 80008a2
+ if (len != i) {
+ 80009f0: 687a ldr r2, [r7, #4]
+ 80009f2: 697b ldr r3, [r7, #20]
+ 80009f4: 429a cmp r2, r3
+ 80009f6: d002 beq.n 80009fe
+ /* If we detect NACK during transaction (before the end of the last byte) */
+ return I2C_ERROR_TX_INCOMPLETE;
+ 80009f8: 2303 movs r3, #3
+ 80009fa: 425b negs r3, r3
+ 80009fc: e000 b.n 8000a00
+ /* NACK after last byte is ok */
+// if (LL_I2C_IsActiveFlag_NACK(i2c_context->i2c)) {
+//
+// return I2C_ERROR_NACK;
+// }
+ return I2C_OK;
+ 80009fe: 2300 movs r3, #0
+}
+ 8000a00: 0018 movs r0, r3
+ 8000a02: 46bd mov sp, r7
+ 8000a04: b006 add sp, #24
+ 8000a06: bd80 pop {r7, pc}
+ 8000a08: 20000024 .word 0x20000024
+ 8000a0c: 80002000 .word 0x80002000
+
+08000a10 :
+
+int8_t i2c_receive(uint8_t address, uint8_t *buffer, int len)
+{
+ 8000a10: b590 push {r4, r7, lr}
+ 8000a12: b089 sub sp, #36 ; 0x24
+ 8000a14: af02 add r7, sp, #8
+ 8000a16: 60b9 str r1, [r7, #8]
+ 8000a18: 607a str r2, [r7, #4]
+ 8000a1a: 210f movs r1, #15
+ 8000a1c: 187b adds r3, r7, r1
+ 8000a1e: 1c02 adds r2, r0, #0
+ 8000a20: 701a strb r2, [r3, #0]
+ LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len,
+ 8000a22: 4b26 ldr r3, [pc, #152] ; (8000abc )
+ 8000a24: 681b ldr r3, [r3, #0]
+ 8000a26: 6818 ldr r0, [r3, #0]
+ 8000a28: 187b adds r3, r7, r1
+ 8000a2a: 7819 ldrb r1, [r3, #0]
+ 8000a2c: 687a ldr r2, [r7, #4]
+ 8000a2e: 4b24 ldr r3, [pc, #144] ; (8000ac0 )
+ 8000a30: 9301 str r3, [sp, #4]
+ 8000a32: 2380 movs r3, #128 ; 0x80
+ 8000a34: 049b lsls r3, r3, #18
+ 8000a36: 9300 str r3, [sp, #0]
+ 8000a38: 0013 movs r3, r2
+ 8000a3a: 2200 movs r2, #0
+ 8000a3c: f7ff ff3c bl 80008b8
+ LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
+ LL_I2C_ClearFlag_STOP(i2c_context->i2c);
+ 8000a40: 4b1e ldr r3, [pc, #120] ; (8000abc )
+ 8000a42: 681b ldr r3, [r3, #0]
+ 8000a44: 681b ldr r3, [r3, #0]
+ 8000a46: 0018 movs r0, r3
+ 8000a48: f7ff ff1d bl 8000886
+ int i = 0;
+ 8000a4c: 2300 movs r3, #0
+ 8000a4e: 617b str r3, [r7, #20]
+ while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
+ 8000a50: e019 b.n 8000a86
+ if (LL_I2C_IsActiveFlag_RXNE(i2c_context->i2c)) {
+ 8000a52: 4b1a ldr r3, [pc, #104] ; (8000abc )
+ 8000a54: 681b ldr r3, [r3, #0]
+ 8000a56: 681b ldr r3, [r3, #0]
+ 8000a58: 0018 movs r0, r3
+ 8000a5a: f7ff fef2 bl 8000842
+ 8000a5e: 1e03 subs r3, r0, #0
+ 8000a60: d011 beq.n 8000a86
+ if (i < len) {
+ 8000a62: 697a ldr r2, [r7, #20]
+ 8000a64: 687b ldr r3, [r7, #4]
+ 8000a66: 429a cmp r2, r3
+ 8000a68: da0d bge.n 8000a86
+ buffer[i++] = LL_I2C_ReceiveData8(i2c_context->i2c);
+ 8000a6a: 4b14 ldr r3, [pc, #80] ; (8000abc )
+ 8000a6c: 681b ldr r3, [r3, #0]
+ 8000a6e: 6819 ldr r1, [r3, #0]
+ 8000a70: 697b ldr r3, [r7, #20]
+ 8000a72: 1c5a adds r2, r3, #1
+ 8000a74: 617a str r2, [r7, #20]
+ 8000a76: 001a movs r2, r3
+ 8000a78: 68bb ldr r3, [r7, #8]
+ 8000a7a: 189c adds r4, r3, r2
+ 8000a7c: 0008 movs r0, r1
+ 8000a7e: f7ff ff41 bl 8000904
+ 8000a82: 0003 movs r3, r0
+ 8000a84: 7023 strb r3, [r4, #0]
+ while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
+ 8000a86: 4b0d ldr r3, [pc, #52] ; (8000abc )
+ 8000a88: 681b ldr r3, [r3, #0]
+ 8000a8a: 681b ldr r3, [r3, #0]
+ 8000a8c: 0018 movs r0, r3
+ 8000a8e: f7ff fee9 bl 8000864
+ 8000a92: 1e03 subs r3, r0, #0
+ 8000a94: d0dd beq.n 8000a52
+ }
+ }
+ }
+ LL_I2C_ClearFlag_STOP(i2c_context->i2c);
+ 8000a96: 4b09 ldr r3, [pc, #36] ; (8000abc )
+ 8000a98: 681b ldr r3, [r3, #0]
+ 8000a9a: 681b ldr r3, [r3, #0]
+ 8000a9c: 0018 movs r0, r3
+ 8000a9e: f7ff fef2 bl 8000886
+ if (len != i) {
+ 8000aa2: 687a ldr r2, [r7, #4]
+ 8000aa4: 697b ldr r3, [r7, #20]
+ 8000aa6: 429a cmp r2, r3
+ 8000aa8: d002 beq.n 8000ab0
+ return I2C_ERROR_RX_INCOMPLETE;
+ 8000aaa: 2304 movs r3, #4
+ 8000aac: 425b negs r3, r3
+ 8000aae: e000 b.n 8000ab2
+ }
+
+ return I2C_OK;
+ 8000ab0: 2300 movs r3, #0
+}
+ 8000ab2: 0018 movs r0, r3
+ 8000ab4: 46bd mov sp, r7
+ 8000ab6: b007 add sp, #28
+ 8000ab8: bd90 pop {r4, r7, pc}
+ 8000aba: 46c0 nop ; (mov r8, r8)
+ 8000abc: 20000024 .word 0x20000024
+ 8000ac0: 80002400 .word 0x80002400
+
+08000ac4 :
+ */
+#include "ltr329.h"
+#include "main.h" /* for uart_disable_interrupts() */
+
+static int8_t ltr329_read_register (ltr329_cmd_t register_addr, uint8_t *register_data )
+{
+ 8000ac4: b590 push {r4, r7, lr}
+ 8000ac6: b087 sub sp, #28
+ 8000ac8: af00 add r7, sp, #0
+ 8000aca: 0002 movs r2, r0
+ 8000acc: 6039 str r1, [r7, #0]
+ 8000ace: 1dfb adds r3, r7, #7
+ 8000ad0: 701a strb r2, [r3, #0]
+ uint8_t tx_buffer[1];
+ uint8_t rx_buffer[1];
+ int result;
+
+ // start measurement
+ tx_buffer[0] = register_addr;
+ 8000ad2: 2410 movs r4, #16
+ 8000ad4: 193b adds r3, r7, r4
+ 8000ad6: 1dfa adds r2, r7, #7
+ 8000ad8: 7812 ldrb r2, [r2, #0]
+ 8000ada: 701a strb r2, [r3, #0]
+ /* disable interrupts to prevent modbus/i2c conflict */
+ uart_disable_interrupts();
+ 8000adc: f001 fa32 bl 8001f44
+ result = i2c_transmit(LTR329_I2C_ADDRESS<<1, tx_buffer, 1);
+ 8000ae0: 193b adds r3, r7, r4
+ 8000ae2: 2201 movs r2, #1
+ 8000ae4: 0019 movs r1, r3
+ 8000ae6: 2052 movs r0, #82 ; 0x52
+ 8000ae8: f7ff ff3a bl 8000960
+ 8000aec: 0003 movs r3, r0
+ 8000aee: 617b str r3, [r7, #20]
+ uart_enable_interrupts();
+ 8000af0: f001 fa3c bl 8001f6c
+ if (result != I2C_OK) {
+ 8000af4: 697b ldr r3, [r7, #20]
+ 8000af6: 2b00 cmp r3, #0
+ 8000af8: d002 beq.n 8000b00
+ return LTR329_ERROR;
+ 8000afa: 2301 movs r3, #1
+ 8000afc: 425b negs r3, r3
+ 8000afe: e01b b.n 8000b38
+ }
+ LL_mDelay(10); /* 10 ms should be enough */
+ 8000b00: 200a movs r0, #10
+ 8000b02: f002 ffe5 bl 8003ad0
+ /* read out */
+ uart_disable_interrupts();
+ 8000b06: f001 fa1d bl 8001f44
+ result = i2c_receive(LTR329_I2C_ADDRESS<<1, rx_buffer, 1);
+ 8000b0a: 230c movs r3, #12
+ 8000b0c: 18fb adds r3, r7, r3
+ 8000b0e: 2201 movs r2, #1
+ 8000b10: 0019 movs r1, r3
+ 8000b12: 2052 movs r0, #82 ; 0x52
+ 8000b14: f7ff ff7c bl 8000a10
+ 8000b18: 0003 movs r3, r0
+ 8000b1a: 617b str r3, [r7, #20]
+ uart_enable_interrupts();
+ 8000b1c: f001 fa26 bl 8001f6c
+ if (result != I2C_OK) {
+ 8000b20: 697b ldr r3, [r7, #20]
+ 8000b22: 2b00 cmp r3, #0
+ 8000b24: d002 beq.n 8000b2c
+ return LTR329_ERROR;
+ 8000b26: 2301 movs r3, #1
+ 8000b28: 425b negs r3, r3
+ 8000b2a: e005 b.n 8000b38
+ }
+
+ *register_data = rx_buffer[0];
+ 8000b2c: 230c movs r3, #12
+ 8000b2e: 18fb adds r3, r7, r3
+ 8000b30: 781a ldrb r2, [r3, #0]
+ 8000b32: 683b ldr r3, [r7, #0]
+ 8000b34: 701a strb r2, [r3, #0]
+ return LTR329_OK;
+ 8000b36: 2300 movs r3, #0
+}
+ 8000b38: 0018 movs r0, r3
+ 8000b3a: 46bd mov sp, r7
+ 8000b3c: b007 add sp, #28
+ 8000b3e: bd90 pop {r4, r7, pc}
+
+08000b40 :
+
+static int8_t ltr329_write_register (ltr329_cmd_t register_addr, uint8_t register_data)
+{
+ 8000b40: b590 push {r4, r7, lr}
+ 8000b42: b085 sub sp, #20
+ 8000b44: af00 add r7, sp, #0
+ 8000b46: 0002 movs r2, r0
+ 8000b48: 1dfb adds r3, r7, #7
+ 8000b4a: 701a strb r2, [r3, #0]
+ 8000b4c: 1dbb adds r3, r7, #6
+ 8000b4e: 1c0a adds r2, r1, #0
+ 8000b50: 701a strb r2, [r3, #0]
+ uint8_t tx_buffer[2];
+ int result;
+
+ // start measurement
+ tx_buffer[0] = register_addr;
+ 8000b52: 2408 movs r4, #8
+ 8000b54: 193b adds r3, r7, r4
+ 8000b56: 1dfa adds r2, r7, #7
+ 8000b58: 7812 ldrb r2, [r2, #0]
+ 8000b5a: 701a strb r2, [r3, #0]
+ tx_buffer[1] = register_data;
+ 8000b5c: 193b adds r3, r7, r4
+ 8000b5e: 1dba adds r2, r7, #6
+ 8000b60: 7812 ldrb r2, [r2, #0]
+ 8000b62: 705a strb r2, [r3, #1]
+ /* disable interrupts to prevent modbus/i2c conflict */
+ uart_disable_interrupts();
+ 8000b64: f001 f9ee bl 8001f44
+ result = i2c_transmit(LTR329_I2C_ADDRESS<<1, tx_buffer, 2);
+ 8000b68: 193b adds r3, r7, r4
+ 8000b6a: 2202 movs r2, #2
+ 8000b6c: 0019 movs r1, r3
+ 8000b6e: 2052 movs r0, #82 ; 0x52
+ 8000b70: f7ff fef6 bl 8000960
+ 8000b74: 0003 movs r3, r0
+ 8000b76: 60fb str r3, [r7, #12]
+ uart_enable_interrupts();
+ 8000b78: f001 f9f8 bl 8001f6c
+ if (result != I2C_OK) {
+ 8000b7c: 68fb ldr r3, [r7, #12]
+ 8000b7e: 2b00 cmp r3, #0
+ 8000b80: d002 beq.n 8000b88
+ return LTR329_ERROR;
+ 8000b82: 2301 movs r3, #1
+ 8000b84: 425b negs r3, r3
+ 8000b86: e000 b.n 8000b8a
+ }
+ return LTR329_OK;
+ 8000b88: 2300 movs r3, #0
+}
+ 8000b8a: 0018 movs r0, r3
+ 8000b8c: 46bd mov sp, r7
+ 8000b8e: b005 add sp, #20
+ 8000b90: bd90 pop {r4, r7, pc}
+
+08000b92 :
+
+int8_t ltr329_write_settings (ltr329_gain_t gain, ltr329_als_mode_t mode, ltr329_integration_time_t integ_time, ltr329_measurement_rate_t meas_rate)
+{
+ 8000b92: b5b0 push {r4, r5, r7, lr}
+ 8000b94: b084 sub sp, #16
+ 8000b96: af00 add r7, sp, #0
+ 8000b98: 0005 movs r5, r0
+ 8000b9a: 000c movs r4, r1
+ 8000b9c: 0010 movs r0, r2
+ 8000b9e: 0019 movs r1, r3
+ 8000ba0: 1dfb adds r3, r7, #7
+ 8000ba2: 1c2a adds r2, r5, #0
+ 8000ba4: 701a strb r2, [r3, #0]
+ 8000ba6: 1dbb adds r3, r7, #6
+ 8000ba8: 1c22 adds r2, r4, #0
+ 8000baa: 701a strb r2, [r3, #0]
+ 8000bac: 1d7b adds r3, r7, #5
+ 8000bae: 1c02 adds r2, r0, #0
+ 8000bb0: 701a strb r2, [r3, #0]
+ 8000bb2: 1d3b adds r3, r7, #4
+ 8000bb4: 1c0a adds r2, r1, #0
+ 8000bb6: 701a strb r2, [r3, #0]
+ int8_t result;
+ /* Write Gain and ALS Mode */
+ result = ltr329_write_register(LTR329_ALS_CONTR, (gain | mode));
+ 8000bb8: 1dfa adds r2, r7, #7
+ 8000bba: 1dbb adds r3, r7, #6
+ 8000bbc: 7812 ldrb r2, [r2, #0]
+ 8000bbe: 781b ldrb r3, [r3, #0]
+ 8000bc0: 4313 orrs r3, r2
+ 8000bc2: b2db uxtb r3, r3
+ 8000bc4: 250f movs r5, #15
+ 8000bc6: 197c adds r4, r7, r5
+ 8000bc8: 0019 movs r1, r3
+ 8000bca: 2080 movs r0, #128 ; 0x80
+ 8000bcc: f7ff ffb8 bl 8000b40
+ 8000bd0: 0003 movs r3, r0
+ 8000bd2: 7023 strb r3, [r4, #0]
+ if (result != LTR329_OK)
+ 8000bd4: 197b adds r3, r7, r5
+ 8000bd6: 781b ldrb r3, [r3, #0]
+ 8000bd8: b25b sxtb r3, r3
+ 8000bda: 2b00 cmp r3, #0
+ 8000bdc: d002 beq.n 8000be4
+ {
+ return LTR329_ERROR;
+ 8000bde: 2301 movs r3, #1
+ 8000be0: 425b negs r3, r3
+ 8000be2: e016 b.n 8000c12
+ }
+ /* Write Integration Time and Measurement Rate */
+
+ result = ltr329_write_register(LTR329_ALS_MEAS_RATE, (integ_time | meas_rate));
+ 8000be4: 1d7a adds r2, r7, #5
+ 8000be6: 1d3b adds r3, r7, #4
+ 8000be8: 7812 ldrb r2, [r2, #0]
+ 8000bea: 781b ldrb r3, [r3, #0]
+ 8000bec: 4313 orrs r3, r2
+ 8000bee: b2db uxtb r3, r3
+ 8000bf0: 250f movs r5, #15
+ 8000bf2: 197c adds r4, r7, r5
+ 8000bf4: 0019 movs r1, r3
+ 8000bf6: 2085 movs r0, #133 ; 0x85
+ 8000bf8: f7ff ffa2 bl 8000b40
+ 8000bfc: 0003 movs r3, r0
+ 8000bfe: 7023 strb r3, [r4, #0]
+ if (result != LTR329_OK)
+ 8000c00: 197b adds r3, r7, r5
+ 8000c02: 781b ldrb r3, [r3, #0]
+ 8000c04: b25b sxtb r3, r3
+ 8000c06: 2b00 cmp r3, #0
+ 8000c08: d002 beq.n 8000c10
+ {
+ return LTR329_ERROR;
+ 8000c0a: 2301 movs r3, #1
+ 8000c0c: 425b negs r3, r3
+ 8000c0e: e000 b.n 8000c12
+ }
+ return LTR329_OK;
+ 8000c10: 2300 movs r3, #0
+}
+ 8000c12: 0018 movs r0, r3
+ 8000c14: 46bd mov sp, r7
+ 8000c16: b004 add sp, #16
+ 8000c18: bdb0 pop {r4, r5, r7, pc}
+
+08000c1a :
+ }
+ return LTR329_OK;
+}
+
+int8_t ltr329_measure (uint16_t *data_ch0, uint16_t *data_ch1)
+{
+ 8000c1a: b580 push {r7, lr}
+ 8000c1c: b084 sub sp, #16
+ 8000c1e: af00 add r7, sp, #0
+ 8000c20: 6078 str r0, [r7, #4]
+ 8000c22: 6039 str r1, [r7, #0]
+ uint8_t ch0_l, ch0_h, ch1_l, ch1_h;
+ int result;
+ result = ltr329_read_register(LTR329_ALS_DATA_CH0_0, &ch0_l);
+ 8000c24: 230b movs r3, #11
+ 8000c26: 18fb adds r3, r7, r3
+ 8000c28: 0019 movs r1, r3
+ 8000c2a: 208a movs r0, #138 ; 0x8a
+ 8000c2c: f7ff ff4a bl 8000ac4
+ 8000c30: 0003 movs r3, r0
+ 8000c32: 60fb str r3, [r7, #12]
+ if (result != LTR329_OK)
+ 8000c34: 68fb ldr r3, [r7, #12]
+ 8000c36: 2b00 cmp r3, #0
+ 8000c38: d002 beq.n 8000c40
+ {
+ return LTR329_ERROR;
+ 8000c3a: 2301 movs r3, #1
+ 8000c3c: 425b negs r3, r3
+ 8000c3e: e046 b.n 8000cce
+ }
+ result = ltr329_read_register(LTR329_ALS_DATA_CH0_1, &ch0_h);
+ 8000c40: 230a movs r3, #10
+ 8000c42: 18fb adds r3, r7, r3
+ 8000c44: 0019 movs r1, r3
+ 8000c46: 208b movs r0, #139 ; 0x8b
+ 8000c48: f7ff ff3c bl 8000ac4
+ 8000c4c: 0003 movs r3, r0
+ 8000c4e: 60fb str r3, [r7, #12]
+ if (result != LTR329_OK)
+ 8000c50: 68fb ldr r3, [r7, #12]
+ 8000c52: 2b00 cmp r3, #0
+ 8000c54: d002 beq.n 8000c5c
+ {
+ return LTR329_ERROR;
+ 8000c56: 2301 movs r3, #1
+ 8000c58: 425b negs r3, r3
+ 8000c5a: e038 b.n 8000cce
+ }
+ result = ltr329_read_register(LTR329_ALS_DATA_CH1_0, &ch1_l);
+ 8000c5c: 2309 movs r3, #9
+ 8000c5e: 18fb adds r3, r7, r3
+ 8000c60: 0019 movs r1, r3
+ 8000c62: 2088 movs r0, #136 ; 0x88
+ 8000c64: f7ff ff2e bl 8000ac4
+ 8000c68: 0003 movs r3, r0
+ 8000c6a: 60fb str r3, [r7, #12]
+ if (result != LTR329_OK)
+ 8000c6c: 68fb ldr r3, [r7, #12]
+ 8000c6e: 2b00 cmp r3, #0
+ 8000c70: d002 beq.n 8000c78
+ {
+ return LTR329_ERROR;
+ 8000c72: 2301 movs r3, #1
+ 8000c74: 425b negs r3, r3
+ 8000c76: e02a b.n 8000cce
+ }
+ result = ltr329_read_register(LTR329_ALS_DATA_CH1_1, &ch1_h);
+ 8000c78: 2308 movs r3, #8
+ 8000c7a: 18fb adds r3, r7, r3
+ 8000c7c: 0019 movs r1, r3
+ 8000c7e: 2089 movs r0, #137 ; 0x89
+ 8000c80: f7ff ff20 bl 8000ac4
+ 8000c84: 0003 movs r3, r0
+ 8000c86: 60fb str r3, [r7, #12]
+ if (result != LTR329_OK)
+ 8000c88: 68fb ldr r3, [r7, #12]
+ 8000c8a: 2b00 cmp r3, #0
+ 8000c8c: d002 beq.n 8000c94
+ {
+ return LTR329_ERROR;
+ 8000c8e: 2301 movs r3, #1
+ 8000c90: 425b negs r3, r3
+ 8000c92: e01c b.n 8000cce
+ }
+
+ *data_ch0 = (ch0_h << 8) + ch0_l;
+ 8000c94: 230a movs r3, #10
+ 8000c96: 18fb adds r3, r7, r3
+ 8000c98: 781b ldrb r3, [r3, #0]
+ 8000c9a: b29b uxth r3, r3
+ 8000c9c: 021b lsls r3, r3, #8
+ 8000c9e: b29a uxth r2, r3
+ 8000ca0: 230b movs r3, #11
+ 8000ca2: 18fb adds r3, r7, r3
+ 8000ca4: 781b ldrb r3, [r3, #0]
+ 8000ca6: b29b uxth r3, r3
+ 8000ca8: 18d3 adds r3, r2, r3
+ 8000caa: b29a uxth r2, r3
+ 8000cac: 687b ldr r3, [r7, #4]
+ 8000cae: 801a strh r2, [r3, #0]
+ *data_ch1 = (ch1_h << 8) + ch1_l;
+ 8000cb0: 2308 movs r3, #8
+ 8000cb2: 18fb adds r3, r7, r3
+ 8000cb4: 781b ldrb r3, [r3, #0]
+ 8000cb6: b29b uxth r3, r3
+ 8000cb8: 021b lsls r3, r3, #8
+ 8000cba: b29a uxth r2, r3
+ 8000cbc: 2309 movs r3, #9
+ 8000cbe: 18fb adds r3, r7, r3
+ 8000cc0: 781b ldrb r3, [r3, #0]
+ 8000cc2: b29b uxth r3, r3
+ 8000cc4: 18d3 adds r3, r2, r3
+ 8000cc6: b29a uxth r2, r3
+ 8000cc8: 683b ldr r3, [r7, #0]
+ 8000cca: 801a strh r2, [r3, #0]
+ return LTR329_OK;
+ 8000ccc: 2300 movs r3, #0
+}
+ 8000cce: 0018 movs r0, r3
+ 8000cd0: 46bd mov sp, r7
+ 8000cd2: b004 add sp, #16
+ 8000cd4: bd80 pop {r7, pc}
+
+08000cd6 :
+
+int8_t ltr329_read_status_register(uint8_t *data_valid, uint8_t *new_data, ltr329_gain_t *gain)
+{
+ 8000cd6: b5b0 push {r4, r5, r7, lr}
+ 8000cd8: b086 sub sp, #24
+ 8000cda: af00 add r7, sp, #0
+ 8000cdc: 60f8 str r0, [r7, #12]
+ 8000cde: 60b9 str r1, [r7, #8]
+ 8000ce0: 607a str r2, [r7, #4]
+ int8_t result;
+ uint8_t status_register_data;
+ result = ltr329_read_register(LTR329_ALS_STATUS, &status_register_data);
+ 8000ce2: 2517 movs r5, #23
+ 8000ce4: 197c adds r4, r7, r5
+ 8000ce6: 2313 movs r3, #19
+ 8000ce8: 18fb adds r3, r7, r3
+ 8000cea: 0019 movs r1, r3
+ 8000cec: 208c movs r0, #140 ; 0x8c
+ 8000cee: f7ff fee9 bl 8000ac4
+ 8000cf2: 0003 movs r3, r0
+ 8000cf4: 7023 strb r3, [r4, #0]
+ if (result != LTR329_OK)
+ 8000cf6: 197b adds r3, r7, r5
+ 8000cf8: 781b ldrb r3, [r3, #0]
+ 8000cfa: b25b sxtb r3, r3
+ 8000cfc: 2b00 cmp r3, #0
+ 8000cfe: d002 beq.n 8000d06
+ {
+ return LTR329_ERROR;
+ 8000d00: 2301 movs r3, #1
+ 8000d02: 425b negs r3, r3
+ 8000d04: e039 b.n 8000d7a
+ }
+
+ /* Check data valid */
+ uint8_t data_invalid_mask = 0b10000000;
+ 8000d06: 2116 movs r1, #22
+ 8000d08: 187b adds r3, r7, r1
+ 8000d0a: 2280 movs r2, #128 ; 0x80
+ 8000d0c: 701a strb r2, [r3, #0]
+ if ((status_register_data & data_invalid_mask) == data_invalid_mask)
+ 8000d0e: 2313 movs r3, #19
+ 8000d10: 18fb adds r3, r7, r3
+ 8000d12: 781b ldrb r3, [r3, #0]
+ 8000d14: 187a adds r2, r7, r1
+ 8000d16: 7812 ldrb r2, [r2, #0]
+ 8000d18: 4013 ands r3, r2
+ 8000d1a: b2db uxtb r3, r3
+ 8000d1c: 187a adds r2, r7, r1
+ 8000d1e: 7812 ldrb r2, [r2, #0]
+ 8000d20: 429a cmp r2, r3
+ 8000d22: d103 bne.n 8000d2c
+ {
+ *data_valid = 0;
+ 8000d24: 68fb ldr r3, [r7, #12]
+ 8000d26: 2200 movs r2, #0
+ 8000d28: 701a strb r2, [r3, #0]
+ 8000d2a: e002 b.n 8000d32
+ } else
+ {
+ *data_valid = 1;
+ 8000d2c: 68fb ldr r3, [r7, #12]
+ 8000d2e: 2201 movs r2, #1
+ 8000d30: 701a strb r2, [r3, #0]
+ }
+
+ /* Check if there is new data */
+ uint8_t data_status_mask = 0b00000100;
+ 8000d32: 2115 movs r1, #21
+ 8000d34: 187b adds r3, r7, r1
+ 8000d36: 2204 movs r2, #4
+ 8000d38: 701a strb r2, [r3, #0]
+ if ((status_register_data & data_status_mask) == data_status_mask)
+ 8000d3a: 2313 movs r3, #19
+ 8000d3c: 18fb adds r3, r7, r3
+ 8000d3e: 781b ldrb r3, [r3, #0]
+ 8000d40: 187a adds r2, r7, r1
+ 8000d42: 7812 ldrb r2, [r2, #0]
+ 8000d44: 4013 ands r3, r2
+ 8000d46: b2db uxtb r3, r3
+ 8000d48: 187a adds r2, r7, r1
+ 8000d4a: 7812 ldrb r2, [r2, #0]
+ 8000d4c: 429a cmp r2, r3
+ 8000d4e: d103 bne.n 8000d58
+ {
+ *new_data = 1;
+ 8000d50: 68bb ldr r3, [r7, #8]
+ 8000d52: 2201 movs r2, #1
+ 8000d54: 701a strb r2, [r3, #0]
+ 8000d56: e002 b.n 8000d5e
+ } else
+ {
+ *new_data = 0;
+ 8000d58: 68bb ldr r3, [r7, #8]
+ 8000d5a: 2200 movs r2, #0
+ 8000d5c: 701a strb r2, [r3, #0]
+ }
+
+ /* Check Gain */
+ /* TODO: This might not be safe */
+ uint8_t gain_mask = 0b01110000;
+ 8000d5e: 2114 movs r1, #20
+ 8000d60: 187b adds r3, r7, r1
+ 8000d62: 2270 movs r2, #112 ; 0x70
+ 8000d64: 701a strb r2, [r3, #0]
+ *gain = status_register_data & gain_mask;
+ 8000d66: 2313 movs r3, #19
+ 8000d68: 18fb adds r3, r7, r3
+ 8000d6a: 781b ldrb r3, [r3, #0]
+ 8000d6c: 187a adds r2, r7, r1
+ 8000d6e: 7812 ldrb r2, [r2, #0]
+ 8000d70: 4013 ands r3, r2
+ 8000d72: b2da uxtb r2, r3
+ 8000d74: 687b ldr r3, [r7, #4]
+ 8000d76: 701a strb r2, [r3, #0]
+
+ return LTR329_OK;
+ 8000d78: 2300 movs r3, #0
+}
+ 8000d7a: 0018 movs r0, r3
+ 8000d7c: 46bd mov sp, r7
+ 8000d7e: b006 add sp, #24
+ 8000d80: bdb0 pop {r4, r5, r7, pc}
+ ...
+
+08000d84 <__NVIC_EnableIRQ>:
+ \details Enables a device specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn Device specific interrupt number.
+ \note IRQn must not be negative.
+ */
+__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ 8000d84: b580 push {r7, lr}
+ 8000d86: b082 sub sp, #8
+ 8000d88: af00 add r7, sp, #0
+ 8000d8a: 0002 movs r2, r0
+ 8000d8c: 1dfb adds r3, r7, #7
+ 8000d8e: 701a strb r2, [r3, #0]
+ if ((int32_t)(IRQn) >= 0)
+ 8000d90: 1dfb adds r3, r7, #7
+ 8000d92: 781b ldrb r3, [r3, #0]
+ 8000d94: 2b7f cmp r3, #127 ; 0x7f
+ 8000d96: d809 bhi.n 8000dac <__NVIC_EnableIRQ+0x28>
+ {
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
+ 8000d98: 1dfb adds r3, r7, #7
+ 8000d9a: 781b ldrb r3, [r3, #0]
+ 8000d9c: 001a movs r2, r3
+ 8000d9e: 231f movs r3, #31
+ 8000da0: 401a ands r2, r3
+ 8000da2: 4b04 ldr r3, [pc, #16] ; (8000db4 <__NVIC_EnableIRQ+0x30>)
+ 8000da4: 2101 movs r1, #1
+ 8000da6: 4091 lsls r1, r2
+ 8000da8: 000a movs r2, r1
+ 8000daa: 601a str r2, [r3, #0]
+ }
+}
+ 8000dac: 46c0 nop ; (mov r8, r8)
+ 8000dae: 46bd mov sp, r7
+ 8000db0: b002 add sp, #8
+ 8000db2: bd80 pop {r7, pc}
+ 8000db4: e000e100 .word 0xe000e100
+
+08000db8 <__NVIC_SetPriority>:
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ \note The priority cannot be set for every processor exception.
+ */
+__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ 8000db8: b590 push {r4, r7, lr}
+ 8000dba: b083 sub sp, #12
+ 8000dbc: af00 add r7, sp, #0
+ 8000dbe: 0002 movs r2, r0
+ 8000dc0: 6039 str r1, [r7, #0]
+ 8000dc2: 1dfb adds r3, r7, #7
+ 8000dc4: 701a strb r2, [r3, #0]
+ if ((int32_t)(IRQn) >= 0)
+ 8000dc6: 1dfb adds r3, r7, #7
+ 8000dc8: 781b ldrb r3, [r3, #0]
+ 8000dca: 2b7f cmp r3, #127 ; 0x7f
+ 8000dcc: d828 bhi.n 8000e20 <__NVIC_SetPriority+0x68>
+ {
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ 8000dce: 4a2f ldr r2, [pc, #188] ; (8000e8c <__NVIC_SetPriority+0xd4>)
+ 8000dd0: 1dfb adds r3, r7, #7
+ 8000dd2: 781b ldrb r3, [r3, #0]
+ 8000dd4: b25b sxtb r3, r3
+ 8000dd6: 089b lsrs r3, r3, #2
+ 8000dd8: 33c0 adds r3, #192 ; 0xc0
+ 8000dda: 009b lsls r3, r3, #2
+ 8000ddc: 589b ldr r3, [r3, r2]
+ 8000dde: 1dfa adds r2, r7, #7
+ 8000de0: 7812 ldrb r2, [r2, #0]
+ 8000de2: 0011 movs r1, r2
+ 8000de4: 2203 movs r2, #3
+ 8000de6: 400a ands r2, r1
+ 8000de8: 00d2 lsls r2, r2, #3
+ 8000dea: 21ff movs r1, #255 ; 0xff
+ 8000dec: 4091 lsls r1, r2
+ 8000dee: 000a movs r2, r1
+ 8000df0: 43d2 mvns r2, r2
+ 8000df2: 401a ands r2, r3
+ 8000df4: 0011 movs r1, r2
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ 8000df6: 683b ldr r3, [r7, #0]
+ 8000df8: 019b lsls r3, r3, #6
+ 8000dfa: 22ff movs r2, #255 ; 0xff
+ 8000dfc: 401a ands r2, r3
+ 8000dfe: 1dfb adds r3, r7, #7
+ 8000e00: 781b ldrb r3, [r3, #0]
+ 8000e02: 0018 movs r0, r3
+ 8000e04: 2303 movs r3, #3
+ 8000e06: 4003 ands r3, r0
+ 8000e08: 00db lsls r3, r3, #3
+ 8000e0a: 409a lsls r2, r3
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ 8000e0c: 481f ldr r0, [pc, #124] ; (8000e8c <__NVIC_SetPriority+0xd4>)
+ 8000e0e: 1dfb adds r3, r7, #7
+ 8000e10: 781b ldrb r3, [r3, #0]
+ 8000e12: b25b sxtb r3, r3
+ 8000e14: 089b lsrs r3, r3, #2
+ 8000e16: 430a orrs r2, r1
+ 8000e18: 33c0 adds r3, #192 ; 0xc0
+ 8000e1a: 009b lsls r3, r3, #2
+ 8000e1c: 501a str r2, [r3, r0]
+ else
+ {
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+}
+ 8000e1e: e031 b.n 8000e84 <__NVIC_SetPriority+0xcc>
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ 8000e20: 4a1b ldr r2, [pc, #108] ; (8000e90 <__NVIC_SetPriority+0xd8>)
+ 8000e22: 1dfb adds r3, r7, #7
+ 8000e24: 781b ldrb r3, [r3, #0]
+ 8000e26: 0019 movs r1, r3
+ 8000e28: 230f movs r3, #15
+ 8000e2a: 400b ands r3, r1
+ 8000e2c: 3b08 subs r3, #8
+ 8000e2e: 089b lsrs r3, r3, #2
+ 8000e30: 3306 adds r3, #6
+ 8000e32: 009b lsls r3, r3, #2
+ 8000e34: 18d3 adds r3, r2, r3
+ 8000e36: 3304 adds r3, #4
+ 8000e38: 681b ldr r3, [r3, #0]
+ 8000e3a: 1dfa adds r2, r7, #7
+ 8000e3c: 7812 ldrb r2, [r2, #0]
+ 8000e3e: 0011 movs r1, r2
+ 8000e40: 2203 movs r2, #3
+ 8000e42: 400a ands r2, r1
+ 8000e44: 00d2 lsls r2, r2, #3
+ 8000e46: 21ff movs r1, #255 ; 0xff
+ 8000e48: 4091 lsls r1, r2
+ 8000e4a: 000a movs r2, r1
+ 8000e4c: 43d2 mvns r2, r2
+ 8000e4e: 401a ands r2, r3
+ 8000e50: 0011 movs r1, r2
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ 8000e52: 683b ldr r3, [r7, #0]
+ 8000e54: 019b lsls r3, r3, #6
+ 8000e56: 22ff movs r2, #255 ; 0xff
+ 8000e58: 401a ands r2, r3
+ 8000e5a: 1dfb adds r3, r7, #7
+ 8000e5c: 781b ldrb r3, [r3, #0]
+ 8000e5e: 0018 movs r0, r3
+ 8000e60: 2303 movs r3, #3
+ 8000e62: 4003 ands r3, r0
+ 8000e64: 00db lsls r3, r3, #3
+ 8000e66: 409a lsls r2, r3
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ 8000e68: 4809 ldr r0, [pc, #36] ; (8000e90 <__NVIC_SetPriority+0xd8>)
+ 8000e6a: 1dfb adds r3, r7, #7
+ 8000e6c: 781b ldrb r3, [r3, #0]
+ 8000e6e: 001c movs r4, r3
+ 8000e70: 230f movs r3, #15
+ 8000e72: 4023 ands r3, r4
+ 8000e74: 3b08 subs r3, #8
+ 8000e76: 089b lsrs r3, r3, #2
+ 8000e78: 430a orrs r2, r1
+ 8000e7a: 3306 adds r3, #6
+ 8000e7c: 009b lsls r3, r3, #2
+ 8000e7e: 18c3 adds r3, r0, r3
+ 8000e80: 3304 adds r3, #4
+ 8000e82: 601a str r2, [r3, #0]
+}
+ 8000e84: 46c0 nop ; (mov r8, r8)
+ 8000e86: 46bd mov sp, r7
+ 8000e88: b003 add sp, #12
+ 8000e8a: bd90 pop {r4, r7, pc}
+ 8000e8c: e000e100 .word 0xe000e100
+ 8000e90: e000ed00 .word 0xe000ed00
+
+08000e94 <__NVIC_SystemReset>:
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
+{
+ 8000e94: b580 push {r7, lr}
+ 8000e96: af00 add r7, sp, #0
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+__STATIC_FORCEINLINE void __DSB(void)
+{
+ __ASM volatile ("dsb 0xF":::"memory");
+ 8000e98: f3bf 8f4f dsb sy
+}
+ 8000e9c: 46c0 nop ; (mov r8, r8)
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ 8000e9e: 4b04 ldr r3, [pc, #16] ; (8000eb0 <__NVIC_SystemReset+0x1c>)
+ 8000ea0: 4a04 ldr r2, [pc, #16] ; (8000eb4 <__NVIC_SystemReset+0x20>)
+ 8000ea2: 60da str r2, [r3, #12]
+ __ASM volatile ("dsb 0xF":::"memory");
+ 8000ea4: f3bf 8f4f dsb sy
+}
+ 8000ea8: 46c0 nop ; (mov r8, r8)
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+
+ for(;;) /* wait until reset */
+ {
+ __NOP();
+ 8000eaa: 46c0 nop ; (mov r8, r8)
+ 8000eac: e7fd b.n 8000eaa <__NVIC_SystemReset+0x16>
+ 8000eae: 46c0 nop ; (mov r8, r8)
+ 8000eb0: e000ed00 .word 0xe000ed00
+ 8000eb4: 05fa0004 .word 0x05fa0004
+
+08000eb8 :
+{
+ 8000eb8: b580 push {r7, lr}
+ 8000eba: b082 sub sp, #8
+ 8000ebc: af00 add r7, sp, #0
+ 8000ebe: 6078 str r0, [r7, #4]
+ SET_BIT(I2Cx->CR1, I2C_CR1_PE);
+ 8000ec0: 687b ldr r3, [r7, #4]
+ 8000ec2: 681b ldr r3, [r3, #0]
+ 8000ec4: 2201 movs r2, #1
+ 8000ec6: 431a orrs r2, r3
+ 8000ec8: 687b ldr r3, [r7, #4]
+ 8000eca: 601a str r2, [r3, #0]
+}
+ 8000ecc: 46c0 nop ; (mov r8, r8)
+ 8000ece: 46bd mov sp, r7
+ 8000ed0: b002 add sp, #8
+ 8000ed2: bd80 pop {r7, pc}
+
+08000ed4 :
+{
+ 8000ed4: b580 push {r7, lr}
+ 8000ed6: b082 sub sp, #8
+ 8000ed8: af00 add r7, sp, #0
+ 8000eda: 6078 str r0, [r7, #4]
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH);
+ 8000edc: 687b ldr r3, [r7, #4]
+ 8000ede: 681b ldr r3, [r3, #0]
+ 8000ee0: 4a03 ldr r2, [pc, #12] ; (8000ef0 )
+ 8000ee2: 401a ands r2, r3
+ 8000ee4: 687b ldr r3, [r7, #4]
+ 8000ee6: 601a str r2, [r3, #0]
+}
+ 8000ee8: 46c0 nop ; (mov r8, r8)
+ 8000eea: 46bd mov sp, r7
+ 8000eec: b002 add sp, #8
+ 8000eee: bd80 pop {r7, pc}
+ 8000ef0: fffdffff .word 0xfffdffff
+
+08000ef4 :
+{
+ 8000ef4: b580 push {r7, lr}
+ 8000ef6: b082 sub sp, #8
+ 8000ef8: af00 add r7, sp, #0
+ 8000efa: 6078 str r0, [r7, #4]
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_GCEN);
+ 8000efc: 687b ldr r3, [r7, #4]
+ 8000efe: 681b ldr r3, [r3, #0]
+ 8000f00: 4a03 ldr r2, [pc, #12] ; (8000f10 )
+ 8000f02: 401a ands r2, r3
+ 8000f04: 687b ldr r3, [r7, #4]
+ 8000f06: 601a str r2, [r3, #0]
+}
+ 8000f08: 46c0 nop ; (mov r8, r8)
+ 8000f0a: 46bd mov sp, r7
+ 8000f0c: b002 add sp, #8
+ 8000f0e: bd80 pop {r7, pc}
+ 8000f10: fff7ffff .word 0xfff7ffff
+
+08000f14 :
+{
+ 8000f14: b580 push {r7, lr}
+ 8000f16: b084 sub sp, #16
+ 8000f18: af00 add r7, sp, #0
+ 8000f1a: 60f8 str r0, [r7, #12]
+ 8000f1c: 60b9 str r1, [r7, #8]
+ 8000f1e: 607a str r2, [r7, #4]
+ MODIFY_REG(I2Cx->OAR2, I2C_OAR2_OA2 | I2C_OAR2_OA2MSK, OwnAddress2 | OwnAddrMask);
+ 8000f20: 68fb ldr r3, [r7, #12]
+ 8000f22: 68db ldr r3, [r3, #12]
+ 8000f24: 4a05 ldr r2, [pc, #20] ; (8000f3c )
+ 8000f26: 401a ands r2, r3
+ 8000f28: 68b9 ldr r1, [r7, #8]
+ 8000f2a: 687b ldr r3, [r7, #4]
+ 8000f2c: 430b orrs r3, r1
+ 8000f2e: 431a orrs r2, r3
+ 8000f30: 68fb ldr r3, [r7, #12]
+ 8000f32: 60da str r2, [r3, #12]
+}
+ 8000f34: 46c0 nop ; (mov r8, r8)
+ 8000f36: 46bd mov sp, r7
+ 8000f38: b004 add sp, #16
+ 8000f3a: bd80 pop {r7, pc}
+ 8000f3c: fffff801 .word 0xfffff801
+
+08000f40 :
+{
+ 8000f40: b580 push {r7, lr}
+ 8000f42: b082 sub sp, #8
+ 8000f44: af00 add r7, sp, #0
+ 8000f46: 6078 str r0, [r7, #4]
+ CLEAR_BIT(I2Cx->OAR2, I2C_OAR2_OA2EN);
+ 8000f48: 687b ldr r3, [r7, #4]
+ 8000f4a: 68db ldr r3, [r3, #12]
+ 8000f4c: 4a03 ldr r2, [pc, #12] ; (8000f5c )
+ 8000f4e: 401a ands r2, r3
+ 8000f50: 687b ldr r3, [r7, #4]
+ 8000f52: 60da str r2, [r3, #12]
+}
+ 8000f54: 46c0 nop ; (mov r8, r8)
+ 8000f56: 46bd mov sp, r7
+ 8000f58: b002 add sp, #8
+ 8000f5a: bd80 pop {r7, pc}
+ 8000f5c: ffff7fff .word 0xffff7fff
+
+08000f60 :
+{
+ 8000f60: b580 push {r7, lr}
+ 8000f62: b082 sub sp, #8
+ 8000f64: af00 add r7, sp, #0
+ 8000f66: 6078 str r0, [r7, #4]
+ SET_BIT(I2Cx->CR2, I2C_CR2_AUTOEND);
+ 8000f68: 687b ldr r3, [r7, #4]
+ 8000f6a: 685b ldr r3, [r3, #4]
+ 8000f6c: 2280 movs r2, #128 ; 0x80
+ 8000f6e: 0492 lsls r2, r2, #18
+ 8000f70: 431a orrs r2, r3
+ 8000f72: 687b ldr r3, [r7, #4]
+ 8000f74: 605a str r2, [r3, #4]
+}
+ 8000f76: 46c0 nop ; (mov r8, r8)
+ 8000f78: 46bd mov sp, r7
+ 8000f7a: b002 add sp, #8
+ 8000f7c: bd80 pop {r7, pc}
+ ...
+
+08000f80 :
+ * @rmtoll KR KEY LL_IWDG_Enable
+ * @param IWDGx IWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_Enable(IWDG_TypeDef *IWDGx)
+{
+ 8000f80: b580 push {r7, lr}
+ 8000f82: b082 sub sp, #8
+ 8000f84: af00 add r7, sp, #0
+ 8000f86: 6078 str r0, [r7, #4]
+ WRITE_REG(IWDGx->KR, LL_IWDG_KEY_ENABLE);
+ 8000f88: 687b ldr r3, [r7, #4]
+ 8000f8a: 4a03 ldr r2, [pc, #12] ; (8000f98 )
+ 8000f8c: 601a str r2, [r3, #0]
+}
+ 8000f8e: 46c0 nop ; (mov r8, r8)
+ 8000f90: 46bd mov sp, r7
+ 8000f92: b002 add sp, #8
+ 8000f94: bd80 pop {r7, pc}
+ 8000f96: 46c0 nop ; (mov r8, r8)
+ 8000f98: 0000cccc .word 0x0000cccc
+
+08000f9c :
+ * @rmtoll KR KEY LL_IWDG_ReloadCounter
+ * @param IWDGx IWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_ReloadCounter(IWDG_TypeDef *IWDGx)
+{
+ 8000f9c: b580 push {r7, lr}
+ 8000f9e: b082 sub sp, #8
+ 8000fa0: af00 add r7, sp, #0
+ 8000fa2: 6078 str r0, [r7, #4]
+ WRITE_REG(IWDGx->KR, LL_IWDG_KEY_RELOAD);
+ 8000fa4: 687b ldr r3, [r7, #4]
+ 8000fa6: 4a03 ldr r2, [pc, #12] ; (8000fb4 )
+ 8000fa8: 601a str r2, [r3, #0]
+}
+ 8000faa: 46c0 nop ; (mov r8, r8)
+ 8000fac: 46bd mov sp, r7
+ 8000fae: b002 add sp, #8
+ 8000fb0: bd80 pop {r7, pc}
+ 8000fb2: 46c0 nop ; (mov r8, r8)
+ 8000fb4: 0000aaaa .word 0x0000aaaa
+
+08000fb8 :
+ * @rmtoll KR KEY LL_IWDG_EnableWriteAccess
+ * @param IWDGx IWDG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_IWDG_EnableWriteAccess(IWDG_TypeDef *IWDGx)
+{
+ 8000fb8: b580 push {r7, lr}
+ 8000fba: b082 sub sp, #8
+ 8000fbc: af00 add r7, sp, #0
+ 8000fbe: 6078 str r0, [r7, #4]
+ WRITE_REG(IWDGx->KR, LL_IWDG_KEY_WR_ACCESS_ENABLE);
+ 8000fc0: 687b ldr r3, [r7, #4]
+ 8000fc2: 4a03 ldr r2, [pc, #12] ; (8000fd0 )
+ 8000fc4: 601a str r2, [r3, #0]
+}
+ 8000fc6: 46c0 nop ; (mov r8, r8)
+ 8000fc8: 46bd mov sp, r7
+ 8000fca: b002 add sp, #8
+ 8000fcc: bd80 pop {r7, pc}
+ 8000fce: 46c0 nop ; (mov r8, r8)
+ 8000fd0: 00005555 .word 0x00005555
+
+08000fd4