Skip to content

Commit 6fe4072

Browse files
shixinke-orionespressif-bot
authored andcommitted
feat(lightbulb): Add iic driver sm2182e
1 parent 3339788 commit 6fe4072

File tree

12 files changed

+461
-22
lines changed

12 files changed

+461
-22
lines changed

components/led/lightbulb_driver/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# ChangeLog
22

3+
## v1.8.0 - 2025-03-28
4+
5+
### Improve:
6+
7+
- Added new dimming driver SM2182E
8+
- Modify some kconfig names. Please refer to [sdkconfig.rename](./sdkconfig.rename)
9+
310
## v1.7.1 - 2025-03-05
411

512
### Bug Fix:

components/led/lightbulb_driver/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ if(CONFIG_ENABLE_SM2135EH_DRIVER)
2323
list(APPEND incs "drivers/common/iic/")
2424
endif()
2525

26+
if(CONFIG_ENABLE_SM2182E_DRIVER)
27+
list(APPEND srcs "drivers/sm2182e/sm2182e.c")
28+
list(APPEND incs "drivers/sm2182e")
29+
list(APPEND srcs "drivers/common/iic/iic.c")
30+
list(APPEND incs "drivers/common/iic/")
31+
endif()
32+
2633
if(CONFIG_ENABLE_SM2x35EGH_DRIVER)
2734
list(APPEND srcs "drivers/sm2x35egh/sm2x35egh.c")
2835
list(APPEND incs "drivers/sm2x35egh")

components/led/lightbulb_driver/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ menu "LightBulb Driver Config"
2121
help
2222
Enable SM2135eh output.
2323

24+
config ENABLE_SM2182E_DRIVER
25+
bool "Enable sm2182e interface"
26+
default "y"
27+
help
28+
Enable SN2182e output.
29+
2430
config ENABLE_SM2X35EGH_DRIVER
2531
bool "Enable sm2x35egh(sm2235egh sm2335egh) interface"
2632
default "y"

components/led/lightbulb_driver/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The lightbulb component encapsulates several commonly used dimming schemes for l
1313

1414
- ~~SM2135E~~
1515
- SM2135EH
16+
- SM2182E
1617
- SM2X35EGH (SM2235EGH/SM2335EGH)
1718
- BP57x8D (BP5758/BP5758D/BP5768)
1819
- BP1658CJ

