diff --git a/esphome/components/kp18058/__init__.py b/esphome/components/kp18058/__init__.py index 0b74af757b..fce4181b7b 100644 --- a/esphome/components/kp18058/__init__.py +++ b/esphome/components/kp18058/__init__.py @@ -19,8 +19,8 @@ CONFIG_SCHEMA = cv.Schema( cv.GenerateID(): cv.declare_id(KP18058), cv.Required(CONF_DATA_PIN): pins.gpio_output_pin_schema, cv.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema, - cv.Optional(CONF_CW_CURRENT, default=5): cv.int_range(min=0, max=31), - cv.Optional(CONF_RGB_CURRENT, default=5): cv.int_range(min=0, max=31), + cv.Optional(CONF_CW_CURRENT, default=8): cv.float_range(min=0, max=77.5), + cv.Optional(CONF_RGB_CURRENT, default=5): cv.float_range(min=0, max=48), } ).extend(cv.COMPONENT_SCHEMA) diff --git a/esphome/components/kp18058/kp18058.cpp b/esphome/components/kp18058/kp18058.cpp index f2a201c561..b181f41c41 100644 --- a/esphome/components/kp18058/kp18058.cpp +++ b/esphome/components/kp18058/kp18058.cpp @@ -59,13 +59,13 @@ void KP18058::program_led_driver() { return true; }; - // Create the settings union + // Create the settings struct KP18058_Settings settings{}; settings.address_identification = 1; settings.working_mode = all_channels_zero() ? STANDBY_MODE : RGBCW_MODE; // Set byte address start. valid values are 0 - 13 - // In this message always all bytes are transmited (starting from 0) + // In this message always all bytes are transmitted (starting from 0) settings.start_byte_address = 0x00; // Set Line Compensation Mechanism @@ -78,7 +78,7 @@ void KP18058::program_led_driver() { settings.max_current_out4_5 = static_cast(max_cw_current_ / 2.5) & 0x1F; settings.max_current_out1_3 = static_cast(max_rgb_current_ / 2.5) & 0x1F; - // set dimming method for RGB channels and chop dimming frequency + // Set dimming method for RGB channels and chop dimming frequency settings.chop_dimming_out1_3 = ANALOG_DIMMING; settings.chop_dimming_frequency = CD_FREQUENCY_500HZ; @@ -90,23 +90,24 @@ void KP18058::program_led_driver() { } // Calculate parity bits for each byte - for (auto &byte : settings.bytes) { + uint8_t *settings_bytes = reinterpret_cast(&settings); + for (auto &byte : settings_bytes) { byte |= get_parity_bit(byte); } // Send the I2C message i2c_.start(); - for (int i = 0; i < sizeof(KP18058_Settings); i++) { - // on error try to repeat the byte transmission I2C_MAX_RETRY times + for (size_t i = 0; i < sizeof(KP18058_Settings); i++) { + // On error, try to repeat the byte transmission I2C_MAX_RETRY times bool write_succeeded; for (int attempt = 0; attempt < I2C_MAX_RETRY; attempt++) { - write_succeeded = i2c_.write_byte(settings.bytes[i]); + write_succeeded = i2c_.write_byte(settings_bytes[i]); if (write_succeeded) break; } - // if all tries failed break and stop sending the rest of the frame bytes + // If all tries failed, break and stop sending the rest of the frame bytes if (!write_succeeded) { - ESP_LOGE(TAG, "Failed to write byte %02d (0x%02X) after %d attempts", i, settings.bytes[i], I2C_MAX_RETRY); + ESP_LOGE(TAG, "Failed to write byte %02d (0x%02X) after %d attempts", i, settings_bytes[i], I2C_MAX_RETRY); i2c_ready_ = false; break; } diff --git a/esphome/components/kp18058/kp18058_cfg.h b/esphome/components/kp18058/kp18058_cfg.h index 2535f8007d..0f519255fb 100644 --- a/esphome/components/kp18058/kp18058_cfg.h +++ b/esphome/components/kp18058/kp18058_cfg.h @@ -92,49 +92,43 @@ enum CDFrequency : uint8_t { #pragma pack(push, 1) /** - * @brief Union representing the structure of the I2C message for configuring the KP18058 LED driver settings. + * @brief the structure of the I2C message for configuring the KP18058 LED driver settings. */ -typedef union { - // Access the settings as a structure +struct KP18058_Settings { + // Byte 0 + uint8_t byte0_parity_bit : 1; + uint8_t start_byte_address : 4; + WorkingMode working_mode : 2; + uint8_t address_identification : 1; + + // Byte 1 + uint8_t byte1_parity_bit : 1; + LCSlope line_comp_slope : 2; + LCThreshold line_comp_threshold : 4; + LCMode line_compensation_enable : 1; + + // Byte 2 + uint8_t byte2_parity_bit : 1; + uint8_t max_current_out1_3 : 5; + CDFrequency chop_dimming_frequency : 2; + + // Byte 3 + uint8_t byte3_parity_bit : 1; + uint8_t max_current_out4_5 : 5; + RCFilter rc_filter_enable : 1; + DimmingMode chop_dimming_out1_3 : 1; + + // Channel array for OUT1 to OUT5 grayscale data struct { - // Byte 0 - uint8_t byte0_parity_bit : 1; - uint8_t start_byte_address : 4; - WorkingMode working_mode : 2; - uint8_t address_identification : 1; + uint8_t upper_parity : 1; + uint8_t upper_grayscale : 5; /**< upper 5 bits of the channel value */ + uint8_t upper_reserved : 2; - // Byte 1 - uint8_t byte1_parity_bit : 1; - LCSlope line_comp_slope : 2; - LCThreshold line_comp_threshold : 4; - LCMode line_compensation_enable : 1; - - // Byte 2 - uint8_t byte2_parity_bit : 1; - uint8_t max_current_out1_3 : 5; - CDFrequency chop_dimming_frequency : 2; - - // Byte 3 - uint8_t byte3_parity_bit : 1; - uint8_t max_current_out4_5 : 5; - RCFilter rc_filter_enable : 1; - DimmingMode chop_dimming_out1_3 : 1; - - // Channel array for OUT1 to OUT5 grayscale data - struct { - uint8_t upper_parity : 1; - uint8_t upper_grayscale : 5; /**< upper 5 bits of the channel value */ - uint8_t upper_reserved : 2; - - uint8_t lower_parity : 1; - uint8_t lower_grayscale : 5; /**< lower 5 bits of the channel value */ - uint8_t lower_reserved : 2; - } channels[5]; - }; - - // Access the settings as a byte array - uint8_t bytes[14]; -} KP18058_Settings; + uint8_t lower_parity : 1; + uint8_t lower_grayscale : 5; /**< lower 5 bits of the channel value */ + uint8_t lower_reserved : 2; + } channels[5]; +}; #pragma pack(pop)