|
|
|
@@ -47,6 +47,7 @@ static struct {
|
|
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
|
bool settings_loaded;
|
|
|
|
|
FuriMutex* mutex;
|
|
|
|
|
bool enabled;
|
|
|
|
|
bool last_rainbow;
|
|
|
|
|
uint8_t last_brightness;
|
|
|
|
@@ -55,6 +56,7 @@ static struct {
|
|
|
|
|
HsvColor rainbow_hsv;
|
|
|
|
|
} rgb_state = {
|
|
|
|
|
.settings_loaded = false,
|
|
|
|
|
.mutex = NULL,
|
|
|
|
|
.enabled = false,
|
|
|
|
|
.last_rainbow = true,
|
|
|
|
|
.last_brightness = 0,
|
|
|
|
@@ -68,37 +70,13 @@ static struct {
|
|
|
|
|
.rainbow_hsv = {0, 255, 255},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void rainbow_timer(void* ctx) {
|
|
|
|
|
UNUSED(ctx);
|
|
|
|
|
rgb_backlight_update(rgb_state.last_brightness, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_reconfigure(bool enabled) {
|
|
|
|
|
if(enabled && !rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
void rgb_backlight_load_settings(bool enabled) {
|
|
|
|
|
if(rgb_state.settings_loaded) return;
|
|
|
|
|
rgb_state.enabled = enabled;
|
|
|
|
|
rgb_state.mutex = furi_mutex_alloc(FuriMutexTypeRecursive);
|
|
|
|
|
|
|
|
|
|
if(rgb_state.enabled && rgb_settings.rainbow_mode != RGBBacklightRainbowModeOff) {
|
|
|
|
|
if(rgb_state.rainbow_timer == NULL) {
|
|
|
|
|
rgb_state.rainbow_timer = furi_timer_alloc(rainbow_timer, FuriTimerTypePeriodic, NULL);
|
|
|
|
|
} else {
|
|
|
|
|
furi_timer_stop(rgb_state.rainbow_timer);
|
|
|
|
|
}
|
|
|
|
|
furi_timer_start(rgb_state.rainbow_timer, rgb_settings.rainbow_interval);
|
|
|
|
|
} else if(rgb_state.rainbow_timer != NULL) {
|
|
|
|
|
furi_timer_stop(rgb_state.rainbow_timer);
|
|
|
|
|
furi_timer_free(rgb_state.rainbow_timer);
|
|
|
|
|
rgb_state.rainbow_timer = NULL;
|
|
|
|
|
}
|
|
|
|
|
rgb_state.rainbow_hsv.s = rgb_settings.rainbow_saturation;
|
|
|
|
|
|
|
|
|
|
rgb_backlight_update(rgb_state.last_brightness, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_load_settings(void) {
|
|
|
|
|
// Do not load data from internal memory when booting in DFU mode
|
|
|
|
|
if(!furi_hal_is_normal_boot() || rgb_state.settings_loaded) {
|
|
|
|
|
if(!furi_hal_is_normal_boot()) {
|
|
|
|
|
rgb_state.settings_loaded = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@@ -115,102 +93,168 @@ void rgb_backlight_load_settings(void) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_save_settings(void) {
|
|
|
|
|
if(!rgb_state.settings_loaded) return;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
saved_struct_save(
|
|
|
|
|
RGB_BACKLIGHT_SETTINGS_PATH,
|
|
|
|
|
&rgb_settings,
|
|
|
|
|
sizeof(rgb_settings),
|
|
|
|
|
RGB_BACKLIGHT_SETTINGS_MAGIC,
|
|
|
|
|
RGB_BACKLIGHT_SETTINGS_VERSION);
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_set_color(uint8_t index, RgbColor color) {
|
|
|
|
|
if(index >= COUNT_OF(rgb_settings.colors)) return;
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!rgb_state.settings_loaded) return;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
rgb_settings.colors[index] = color;
|
|
|
|
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RgbColor rgb_backlight_get_color(uint8_t index) {
|
|
|
|
|
if(index >= COUNT_OF(rgb_settings.colors)) return (RgbColor){0, 0, 0};
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
return rgb_settings.colors[index];
|
|
|
|
|
|
|
|
|
|
if(!rgb_state.settings_loaded) return (RgbColor){0, 0, 0};
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
RgbColor color = rgb_settings.colors[index];
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_set_rainbow_mode(RGBBacklightRainbowMode rainbow_mode) {
|
|
|
|
|
if(rainbow_mode >= RGBBacklightRainbowModeCount) return;
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!rgb_state.settings_loaded) return;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
rgb_settings.rainbow_mode = rainbow_mode;
|
|
|
|
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RGBBacklightRainbowMode rgb_backlight_get_rainbow_mode() {
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
return rgb_settings.rainbow_mode;
|
|
|
|
|
if(!rgb_state.settings_loaded) return 0;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
RGBBacklightRainbowMode rainbow_mode = rgb_settings.rainbow_mode;
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return rainbow_mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_set_rainbow_speed(uint8_t rainbow_speed) {
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
if(!rgb_state.settings_loaded) return;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
rgb_settings.rainbow_speed = rainbow_speed;
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t rgb_backlight_get_rainbow_speed() {
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
return rgb_settings.rainbow_speed;
|
|
|
|
|
if(!rgb_state.settings_loaded) return 0;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
uint8_t rainbow_speed = rgb_settings.rainbow_speed;
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return rainbow_speed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_set_rainbow_interval(uint32_t rainbow_interval) {
|
|
|
|
|
if(rainbow_interval < 100) return;
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!rgb_state.settings_loaded) return;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
rgb_settings.rainbow_interval = rainbow_interval;
|
|
|
|
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t rgb_backlight_get_rainbow_interval() {
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
return rgb_settings.rainbow_interval;
|
|
|
|
|
if(!rgb_state.settings_loaded) return 0;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
uint32_t rainbow_interval = rgb_settings.rainbow_interval;
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return rainbow_interval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_set_rainbow_saturation(uint8_t rainbow_saturation) {
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
}
|
|
|
|
|
if(!rgb_state.settings_loaded) return;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
rgb_settings.rainbow_saturation = rainbow_saturation;
|
|
|
|
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t rgb_backlight_get_rainbow_saturation() {
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
if(!rgb_state.settings_loaded) return 0;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
uint8_t rainbow_saturation = rgb_settings.rainbow_saturation;
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return rainbow_saturation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rainbow_timer(void* ctx) {
|
|
|
|
|
UNUSED(ctx);
|
|
|
|
|
rgb_backlight_update(rgb_state.last_brightness, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_reconfigure(bool enabled) {
|
|
|
|
|
if(!rgb_state.settings_loaded) return;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
rgb_state.enabled = enabled;
|
|
|
|
|
if(rgb_state.enabled && rgb_settings.rainbow_mode != RGBBacklightRainbowModeOff) {
|
|
|
|
|
if(rgb_state.rainbow_timer == NULL) {
|
|
|
|
|
rgb_state.rainbow_timer = furi_timer_alloc(rainbow_timer, FuriTimerTypePeriodic, NULL);
|
|
|
|
|
} else {
|
|
|
|
|
furi_timer_stop(rgb_state.rainbow_timer);
|
|
|
|
|
}
|
|
|
|
|
furi_timer_start(rgb_state.rainbow_timer, rgb_settings.rainbow_interval);
|
|
|
|
|
} else if(rgb_state.rainbow_timer != NULL) {
|
|
|
|
|
furi_timer_stop(rgb_state.rainbow_timer);
|
|
|
|
|
furi_timer_free(rgb_state.rainbow_timer);
|
|
|
|
|
rgb_state.rainbow_timer = NULL;
|
|
|
|
|
}
|
|
|
|
|
return rgb_settings.rainbow_saturation;
|
|
|
|
|
rgb_state.rainbow_hsv.s = rgb_settings.rainbow_saturation;
|
|
|
|
|
rgb_backlight_update(rgb_state.last_brightness, false);
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rgb_backlight_update(uint8_t brightness, bool tick) {
|
|
|
|
|
if(!rgb_state.enabled) return;
|
|
|
|
|
if(!rgb_state.settings_loaded) {
|
|
|
|
|
rgb_backlight_load_settings();
|
|
|
|
|
if(!rgb_state.settings_loaded) return;
|
|
|
|
|
furi_check(furi_mutex_acquire(rgb_state.mutex, FuriWaitForever) == FuriStatusOk);
|
|
|
|
|
|
|
|
|
|
if(!rgb_state.enabled) {
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(rgb_settings.rainbow_mode) {
|
|
|
|
|
case RGBBacklightRainbowModeOff: {
|
|
|
|
|
if(!rgb_state.last_rainbow && rgb_state.last_brightness == brightness &&
|
|
|
|
|
memcmp(rgb_state.last_colors, rgb_settings.colors, sizeof(rgb_settings.colors)) == 0) {
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
rgb_state.last_rainbow = false;
|
|
|
|
@@ -235,6 +279,7 @@ void rgb_backlight_update(uint8_t brightness, bool tick) {
|
|
|
|
|
rgb_state.rainbow_hsv.h += rgb_settings.rainbow_speed;
|
|
|
|
|
} else {
|
|
|
|
|
if(rgb_state.last_brightness == brightness && rgb_state.last_rainbow) {
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
rgb_state.rainbow_hsv.v = brightness;
|
|
|
|
@@ -254,9 +299,12 @@ void rgb_backlight_update(uint8_t brightness, bool tick) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rgb_state.last_brightness = brightness;
|
|
|
|
|
SK6805_update();
|
|
|
|
|
|
|
|
|
|
furi_check(furi_mutex_release(rgb_state.mutex) == FuriStatusOk);
|
|
|
|
|
}
|
|
|
|
|