components/led/lightbulb_driver/README_CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
- ~~SM2135E~~
1717
- SM2135EH
18+
- SM2182E
1819
- SM2X35EGH (SM2235EGH/SM2335EGH)
1920
- BP57x8D (BP5758/BP5758D/BP5768)
2021
- BP1658CJ
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdio.h>
8+
#include <string.h>
9+
10+
#include <esp_log.h>
11+
12+
#include "sm2182e.h"
13+
#include "iic.h"
14+
15+
static const char *TAG = "driver_sm2182e";
16+
17+
#define INVALID_ADDR 0xFF
18+
#define IIC_BASE_UNIT_HZ 1000
19+
#define SM2182E_MAX_PIN 2
20+
21+
/**
22+
* SM2182E register start address - Byte0
23+
*/
24+
/* B[7:6] */
25+
#define BASE_ADDR 0xC0
26+
27+
/* B[4:3] */
28+
#define BIT_ENABLE_ACTIVE 0x10
29+
#define BIT_DISABLE_OUTPUT 0x00
30+
31+
/* B[2:0] */
32+
#define BIT_CH_FIXED_VALUE 0x03
33+
34+
/**
35+
* SM2135EH register current address - Byte1
36+
*/
37+
// Nothing
38+
39+
/**
40+
* SM2135EH register grayscale address - Byte2-5
41+
*
42+
*
43+
*/
44+
// Nothing
45+
46+
typedef struct {
47+
sm2182e_cw_current_t cw_current;
48+
uint8_t mapping_addr[SM2182E_MAX_PIN];
49+
bool init_done;
50+
} sm2182e_handle_t;
51+
52+
static sm2182e_handle_t *s_sm2182e = NULL;
53+
54+
esp_err_t sm2182e_set_standby_mode(bool enable_standby)
55+
{
56+
DRIVER_CHECK(s_sm2182e, "not init", return ESP_ERR_INVALID_STATE);
57+
58+
uint8_t addr = 0;
59+
uint8_t value[5] = {0};
60+
if (enable_standby) {
61+
addr = BASE_ADDR | BIT_DISABLE_OUTPUT | BIT_CH_FIXED_VALUE;
62+
} else {
63+
addr = BASE_ADDR | BIT_ENABLE_ACTIVE | BIT_CH_FIXED_VALUE;
64+
}
65+
66+
return iic_driver_write(addr, value, sizeof(value));
67+
}
68+
69+
esp_err_t sm2182e_set_shutdown(void)
70+
{
71+
DRIVER_CHECK(s_sm2182e, "not init", return ESP_ERR_INVALID_STATE);
72+
73+
return sm2182e_set_standby_mode(true);
74+
}
75+
76+
esp_err_t sm2182e_regist_channel(sm2182e_channel_t channel, sm2182e_out_pin_t pin)
77+
{
78+
DRIVER_CHECK(s_sm2182e, "not init", return ESP_ERR_INVALID_STATE);
79+
DRIVER_CHECK(channel >= SM2182E_CHANNEL_C && channel < SM2182E_CHANNEL_MAX, "check channel fail", return ESP_ERR_INVALID_ARG);
80+
DRIVER_CHECK(pin < SM2182E_PIN_OUT_MAX, "check out pin fail", return ESP_ERR_INVALID_ARG);
81+
82+
s_sm2182e->mapping_addr[channel - 3] = pin;
83+
return ESP_OK;
84+
}
85+
86+
esp_err_t sm2182e_set_cw_channel(uint16_t value_c, uint16_t value_w)
87+
{
88+
DRIVER_CHECK(s_sm2182e, "not init", return ESP_ERR_INVALID_STATE);
89+
DRIVER_CHECK(s_sm2182e->mapping_addr[SM2182E_CHANNEL_C - 3] != INVALID_ADDR || s_sm2182e->mapping_addr[SM2182E_CHANNEL_W - 3] != INVALID_ADDR, "white channel not regist", return ESP_ERR_INVALID_STATE);
90+
DRIVER_CHECK(value_c <= 1023 && value_w <= 1023, "value out of range", return ESP_ERR_INVALID_ARG);
91+
92+
uint8_t _value[5] = { 0 };
93+
uint8_t addr = BASE_ADDR | BIT_ENABLE_ACTIVE | BIT_CH_FIXED_VALUE;
94+
95+
_value[0] = s_sm2182e->cw_current;
96+
97+
_value[(s_sm2182e->mapping_addr[0]) * 2 + 2] = value_c & 0xFF;
98+
_value[(s_sm2182e->mapping_addr[0]) * 2 + 1] = value_c >> 8;
99+
100+
_value[(s_sm2182e->mapping_addr[1]) * 2 + 2] = value_w & 0xFF;
101+
_value[(s_sm2182e->mapping_addr[1]) * 2 + 1] = value_w >> 8;
102+
103+
ESP_LOGD(TAG, "addr:%x [out1:[%x][%x] out2:[%x][%x]]", addr, _value[1], _value[2], _value[3], _value[4]);
104+
return iic_driver_write(addr, _value, sizeof(_value));
105+
}
106+
107+
sm2182e_cw_current_t sm2182e_cw_current_mapping(int current_mA)
108+
{
109+
DRIVER_CHECK((current_mA >= 5) && (current_mA <= 80), "The current value is incorrect and cannot be mapped.", return SM2182E_CW_CURRENT_MAX);
110+
111+
const uint8_t limits[] = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80};
112+
for (int i = 0; i < sizeof(limits); i++) {
113+
if (current_mA == limits[i]) {
114+
return (sm2182e_cw_current_t)i;
115+
}
116+
}
117+
118+
return SM2182E_CW_CURRENT_MAX;
119+
}
120+
121+
esp_err_t sm2182e_init(driver_sm2182e_t *config, void(*hook_func)(void *))
122+
{
123+
esp_err_t err = ESP_OK;
124+
125+
DRIVER_CHECK(config, "config is null", return ESP_ERR_INVALID_ARG);
126+
DRIVER_CHECK(!s_sm2182e, "already init done", return ESP_ERR_INVALID_ARG);
127+
DRIVER_CHECK(config->cw_current >= SM2182E_CW_CURRENT_5MA && config->cw_current < SM2182E_CW_CURRENT_MAX, "cw channel current param error", return ESP_ERR_INVALID_ARG);
128+
129+
s_sm2182e = calloc(1, sizeof(sm2182e_handle_t));
130+
DRIVER_CHECK(s_sm2182e, "alloc fail", return ESP_ERR_NO_MEM);
131+
memset(s_sm2182e->mapping_addr, INVALID_ADDR, SM2182E_MAX_PIN);
132+
133+
s_sm2182e->cw_current = config->cw_current;
134+
135+
if (config->freq_khz > 400) {
136+
config->freq_khz = 400;
137+
ESP_LOGW(TAG, "The frequency is too high, adjust it to 400khz");
138+
}
139+
140+
err |= iic_driver_init(I2C_NUM_0, config->iic_sda, config->iic_clk, config->freq_khz * IIC_BASE_UNIT_HZ);
141+
DRIVER_CHECK(err == ESP_OK, "i2c master init fail", goto EXIT);
142+
143+
if (config->enable_iic_queue) {
144+
err |= iic_driver_send_task_create();
145+
DRIVER_CHECK(err == ESP_OK, "task create fail", goto EXIT);
146+
}
147+
148+
return err;
149+
EXIT:
150+
151+
if (s_sm2182e) {
152+
free(s_sm2182e);
153+
s_sm2182e = NULL;
154+
}
155+
return err;
156+
}
157+
158+
esp_err_t sm2182e_deinit(void)
159+
{
160+
DRIVER_CHECK(s_sm2182e, "not init", return ESP_ERR_INVALID_STATE);
161+
162+
sm2182e_set_shutdown();
163+
iic_driver_deinit();
164+
iic_driver_task_destroy();
165+
free(s_sm2182e);
166+
s_sm2182e = NULL;
167+
return ESP_OK;
168+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
#include "driver/gpio.h"
9+
10+
/**
11+
* @brief Current options for WY channels
12+
*
13+
*/
14+
typedef enum {
15+
SM2182E_CW_CURRENT_5MA,
16+
SM2182E_CW_CURRENT_10MA,
17+
SM2182E_CW_CURRENT_15MA,
18+
SM2182E_CW_CURRENT_20MA,
19+
SM2182E_CW_CURRENT_25MA,
20+
SM2182E_CW_CURRENT_30MA,
21+
SM2182E_CW_CURRENT_35MA,
22+
SM2182E_CW_CURRENT_40MA,
23+
SM2182E_CW_CURRENT_45MA,
24+
SM2182E_CW_CURRENT_50MA,
25+
SM2182E_CW_CURRENT_55MA,
26+
SM2182E_CW_CURRENT_60MA,
27+
SM2182E_CW_CURRENT_65MA,
28+
SM2182E_CW_CURRENT_70MA,
29+
SM2182E_CW_CURRENT_75MA,
30+
SM2182E_CW_CURRENT_80MA,
31+
SM2182E_CW_CURRENT_MAX,
32+
} sm2182e_cw_current_t;
33+
34+
/**
35+
* @brief Output configuration
36+
*
37+
*/
38+
typedef struct {
39+
sm2182e_cw_current_t cw_current;
40+
gpio_num_t iic_clk;
41+
gpio_num_t iic_sda;
42+
bool enable_iic_queue;
43+
uint16_t freq_khz;
44+
} driver_sm2182e_t;
45+
46+
/**
47+
* @brief SM2182E channel abstract definition
48+
*
49+
*/
50+
typedef enum {
51+
SM2182E_CHANNEL_C = 3,
52+
SM2182E_CHANNEL_W,
53+
SM2182E_CHANNEL_MAX,
54+
} sm2182e_channel_t;
55+
56+
/**
57+
* @brief SM2182E output pin definition
58+
*
59+
*/
60+
typedef enum {
61+
SM2182E_PIN_OUT1 = 0,
62+
SM2182E_PIN_OUT2,
63+
SM2182E_PIN_OUT_MAX,
64+
} sm2182e_out_pin_t;
65+
66+
/**
67+
* @brief Initialize sm2135e output
68+
*
69+
* @param config Driver configuration
70+
* @param hook_func Hook function, which will be called inside the driver. e.g. to notify that config have been changed internally
71+
* @return esp_err_t
72+
*/
73+
esp_err_t sm2182e_init(driver_sm2182e_t *config, void(*hook_func)(void *));
74+
75+
/**
76+
* @brief Register the sm2182e channel
77+
* @note Needs to correspond to the real hardware
78+
*
79+
* @param channel Abstract channel
80+
* @param pin Chip pin
81+
* @return esp_err_t
82+
*/
83+
esp_err_t sm2182e_regist_channel(sm2182e_channel_t channel, sm2182e_out_pin_t pin);
84+
85+
/**
86+
* @brief Set only wy channel output
87+
*
88+
* @param value_w Output cold value
89+
* @param value_y Output warm value
90+
* @return esp_err_t
91+
*/
92+
esp_err_t sm2182e_set_cw_channel(uint16_t value_c, uint16_t value_w);
93+
94+
/**
95+
* @brief Stop all channel output
96+
*
97+
* @return esp_err_t
98+
*/
99+
esp_err_t sm2182e_set_shutdown(void);
100+
101+
/**
102+
* @brief Set standby mode
103+
*
104+
* @param enable_standby If set to true will enter standby mode
105+
* @return esp_err_t
106+
*/
107+
esp_err_t sm2182e_set_standby_mode(bool enable_standby);
108+
109+
/**
110+
* @brief Convert the cw channel current value into the enumeration value required by the driver
111+
*
112+
* @param current_mA Only the following current values can be used: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80
113+
* @return sm2182e_cw_current_t
114+
*/
115+
sm2182e_cw_current_t sm2182e_cw_current_mapping(int current_mA);
116+
117+
/**
118+
* @brief Deinitialize sm2182e and release resources
119+
*
120+
* @return esp_err_t
121+
*/
122+
esp_err_t sm2182e_deinit(void);

components/led/lightbulb_driver/idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: "1.7.1"
1+
version: "1.8.0"
22
description: Provide multiple dimming driver solutions to easily build lightbulb applications
33
url: https://github.com/espressif/esp-iot-solution/tree/master/components/led/lightbulb_driver
44
dependencies:

components/led/lightbulb_driver/include/lightbulb.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ extern "C" {
2222
#include "pwm.h"
2323
#endif
2424

25+
#ifdef CONFIG_ENABLE_SM2182E_DRIVER
26+
#include "sm2182e.h"
27+
#endif
28+
2529
#ifdef CONFIG_ENABLE_SM2135EH_DRIVER
2630
#include "sm2135eh.h"
2731
#endif
@@ -56,15 +60,16 @@ typedef enum {
5660
DRIVER_ESP_PWM = 1,
5761

5862
/* IIC */
59-
DRIVER_SM2135E, // This version is no longer supported. Please checkout to v0.5.2
63+
DRIVER_SM2135E = 10, // This version is no longer supported. Please checkout to v0.5.2
6064
DRIVER_SM2135EH,
61-
DRIVER_SM2x35EGH, // Available for SM2235EGH SM2335EGH
62-
DRIVER_BP57x8D, // Available for BP5758 BP5758D BP5768D
63-
DRIVER_BP1658CJ,
64-
DRIVER_KP18058,
65+
DRIVER_SM2182E,
66+
DRIVER_SM2x35EGH, // Available for SM2235EGH SM2335EGH
67+
DRIVER_BP1658CJ = 20,
68+
DRIVER_BP57x8D, // Available for BP5758 BP5758D BP5768D
69+
DRIVER_KP18058 = 40,
6570

6671
/* Single Bus */
67-
DRIVER_WS2812,
72+
DRIVER_WS2812 = 100,
6873

6974
DRIVER_SELECT_MAX,
7075
} lightbulb_driver_t;
@@ -305,6 +310,9 @@ typedef struct {
305310
#ifdef CONFIG_ENABLE_SM2135EH_DRIVER
306311
driver_sm2135eh_t sm2135eh;
307312
#endif
313+
#ifdef CONFIG_ENABLE_SM2182E_DRIVER
314+
driver_sm2182e_t sm2182e;
315+
#endif
308316
#ifdef CONFIG_ENABLE_BP57x8D_DRIVER
309317
driver_bp57x8d_t bp57x8d;
310318
#endif

0 commit comments

Comments
 (0)