Skip to content

Commit

Permalink
Add ability to set led color
Browse files Browse the repository at this point in the history
  • Loading branch information
bpbradley committed Jan 28, 2022
1 parent 7b7744d commit 29ae41e
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ CONFIG_JSON_LIBRARY=y
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FCB=y
CONFIG_PWM=y
85 changes: 85 additions & 0 deletions app/src/alerts.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,27 @@
#include <alerts.h>
#include <logging/log.h>
#include <zephyr.h>
#include <device.h>
#include <drivers/pwm.h>

LOG_MODULE_REGISTER(alerts, CONFIG_PYRRHA_LOG_LEVEL);

#define OVER_TEMPERATURE(temp) (temp > CONFIG_TEMPERATURE_ALERT_THRESHOLD_CELCIUS)
#define OVER_CO(co) (co > CONFIG_CO_ALERT_THRESHOLD_PPM)
#define OVER_NO2(no2) (no2 > CONFIG_NO2_ALERT_THRESHOLD_PPM)

/*
* 50hz is flicker fusion threshold. Modulated light will be perceived
* as steady by our eyes when blinking rate is at least 50.
*/
#define PERIOD_USEC (USEC_PER_SEC / 50U)

#define RED_LED_NODE DT_ALIAS(red_pwm_led)
#define GREEN_LED_NODE DT_ALIAS(green_pwm_led)
#define BLUE_LED_NODE DT_ALIAS(blue_pwm_led)

#define COLOR_TO_PULSE(color, period) (color == UINT8_MAX ? (period) : (color * (period) >> 8))

/**
* @brief union which allows easy set/conversion to hex or rgb directly
*
Expand All @@ -31,9 +47,75 @@ typedef union Color{
};
}color_t;

/**
* @brief Configuration table for pwm led
*
*/
struct pwm_cfg{
const struct device * pwm;
const uint8_t pin;
const uint8_t flags;
const uint32_t period;
};

/**
* @brief Container for all pwm leds associated with the rgb led
*
*/
struct rgb_led_device{
const struct pwm_cfg red;
const struct pwm_cfg green;
const struct pwm_cfg blue;
};

K_MUTEX_DEFINE(mtx_alert);
static color_t g_alert_override = {0};

const struct rgb_led_device g_led = {
.red = {
.pwm = DEVICE_DT_GET(DT_PWMS_CTLR(RED_LED_NODE)),
.pin = DT_PWMS_CHANNEL(RED_LED_NODE),
.flags = DT_PWMS_FLAGS(RED_LED_NODE),
.period = PERIOD_USEC
},
.green = {
.pwm = DEVICE_DT_GET(DT_PWMS_CTLR(GREEN_LED_NODE)),
.pin = DT_PWMS_CHANNEL(GREEN_LED_NODE),
.flags = DT_PWMS_FLAGS(GREEN_LED_NODE),
.period = PERIOD_USEC
},
.blue = {
.pwm = DEVICE_DT_GET(DT_PWMS_CTLR(BLUE_LED_NODE)),
.pin = DT_PWMS_CHANNEL(BLUE_LED_NODE),
.flags = DT_PWMS_FLAGS(BLUE_LED_NODE),
.period = PERIOD_USEC
},
};

/**
* @brief Set pwm output directly to the coresponding 8-bit color value
*
* @param cfg : configuration table for pwm device
* @param color : 8-bit color value for the specified pwm
* @retval 0 on success
* @retval -ENODEV if no configuration table
* @retval -EFAULT if pwm set error
*/
static int set_pwm(const struct pwm_cfg * cfg, uint8_t color)
{
if (cfg == NULL){
return -ENODEV;
}
const struct device *dev = cfg->pwm;
uint32_t pulse = COLOR_TO_PULSE(color, cfg->period);
/* Verify pwm_pin_set_usec() */
if (pwm_pin_set_usec(dev, cfg->pin, cfg->period, pulse, cfg->flags)) {
LOG_ERR("Fail to set the period and pulse width");
return -EFAULT;
}
return 0;
}

/**
* @brief Set the alert led to a specific color
*
Expand All @@ -42,6 +124,9 @@ static color_t g_alert_override = {0};
* @retval -errno otherwise
*/
static int set_alert_led(color_t color){
set_pwm(&g_led.red, color.red);
set_pwm(&g_led.green, color.green);
set_pwm(&g_led.blue, color.blue);
return 0;
}

Expand Down

0 comments on commit 29ae41e

Please sign in to comment.