diff --git a/fw/Core/Inc/led.h b/fw/Core/Inc/led.h
new file mode 100644
index 0000000..7031759
--- /dev/null
+++ b/fw/Core/Inc/led.h
@@ -0,0 +1,52 @@
+/*
+ * led.h
+ *
+ * Created on: Jun 6, 2021
+ * Author: user
+ */
+
+#ifndef INC_LED_H_
+#define INC_LED_H_
+
+#include "stdint.h"
+#include "stm32l0xx_hal.h"
+
+/*
+ * Context struct
+ */
+
+typedef struct {
+ GPIO_TypeDef *red_led_port;
+ int red_led_pin;
+ GPIO_TypeDef *green_led_port;
+ int green_led_pin;
+ GPIO_TypeDef *blue_led_port;
+ int blue_led_pin;
+
+} led_context_t;
+
+/*
+ * Externally defined variables
+ */
+
+extern int led_pwm_max;
+extern int led_pwm_counter;
+extern int led_red_intensity;
+extern int led_green_intensity;
+extern int led_blue_intensity;
+
+/*
+ * Function prototypes
+ */
+
+void led_test();
+void led_set_color(float red, float green, float blue);
+// led_off(): turn off all LEDs
+void led_off();
+// led_pwm_handler(): handles switching LEDs on/off according to desired intensity;
+// should be regularly called in timer routine, preferably in SysTick_Handler()
+void led_pwm_handler();
+void led_init(led_context_t *context, int pwm_freq, int pwm_handler_freq);
+void led_test(int r, int g, int b);
+
+#endif /* INC_LED_H_ */
diff --git a/fw/Core/Inc/main.h b/fw/Core/Inc/main.h
index 85dd1dc..f4efcd0 100644
--- a/fw/Core/Inc/main.h
+++ b/fw/Core/Inc/main.h
@@ -32,7 +32,7 @@ extern "C" {
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
-
+#include "led.h"
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
diff --git a/fw/Core/Src/led.c b/fw/Core/Src/led.c
new file mode 100644
index 0000000..96a35d0
--- /dev/null
+++ b/fw/Core/Src/led.c
@@ -0,0 +1,121 @@
+/*
+ * led.c
+ *
+ * Created on: Jun 6, 2021
+ * Author: user
+ */
+
+#include "led.h"
+
+/*
+ * Global variables
+ */
+
+int led_pwm_max;
+int led_pwm_counter;
+int led_red_intensity;
+int led_green_intensity;
+int led_blue_intensity;
+int led_red_state;
+int led_green_state;
+int led_blue_state;
+led_context_t *led_context;
+
+/*
+ * Functions
+ */
+
+/*
+ * led_set_color():
+ * Set LED color
+ * Arguments:
+ * float red: red color intensity, possible values 0.0 ... 1.0
+ * float green: green color intensity, possible values 0.0 ... 1.0
+ * float blue: blue color intensity, possible values 0.0 ... 1.0
+ */
+void led_set_color(float red, float green, float blue)
+{
+ led_red_intensity = red * led_pwm_max;
+ led_green_intensity = green * led_pwm_max;
+ led_blue_intensity = blue * led_pwm_max;
+}
+
+/*
+ * led_off():
+ * Set LED intensity to 0 for each color
+ */
+void led_off()
+{
+ led_red_intensity = 0;
+ led_green_intensity = 0;
+ led_blue_intensity = 0;
+}
+
+/*
+ * led_pwm_handler():
+ * handles switching LEDs on/off according to desired intensity;
+ * should be regularly called in timer routine, preferably in SysTick_Handler()
+ */
+void led_pwm_handler()
+{
+ int new_red_state, new_green_state, new_blue_state;
+
+ new_red_state = led_pwm_counter >= led_red_intensity ? 1 : 0;
+ new_green_state = led_pwm_counter >= led_green_intensity ? 1 : 0;
+ new_blue_state = led_pwm_counter >= led_blue_intensity ? 1 : 0;
+ // SysTick() is called at 1 kHz frequency, we don't want to call HAL_GPIO_WritePin() every time
+ if (led_red_state != new_red_state) {
+ HAL_GPIO_WritePin(led_context->red_led_port, led_context->red_led_pin, new_red_state);
+ led_red_state = new_red_state;
+ }
+ if (led_green_state != new_green_state) {
+ HAL_GPIO_WritePin(led_context->green_led_port, led_context->green_led_pin, new_green_state);
+ led_green_state = new_green_state;
+ }
+ if (led_blue_state != new_blue_state) {
+ HAL_GPIO_WritePin(led_context->blue_led_port, led_context->blue_led_pin, new_blue_state);
+ led_blue_state = new_blue_state;
+ }
+ if (++led_pwm_counter > led_pwm_max) {
+ led_pwm_counter = 0;
+ }
+}
+
+/*
+ * led_init():
+ * Saves context and calculates max pwm value. Note that is PWM frequency is low (< 25 Hz),
+ * flickering might be visible. If pwm_handler_freq is low (less than several kHz),
+ * resolution of PWM will be limited
+ * Arguments:
+ * led_context_t *context:
+ * Pointer to LED context struct, which contains port and pin for each LED
+ * int pwm_freq:
+ * Desired frequency of PWM in Hz (e.g. 25 Hz)
+ * int pwm_handler_freq:
+ * Frequency of led_pwm_handler() calls. Eequal to timer frequency if timer callback is used,
+ * e.g. if led_pwm_handler() is called within SysTick_Handler(), then frequency is
+ * HAL_TICK_FREQ_1KHZ
+ */
+void led_init(led_context_t *context, int pwm_freq, int pwm_handler_freq)
+{
+ // save context
+ led_context = context;
+ // Initial values
+ led_red_intensity = 0;
+ led_red_state = 1; // state is inverted (LEDs are sinking current into MCU)
+ led_green_intensity = 0;
+ led_green_state = 1;
+ led_blue_intensity = 0;
+ led_blue_state = 1;
+ // calculate PWM counter overflow value (max value)
+ // e.g. for 1 kHz handler freq and 25 Hz PWM freq, we only have
+ // resolution of 40 steps for pwm
+ led_pwm_max = pwm_handler_freq / pwm_freq;
+}
+
+void led_test(int r, int g, int b)
+{
+ HAL_GPIO_WritePin(led_context->red_led_port, led_context->red_led_pin, r);
+ HAL_GPIO_WritePin(led_context->green_led_port, led_context->green_led_pin, g);
+ HAL_GPIO_WritePin(led_context->blue_led_port, led_context->blue_led_pin, b);
+}
diff --git a/fw/Core/Src/main.c b/fw/Core/Src/main.c
index 8112496..656fd92 100644
--- a/fw/Core/Src/main.c
+++ b/fw/Core/Src/main.c
@@ -93,27 +93,38 @@ int main(void)
MX_I2C1_Init();
MX_LPUART1_UART_Init();
/* USER CODE BEGIN 2 */
+ /* Create LED context */
+ led_context_t led_context;
+ led_context.red_led_port = LED_R_GPIO_Port;
+ led_context.red_led_pin = LED_R_Pin;
+ led_context.green_led_port = LED_G_GPIO_Port;
+ led_context.green_led_pin = LED_G_Pin;
+ led_context.blue_led_port = LED_B_GPIO_Port;
+ led_context.blue_led_pin = LED_B_Pin;
+ led_init(&led_context, 25, 1000);
/* Turn off all LEDs */
- HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, 1);
- HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, 1);
- HAL_GPIO_WritePin(LED_B_GPIO_Port, LED_B_Pin, 1);
+ led_off();
+ led_set_color(0.1, 0.0, 0.0);
+// led_test(0,0,0);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
+ int counter = 0;
+ float R = 0.0, G = 0.0, B = 0.0;
while (1)
{
- HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin);
- HAL_Delay(500);
- HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin);
- HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);
- HAL_Delay(500);
- HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);
- HAL_GPIO_TogglePin(LED_B_GPIO_Port, LED_B_Pin);
- HAL_Delay(500);
- HAL_GPIO_TogglePin(LED_B_GPIO_Port, LED_B_Pin);
-
-
+ led_pwm_handler();
+ if (counter % 1000 == 0) {
+ R += 0.05;
+ G += 0.01;
+ B += 0.02;
+ if (R > 1.0) R = 0;
+ if (G > 1.0) G = 0;
+ if (B > 1.0) B = 0;
+ led_set_color(R, G, B);
+ }
+ counter++;
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
diff --git a/fw/Core/Src/stm32l0xx_it.c b/fw/Core/Src/stm32l0xx_it.c
index bf098ed..33758c5 100644
--- a/fw/Core/Src/stm32l0xx_it.c
+++ b/fw/Core/Src/stm32l0xx_it.c
@@ -23,6 +23,7 @@
#include "stm32l0xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
+#include "led.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -130,7 +131,7 @@ void SysTick_Handler(void)
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
-
+// led_pwm_handler();
/* USER CODE END SysTick_IRQn 1 */
}
diff --git a/fw/iaq_wired_sensor Debug.launch b/fw/iaq_wired_sensor Debug.launch
index e86809a..c6a4875 100644
--- a/fw/iaq_wired_sensor Debug.launch
+++ b/fw/iaq_wired_sensor Debug.launch
@@ -68,5 +68,6 @@
+