LP5817 RGB LED Driver

The LP5817 RGB LED driver component allows control of 3 LED channels via I2C with 8-bit brightness and programmable fade (ramp) timing.

API Reference

Header File

Classes

class Lp5817 : public espp::BasePeripheral<>

LP5817 RGB LED Driver (I2C)

Implements a minimal functional interface to control RGB brightness and fades following the register map of the LP5817 datasheet.

For more information see the datasheet here: https://www.ti.com/lit/gpn/LP5817

LP5817 Example

  espp::I2c i2c({
      .port = I2C_NUM_0,
      .sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO,
      .scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO,
      .sda_pullup_en = GPIO_PULLUP_ENABLE,
      .scl_pullup_en = GPIO_PULLUP_ENABLE,
      .clk_speed = CONFIG_EXAMPLE_I2C_CLOCK_SPEED_HZ,
      .log_level = espp::Logger::Verbosity::INFO,
  });

  espp::Lp5817 lp({.device_address = espp::Lp5817::DEFAULT_ADDRESS,
                   .write = std::bind_front(&espp::I2c::write, &i2c),
                   .write_then_read = std::bind_front(&espp::I2c::write_read, &i2c),
                   .log_level = espp::Logger::Verbosity::WARN});
  std::error_code ec;
  if (!lp.initialize(ec)) {
    logger.error("Failed to initialize LP5817: {}", ec.message());
    return;
  }

  // configure the max current per channel
  static constexpr auto max_current = espp::Lp5817::GlobalMaxCurrent::MA_51;
  logger.info("Setting max current to {}", max_current);
  if (!lp.set_max_current(max_current, ec)) {
    logger.error("Failed to set max current: {}", ec.message());
    return;
  }

  // configure the fade time
  static constexpr auto fade_time = espp::Lp5817::FadeTime::TIME_300MS;
  logger.info("Setting fade time to {}", fade_time);
  if (!lp.set_fade_time(fade_time, ec)) {
    logger.error("Failed to set fade time: {}", ec.message());
    return;
  }

  // enable fading and exponential dimming on all channels
  using Ch = espp::Lp5817::Channel;
  for (auto ch : {Ch::OUT0, Ch::OUT1, Ch::OUT2}) {
    // enable output on the channel
    if (!lp.set_output_enable(ch, true, ec)) {
      logger.error("Failed to enable output on channel {}: {}", ch, ec.message());
      return;
    }
    // set the dot current (DC) according to how much current you want to drive
    uint8_t dc_value = 0x50; // about 80/255 of max current
    if (!lp.set_dot_current(ch, dc_value, ec)) {
      logger.error("Failed to set dot-current on channel {}: {}", ch, ec.message());
      return;
    }
    // enable fading on the channel
    if (!lp.set_fade_enable(ch, true, ec)) {
      logger.error("Failed to enable fading on channel {}: {}", ch, ec.message());
      return;
    }
    // enable exponential dimming on the channel
    if (!lp.set_exponential_dimming_enable(ch, true, ec)) {
      logger.error("Failed to enable exponential dimming on channel {}: {}", ch, ec.message());
      return;
    }
  }

  // Latch the settings (update)
  if (!lp.update(ec)) {
    logger.error("Failed to latch settings: {}", ec.message());
    return;
  }

  // Simple breathing RGB demo
  auto task_fn = [&](std::mutex &m, std::condition_variable &cv) {
    static float brightness = 0.0f;
    brightness = (brightness == 0.0f) ? 1.0f : 0.0f;
    // for now we'll just to white and fade it in and out
    float r = brightness;
    float g = brightness;
    float b = brightness;
    if (!lp.set_rgb_pwm(r, g, b, ec)) {
      logger.error("LP5817 set_rgb failed: {}", ec.message().c_str());
      return true;
    }
    {
      std::unique_lock<std::mutex> lk(m);
      // waiting for 300ms since that is our fade time
      cv.wait_for(lk, 300ms);
    }
    return false;
  };

  auto task = espp::Task({.callback = task_fn,
                          .task_config = {.name = "LP5817 Task", .stack_size_bytes = 4 * 1024},
                          .log_level = espp::Logger::Verbosity::WARN});
  task.start();

