Skip to content

Commit 143f589

Browse files
authored
feat(lp5718): Add LP5817 I2C RGB LED Driver component (#522)
* feat(lp5718): Add LP5718 I2C RGB LED Driver component * fix sa * clean up switch statements * add missing docstring
1 parent 1024f1d commit 143f589

File tree

18 files changed

+868
-1
lines changed

18 files changed

+868
-1
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ jobs:
119119
target: esp32
120120
- path: 'components/logger/example'
121121
target: esp32
122+
- path: 'components/lp5817/example'
123+
target: esp32
122124
- path: 'components/lsm6dso/example'
123125
target: esp32s3
124126
- path: 'components/math/example'

.github/workflows/upload_components.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ jobs:
8080
components/led
8181
components/led_strip
8282
components/logger
83+
components/lp5817
8384
components/lsm6dso
8485
components/math
8586
components/matouch-rotary-display

components/hid_service/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# BLE HID Service Example
1+
# BLE HID Service
22

33
[![Badge](https://components.espressif.com/components/espp/hid_service/badge.svg)](https://components.espressif.com/components/espp/hid_service)
44

components/lp5817/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
idf_component_register(
2+
INCLUDE_DIRS "include"
3+
REQUIRES "base_peripheral"
4+
)

components/lp5817/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# LP5817 - RGB LED Driver (I2C)
2+
3+
[![Badge](https://components.espressif.com/components/espp/lp5817/badge.svg)](https://components.espressif.com/components/espp/lp5817)
4+
5+
This component provides a C++ driver for the TI LP5817 RGB LED driver over I2C,
6+
implemented using `espp::BasePeripheral`.
7+
8+
- 3 LED channels (R, G, B) with 8-bit brightness, controllable via analog
9+
dot-current control or 26 KHz PWM control with linear or exponential dimming
10+
- Programmable fade (ramp) times and step sizes
11+
- Global enable/shutdown
12+
- Open short detection/status
13+
14+
See the [example](./example) for usage.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
cmake_minimum_required(VERSION 3.20)
2+
3+
set(ENV{IDF_COMPONENT_MANAGER} "0")
4+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
5+
6+
set(EXTRA_COMPONENT_DIRS
7+
"../../../components/"
8+
)
9+
10+
set(
11+
COMPONENTS
12+
"main esptool_py task i2c lp5817"
13+
CACHE STRING
14+
"List of components to include"
15+
)
16+
17+
project(lp5817_example)
18+
19+
set(CMAKE_CXX_STANDARD 20)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# LP5817 Example
2+
3+
This example shows how to use the `espp::Lp5817` component to control an RGB LED over I2C.
4+
5+
It is designed for ESP32-S3 but can be adapted by changing the I2C pins.
6+
7+
## How to use example
8+
9+
### Hardware Required
10+
11+
This example can run on and ESP microcontroller with I2C connected to an LP5817
12+
RGB LED driver. You should run `idf.py menuconfig` to set the I2C pins to match
13+
your hardware configuration.
14+
15+
## Configuration
16+
17+
Run `idf.py menuconfig` to set the I2C pins to match your hardware
18+
configuration, or select a predefined board configuration.
19+
20+
## Build and Flash
21+
22+
```
23+
idf.py -p PORT flash monitor
24+
```
25+
26+
(Replace PORT with the name of the serial port to use.)
27+
28+
(To exit the serial monitor, type ``Ctrl-]``.)
29+
30+
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
31+
32+
## Example Output
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
idf_component_register(SRC_DIRS "."
2+
INCLUDE_DIRS ".")
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
menu "Example Configuration"
2+
3+
choice EXAMPLE_HARDWARE
4+
prompt "Hardware"
5+
default EXAMPLE_HARDWARE_QTPYPICO
6+
help
7+
Select the hardware to run this example on.
8+
9+
config EXAMPLE_HARDWARE_QTPYPICO
10+
depends on IDF_TARGET_ESP32
11+
bool "Qt Py PICO"
12+
13+
config EXAMPLE_HARDWARE_QTPYS3
14+
depends on IDF_TARGET_ESP32S3
15+
bool "Qt Py S3"
16+
17+
config EXAMPLE_HARDWARE_CUSTOM
18+
bool "Custom"
19+
endchoice
20+
21+
config EXAMPLE_I2C_SCL_GPIO
22+
int "SCL GPIO Num"
23+
range 0 50
24+
default 19 if EXAMPLE_HARDWARE_QTPYPICO
25+
default 40 if EXAMPLE_HARDWARE_QTPYS3
26+
default 19 if EXAMPLE_HARDWARE_CUSTOM
27+
help
28+
GPIO number for I2C Master clock line.
29+
30+
config EXAMPLE_I2C_SDA_GPIO
31+
int "SDA GPIO Num"
32+
range 0 50
33+
default 22 if EXAMPLE_HARDWARE_QTPYPICO
34+
default 41 if EXAMPLE_HARDWARE_QTPYS3
35+
default 22 if EXAMPLE_HARDWARE_CUSTOM
36+
help
37+
GPIO number for I2C Master data line.
38+
39+
config EXAMPLE_I2C_CLOCK_SPEED_HZ
40+
int "I2C Clock Speed"
41+
range 100 400000
42+
default 400000
43+
help
44+
I2C clock speed in Hz.
45+
46+
endmenu
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include <chrono>
2+
#include <sdkconfig.h>
3+
#include <vector>
4+
5+
#include "i2c.hpp"
6+
#include "lp5817.hpp"
7+
#include "task.hpp"
8+
9+
using namespace std::chrono_literals;
10+
11+
extern "C" void app_main(void) {
12+
espp::Logger logger({.tag = "LP5817 Example", .level = espp::Logger::Verbosity::INFO});
13+
logger.info("Starting");
14+
15+
//! [lp5817 example]
16+
espp::I2c i2c({
17+
.port = I2C_NUM_0,
18+
.sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO,
19+
.scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO,
20+
.sda_pullup_en = GPIO_PULLUP_ENABLE,
21+
.scl_pullup_en = GPIO_PULLUP_ENABLE,
22+
.clk_speed = CONFIG_EXAMPLE_I2C_CLOCK_SPEED_HZ,
23+
.log_level = espp::Logger::Verbosity::INFO,
24+
});
25+
26+
espp::Lp5817 lp({.device_address = espp::Lp5817::DEFAULT_ADDRESS,
27+
.write = std::bind_front(&espp::I2c::write, &i2c),
28+
.write_then_read = std::bind_front(&espp::I2c::write_read, &i2c),
29+
.log_level = espp::Logger::Verbosity::WARN});
30+
std::error_code ec;
31+
if (!lp.initialize(ec)) {
32+
logger.error("Failed to initialize LP5817: {}", ec.message());
33+
return;
34+
}
35+
36+
// configure the max current per channel
37+
static constexpr auto max_current = espp::Lp5817::GlobalMaxCurrent::MA_51;
38+
logger.info("Setting max current to {}", max_current);
39+
if (!lp.set_max_current(max_current, ec)) {
40+
logger.error("Failed to set max current: {}", ec.message());
41+
return;
42+
}
43+
44+
// configure the fade time
45+
static constexpr auto fade_time = espp::Lp5817::FadeTime::TIME_300MS;
46+
logger.info("Setting fade time to {}", fade_time);
47+
if (!lp.set_fade_time(fade_time, ec)) {
48+
logger.error("Failed to set fade time: {}", ec.message());
49+
return;
50+
}
51+
52+
// enable fading and exponential dimming on all channels
53+
using Ch = espp::Lp5817::Channel;
54+
for (auto ch : {Ch::OUT0, Ch::OUT1, Ch::OUT2}) {
55+
if (!lp.set_fade_enable(ch, true, ec)) {
56+
logger.error("Failed to enable fading on channel {}: {}", ch, ec.message());
57+
return;
58+
}
59+
if (!lp.set_exponential_dimming_enable(ch, true, ec)) {
60+
logger.error("Failed to enable exponential dimming on channel {}: {}", ch, ec.message());
61+
return;
62+
}
63+
if (!lp.set_output_enable(ch, true, ec)) {
64+
logger.error("Failed to enable output on channel {}: {}", ch, ec.message());
65+
return;
66+
}
67+
}
68+
69+
// Latch the settings (update)
70+
if (!lp.update(ec)) {
71+
logger.error("Failed to latch settings: {}", ec.message());
72+
return;
73+
}
74+
75+
// Simple breathing RGB demo
76+
auto task_fn = [&](std::mutex &m, std::condition_variable &cv) {
77+
static float brightness = 0.0f;
78+
brightness = (brightness == 0.0f) ? 1.0f : 0.0f;
79+
// for now we'll just to white and fade it in and out
80+
float r = brightness;
81+
float g = brightness;
82+
float b = brightness;
83+
if (!lp.set_rgb_pwm(r, g, b, ec)) {
84+
logger.error("LP5817 set_rgb failed: {}", ec.message().c_str());
85+
return true;
86+
}
87+
{
88+
std::unique_lock<std::mutex> lk(m);
89+
// waiting for 300ms since that is our fade time
90+
cv.wait_for(lk, 300ms);
91+
}
92+
return false;
93+
};
94+
95+
auto task = espp::Task({.callback = task_fn,
96+
.task_config = {.name = "LP5817 Task", .stack_size_bytes = 4 * 1024},
97+
.log_level = espp::Logger::Verbosity::WARN});
98+
task.start();
99+
//! [lp5817 example]
100+
101+
while (true) {
102+
std::this_thread::sleep_for(100ms);
103+
}
104+
}

0 commit comments

Comments
 (0)