Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/releases/release-notes-4.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ Drivers and Sensors
* LED

* Added a new set of devicetree based LED APIs, see :c:struct:`led_dt_spec`.
* lp5569: added use of auto-increment functionality.
* lp5569: implemented ``write_channels`` api.
* lp5569: demonstrate ``led_write_channels`` in the sample.

* LED Strip

Expand Down
21 changes: 20 additions & 1 deletion drivers/led/lp5569.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ LOG_MODULE_REGISTER(lp5569, CONFIG_LED_LOG_LEVEL);

#define LP5569_MISC 0x2F
#define LP5569_POWERSAVE_EN BIT(5)
#define LP5569_EN_AUTO_INCR BIT(6)
#define LP5569_CP_MODE_SHIFT 3

/* PWM base Register for controlling the duty-cycle */
Expand Down Expand Up @@ -76,6 +77,23 @@ static inline int lp5569_led_off(const struct device *dev, uint32_t led)
return lp5569_led_set_brightness(dev, led, 0);
}

static int lp5569_write_channels(const struct device *dev, uint32_t start_channel,
uint32_t num_channels, const uint8_t *buf)
{
const struct lp5569_config *config = dev->config;
uint32_t i2c_len = num_channels + 1;
uint8_t i2c_msg[LP5569_NUM_LEDS + 1];

if ((uint64_t)start_channel + num_channels > LP5569_NUM_LEDS) {
return -EINVAL;
}

i2c_msg[0] = LP5569_LED0_PWM + start_channel;
memcpy(&i2c_msg[1], buf, num_channels);

return i2c_write_dt(&config->bus, i2c_msg, i2c_len);
}

static int lp5569_enable(const struct device *dev)
{
const struct lp5569_config *config = dev->config;
Expand Down Expand Up @@ -110,7 +128,7 @@ static int lp5569_enable(const struct device *dev)
}

ret = i2c_reg_write_byte_dt(&config->bus, LP5569_MISC,
LP5569_POWERSAVE_EN |
LP5569_POWERSAVE_EN | LP5569_EN_AUTO_INCR |
(config->cp_mode << LP5569_CP_MODE_SHIFT));
if (ret < 0) {
LOG_ERR("LED reg update failed");
Expand Down Expand Up @@ -169,6 +187,7 @@ static const struct led_driver_api lp5569_led_api = {
.set_brightness = lp5569_led_set_brightness,
.on = lp5569_led_on,
.off = lp5569_led_off,
.write_channels = lp5569_write_channels,
};

#define LP5569_DEFINE(id) \
Expand Down
5 changes: 4 additions & 1 deletion samples/drivers/led/lp5569/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ Overview
********

This sample controls 9 LEDs connected to an LP5569 driver. The sample turns
all LEDs on and switches all LEDs off again within a one second interval.
all LEDs on one by one with a 1 second delay between each. Then it fades all
LEDs until they are off again. Afterwards, it turns them all on at once, waits
a second, and turns them all back off.
This pattern then repeats indefinitely.

Building and Running
********************
Expand Down
24 changes: 23 additions & 1 deletion samples/drivers/led/lp5569/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ LOG_MODULE_REGISTER(app, CONFIG_LED_LOG_LEVEL);
int main(void)
{
const struct device *const led_dev = DEVICE_DT_GET_ANY(ti_lp5569);
uint8_t ch_buf[9] = {0};
int i, ret;

if (!led_dev) {
Expand All @@ -32,7 +33,8 @@ int main(void)

/*
* Display a continuous pattern that turns on 9 LEDs at 1 s one by
* one until it reaches the end and turns off LEDs in reverse order.
* one until it reaches the end and fades off all LEDs.
* Afterwards, all LEDs get blinked once at the same time.
*/

LOG_INF("Testing 9 LEDs ..");
Expand All @@ -59,6 +61,26 @@ int main(void)

k_sleep(DELAY_TIME_BREATHING);
}

k_sleep(DELAY_TIME_ON);

/* Turn on all LEDs at once to demonstrate write_channels */
memset(ch_buf, 255, ARRAY_SIZE(ch_buf));
ret = led_write_channels(led_dev, 0, ARRAY_SIZE(ch_buf), ch_buf);
if (ret) {
return ret;
}

k_sleep(DELAY_TIME_ON);

/* Turn off all LEDs at once to demonstrate write_channels */
memset(ch_buf, 0, ARRAY_SIZE(ch_buf));
ret = led_write_channels(led_dev, 0, ARRAY_SIZE(ch_buf), ch_buf);
if (ret) {
return ret;
}

k_sleep(DELAY_TIME_ON);
}
return 0;
}
Loading