Note

Dot-current (brightness) is controlled on a per-channel basis using the DC registers. It represents the maximum current that can be driven through the LED channel, and is an 8-bit value (0-255). The actual brightness output is then controlled using the PWM registers, which can be changed on-the-fly to adjust brightness.

Note

In this driver, brightness is equivalent to the dot-current (DC) setting in the datasheet, which is an 8-bit value (0-255).

Note

When initializing, you should set the global max current and the dot-current (brightness) for each channel to appropriate values for your application. Then you can use the pwm registers to adjust brightness on-the-fly, which will also take into account any fading that is enabled.

Public Types

enum class Channel : uint8_t

LED channels.

Values:

enumerator OUT0
enumerator OUT1
enumerator OUT2
enum class GlobalMaxCurrent : uint8_t

Global max current settings.

Values:

enumerator MA_25_5

25.5mA

enumerator MA_51

51mA

enum class FadeTime : uint8_t

Fade time codes (datasheet-defined)

Values:

enumerator TIME_0

No fade (instant)

enumerator TIME_50MS

50ms

enumerator TIME_100MS

100ms

enumerator TIME_150MS

150ms

enumerator TIME_200MS

200ms

enumerator TIME_250MS

250ms

enumerator TIME_300MS

300ms

enumerator TIME_350MS

350ms

enumerator TIME_400MS

400ms

enumerator TIME_450MS

450ms

enumerator TIME_500MS

500ms

enumerator TIME_1S

1 second

enumerator TIME_2S

2 seconds

enumerator TIME_4S

4 seconds

enumerator TIME_6S

6 seconds

enumerator TIME_8S

8 seconds

typedef std::function<bool(uint8_t)> probe_fn

Function to probe the peripheral

Param address:

The address to probe

Return:

True if the peripheral is found at the given address

Public Functions

inline explicit Lp5817(const Config &config)

Construct a new Lp5817 object.

Parameters:

config – Configuration structure

inline bool initialize(std::error_code &ec)

Initialize the device.

Parameters:

ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool enable(bool on, std::error_code &ec)

Enable or disable the device.

Parameters:
  • on – True to enable outputs, false to disable.

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool is_enabled(std::error_code &ec)

Check if device is enabled.

Parameters:

ec – Error code set on failure.

Returns:

true if device is enabled, false otherwise.

inline bool set_dot_current(Channel ch, uint8_t value, std::error_code &ec)

Set per-channel 8-bit dot-current (DC).

Parameters:
  • ch – Channel to update.

  • value – Dot-current [0,255].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_dot_current(Channel ch, float value, std::error_code &ec)

Set per-channel dot-current (DC) using a float value.

Note

Value is clamped to [0.0, 1.0] range.

Parameters:
  • ch – Channel to update.

  • value – Dot-current [0.0, 1.0].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_brightness(Channel ch, uint8_t value, std::error_code &ec)

Set per-channel 8-bit brightness (dot-current).

Note

This is an alias for set_dot_current().

Parameters:
  • ch – Channel to update.

  • value – Dot-Current Brightness [0,255].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_brightness(Channel ch, float value, std::error_code &ec)

Set per-channel brightness (dot-current) using a float value.

Note

Value is clamped to [0.0, 1.0] range.

Parameters:
  • ch – Channel to update.

  • value – Dot-Current Brightness [0.0, 1.0].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline uint8_t get_dot_current(Channel ch, std::error_code &ec)

Get the current dot-current (DC) of a channel.

Parameters:
  • ch – Channel to read.

  • ec – Error code set on failure.

Returns:

Dot-current [0,255].

inline uint8_t get_brightness(Channel ch, std::error_code &ec)

Get the brightness (dot-current) of a channel.

Parameters:
  • ch – Channel to read.

  • ec – Error code set on failure.

Returns:

Dot Current Brightness [0,255].

inline bool set_dot_current(const std::array<uint8_t, 3> &data, std::error_code &ec)

Set all three channel dot-current (DC) values.

Parameters:
  • data – Array of three dot-current values [0,255].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_rgb_dot_current(uint8_t r, uint8_t g, uint8_t b, std::error_code &ec)

Set all three channel dot-current (DC) values.

Note

This assumes RGB are mapped to channels 0, 1, 2 respectively.

Parameters:
  • r – Red dot-current [0,255].

  • g – Green dot-current [0,255].

  • b – Blue dot-current [0,255].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_rgb(uint8_t r, uint8_t g, uint8_t b, std::error_code &ec)

Set all three channel brightness (dot-current) values.

Note

This assumes RGB are mapped to channels 0, 1, 2 respectively.

Note

This is an alias for set_rgb_dot_current().

Parameters:
  • r – Red Dot-Current brightness [0,255].

  • g – Green Dot-Current brightness [0,255].

  • b – Blue Dot-Current brightness [0,255].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_rgb(float r, float g, float b, std::error_code &ec)

Set all three channel brightness (dot-current) values using float values.

Note

Values are clamped to [0.0, 1.0] range.

Note

This assumes RGB are mapped to channels 0, 1, 2 respectively.

Note

This is an alias for set_rgb_dot_current().

Parameters:
  • r – Red Dot-Current brightness [0.0, 1.0].

  • g – Green Dot-Current brightness [0.0, 1.0].

  • b – Blue Dot-Current brightness [0.0, 1.0].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_pwm(const std::array<uint8_t, 3> &data, std::error_code &ec)

Set all three channel manual PWM values (manual mode).

Parameters:
  • data – Array of three manual PWM values [0,255].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_rgb_pwm(uint8_t r, uint8_t g, uint8_t b, std::error_code &ec)

Set all three channel manual PWM values (manual mode).

Note

This assumes RGB are mapped to channels 0, 1, 2 respectively.

Note

This is best used when fading is enabled on all channels and there is a non-zero fade time, to avoid visible stepping.

Parameters:
  • r – Red manual PWM value [0,255].

  • g – Green manual PWM value [0,255].

  • b – Blue manual PWM value [0,255].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_rgb_pwm(float r, float g, float b, std::error_code &ec)

Set all three channel manual PWM values using float values (manual mode).

Note

Values are clamped to [0.0, 1.0] range.

Note

This assumes RGB are mapped to channels 0, 1, 2 respectively.

Note

This is best used when fading is enabled on all channels and there is a non-zero fade time configured.

Parameters:
  • r – Red manual PWM value [0.0, 1.0].

  • g – Green manual PWM value [0.0, 1.0].

  • b – Blue manual PWM value [0.0, 1.0].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_manual_pwm(Channel ch, uint8_t value, std::error_code &ec)

Set manual PWM value for a channel (manual mode).

Note

This is best used when fading is enabled on the channel and there is a non-zero fade time configured.

Parameters:
  • ch – Channel to update.

  • value – Manual PWM value [0,255].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool set_manual_pwm(Channel ch, float value, std::error_code &ec)

Set manual PWM value for a channel using a float value (manual mode).

Note

Value is clamped to [0.0, 1.0] range.

Parameters:
  • ch – Channel to update.

  • value – Manual PWM value [0.0, 1.0].

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline uint8_t get_manual_pwm(Channel ch, std::error_code &ec)

Get the current manual PWM value of a channel (manual mode).

Parameters:
  • ch – Channel to read.

  • ec – Error code set on failure.

Returns:

Manual PWM value [0,255].

inline bool set_fade_time(FadeTime time, std::error_code &ec)

Set global fade time (datasheet-defined).

Note

This sets the fade time for all channels.

Note

You must call update() after changing this setting for it to take effect.

Parameters:
  • time – Fade time.

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline FadeTime get_fade_time(std::error_code &ec)

Get the current global fade time setting.

Parameters:

ec – Error code set on failure.

Returns:

Current global fade time setting.

inline bool set_fade_enable(Channel ch, bool enable, std::error_code &ec)

Enable/disable fade engine for a channel.

Note

Fading must be enabled for exponential dimming to have any effect.

Note

You must call update() after changing this setting for it to take effect.

Parameters:
  • ch – Channel to configure.

  • enable – True to enable fading, false to disable.

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool is_fade_enabled(Channel ch, std::error_code &ec)

Is fading enabled for a channel?

Parameters:
  • ch – Channel to check.

  • ec – Error code set on failure.

Returns:

true if fading is enabled, false otherwise.

inline bool set_exponential_dimming_enable(Channel ch, bool enable, std::error_code &ec)

Enable/disable exponential dimming for a channel.

Note

Exponential dimming is only effective if fading is also enabled. See datasheet for details.

Note

You must call update() after changing this setting for it to take effect.

Parameters:
  • ch – Channel to configure.

  • enable – True to enable exponential dimming, false for linear.

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool is_exponential_dimming_enabled(Channel ch, std::error_code &ec)

Is exponential dimming enabled for a channel?

Parameters:
  • ch – Channel to check.

  • ec – Error code set on failure.

Returns:

true if exponential dimming is enabled, false otherwise.

inline bool set_output_enable(Channel ch, bool enable, std::error_code &ec)

Enable/disable output stage for a channel.

Note

You must call update() after changing this setting for it to take effect.

Parameters:
  • ch – Channel to configure.

  • enable – True to enable output, false to disable.

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool is_output_enabled(Channel ch, std::error_code &ec)

Check if output stage is enabled for a channel.

Parameters:
  • ch – Channel to check.

  • ec – Error code set on failure.

Returns:

true if output stage is enabled, false otherwise.

inline bool set_max_current(GlobalMaxCurrent current, std::error_code &ec)

Set global max current.

Note

This sets the max current for all channels.

Note

You must call update() after changing this setting for it to take effect.

Parameters:
  • current – Global max current setting.

  • ec – Error code set on failure.

Returns:

true on success, false on failure.

inline GlobalMaxCurrent get_max_current(std::error_code &ec)

Get the current global max current setting.

Parameters:

ec – Error code set on failure.

Returns:

Current global max current setting.

inline bool update(std::error_code &ec)

Issue update command (latch new settings).

Parameters:

ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool reset(std::error_code &ec)

Issue reset command.

Parameters:

ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool shutdown(std::error_code &ec)

Issue shutdown command.

Parameters:

ec – Error code set on failure.

Returns:

true on success, false on failure.

inline uint8_t read_flags(std::error_code &ec)

Read flag register (POR/TSD).

Note

Bit0 = POR (Power-On Reset), Bit1 = TSD (Thermal Shutdown)

Parameters:

ec – Error code set on failure.

Returns:

Flag register value.

inline bool is_por_flag_set(std::error_code &ec)

Check if POR (Power-On Reset) flag is set.

Parameters:

ec – Error code set on failure.

Returns:

true if POR flag is set, false otherwise.

inline bool is_tsd_flag_set(std::error_code &ec)

Check if TSD (Thermal Shutdown) flag is set.

Parameters:

ec – Error code set on failure.

Returns:

true if TSD flag is set, false otherwise.

inline bool clear_flags(std::error_code &ec)

Clear both POR (Power-On Reset) and TSD (Thermal Shutdown) flags.

Parameters:

ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool clear_por_flag(std::error_code &ec)

Clear POR (Power-On Reset) flag.

Parameters:

ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool clear_tsd_flag(std::error_code &ec)

Clear TSD (Thermal Shutdown) flag.

Parameters:

ec – Error code set on failure.

Returns:

true on success, false on failure.

inline bool probe(std::error_code &ec) const

Probe the peripheral

Note

This function is thread safe

Note

If the probe function is not set, this function will return false and set the error code to operation_not_supported

Note

This function is only available if UseAddress is true

Parameters:

ec – The error code to set if there is an error

Returns:

True if the peripheral is found

inline void set_address(uint8_t address)

Set the address of the peripheral

Note

This function is thread safe

Note

This function is only available if UseAddress is true

Parameters:

address – The address of the peripheral

inline void set_probe(const probe_fn &probe)

Set the probe function

Note

This function is thread safe

Note

This should rarely be used, as the probe function is usually set in the constructor. If you need to change the probe function, consider using the set_config function instead.

Note

This function is only available if UseAddress is true

Parameters:

probe – The probe function

inline void set_write(const write_fn &write)

Set the write function

Note

This function is thread safe

Note

This should rarely be used, as the write function is usually set in the constructor. If you need to change the write function, consider using the set_config function instead.

Parameters:

write – The write function

inline void set_read(const read_fn &read)

Set the read function

Note

This function is thread safe

Note

This should rarely be used, as the read function is usually set in the constructor. If you need to change the read function, consider using the set_config function instead.

Parameters:

read – The read function

inline void set_read_register(const read_register_fn &read_register)

Set the read register function

Note

This function is thread safe

Note

This should rarely be used, as the read register function is usually set in the constructor. If you need to change the read register function, consider using the set_config function instead.

Parameters:

read_register – The read register function

inline void set_write_then_read(const write_then_read_fn &write_then_read)

Set the write then read function

Note

This function is thread safe

Note

This should rarely be used, as the write then read function is usually set in the constructor. If you need to change the write then

Parameters:

write_then_read – The write then read function

inline void set_separate_write_then_read_delay(const std::chrono::milliseconds &delay)

Set the delay between the write and read operations in write_then_read

Note

This function is thread safe

Note

This should rarely be used, as the delay is usually set in the constructor. If you need to change the delay, consider using the set_config function instead.

Note

This delay is only used if the write_then_read function is not set to a custom function and the write and read functions are separate functions.

Parameters:

delay – The delay between the write and read operations in write_then_read

inline void set_config(const Config &config)

Set the configuration for the peripheral

Note

This function is thread safe

Note

The configuration should normally be set in the constructor, but this function can be used to change the configuration after the peripheral has been created - for instance if the peripheral could be found on different communications buses.

Parameters:

config – The configuration for the peripheral

inline void set_config(Config &&config)

Set the configuration for the peripheral

Note

This function is thread safe

Note

The configuration should normally be set in the constructor, but this function can be used to change the configuration after the peripheral has been created - for instance if the peripheral could be found on different communications buses.

Parameters:

config – The configuration for the peripheral

inline const Config &config() const

Get the configuration for the peripheral

Returns:

The configuration for the peripheral

inline uint8_t address() const

Get the address of the peripheral

Returns:

The address of the peripheral

inline const std::string &get_name() const

Get the name of the component

Note

This is the tag of the logger

Returns:

A const reference to the name of the component

inline void set_log_tag(const std::string_view &tag)

Set the tag for the logger

Parameters:

tag – The tag to use for the logger

inline espp::Logger::Verbosity get_log_level() const

Get the log level for the logger

Returns:

The verbosity level of the logger

inline void set_log_level(espp::Logger::Verbosity level)

Set the log level for the logger

Parameters:

level – The verbosity level to use for the logger

inline void set_log_verbosity(espp::Logger::Verbosity level)

Set the log verbosity for the logger

See also

set_log_level

Note

This is a convenience method that calls set_log_level

Parameters:

level – The verbosity level to use for the logger

inline espp::Logger::Verbosity get_log_verbosity() const

Get the log verbosity for the logger

See also

get_log_level

Note

This is a convenience method that calls get_log_level

Returns:

The verbosity level of the logger

inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)

Set the rate limit for the logger

Note

Only calls to the logger that have _rate_limit suffix will be rate limited

Parameters:

rate_limit – The rate limit to use for the logger

struct Config

Configuration structure.

Public Members

uint8_t device_address = DEFAULT_ADDRESS

I2C address of the device.

BasePeripheral::write_fn write

Write function.

BasePeripheral::write_then_read_fn write_then_read

Write-then-read function.

bool auto_init = true

If true, initialize() is called in constructor.

Logger::Verbosity log_level = {Logger::Verbosity::WARN}

Log level.