/*
RGB backlight FlipperZero driver
Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "rgb_backlight.h"
#include
#include
#define RGB_BACKLIGHT_SETTINGS_VERSION 5
#define RGB_BACKLIGHT_SETTINGS_PATH CFG_PATH("rgb_backlight.settings")
#define COLOR_COUNT (sizeof(colors) / sizeof(RGBBacklightColor))
#define TAG "RGB Backlight"
static RGBBacklightSettings rgb_settings = {
.version = RGB_BACKLIGHT_SETTINGS_VERSION,
.display_color_index = 0,
.settings_is_loaded = false};
static const RGBBacklightColor colors[] = {
{"Orange", 255, 69, 0},
{"Red", 255, 0, 0},
{"Maroon", 128, 0, 0},
{"Yellow", 255, 255, 0},
{"Olive", 128, 128, 0},
{"Lime", 0, 255, 0},
{"Green", 0, 128, 0},
{"Aqua", 0, 255, 127},
{"Cyan", 0, 210, 210},
{"Azure", 0, 127, 255},
{"Teal", 0, 128, 128},
{"Blue", 0, 0, 255},
{"Navy", 0, 0, 128},
{"Purple", 128, 0, 128},
{"Fuchsia", 255, 0, 255},
{"Pink", 173, 31, 173},
{"Brown", 165, 42, 42},
{"White", 255, 192, 203},
};
uint8_t rgb_backlight_get_color_count(void) {
return COLOR_COUNT;
}
const char* rgb_backlight_get_color_text(uint8_t index) {
return colors[index].name;
}
void rgb_backlight_load_settings(void) {
//Не загружать данные из внутренней памяти при загрузке в режиме DFU
if(!furi_hal_is_normal_boot()) {
rgb_settings.settings_is_loaded = true;
return;
}
RGBBacklightSettings settings;
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
const size_t settings_size = sizeof(RGBBacklightSettings);
FURI_LOG_I(TAG, "loading settings from \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH);
bool fs_result =
storage_file_open(file, RGB_BACKLIGHT_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
if(fs_result) {
uint16_t bytes_count = storage_file_read(file, &settings, settings_size);
if(bytes_count != settings_size) {
fs_result = false;
}
}
if(fs_result) {
FURI_LOG_I(TAG, "load success");
if(settings.version != RGB_BACKLIGHT_SETTINGS_VERSION) {
FURI_LOG_E(
TAG,
"version(%d != %d) mismatch",
settings.version,
RGB_BACKLIGHT_SETTINGS_VERSION);
} else {
memcpy(&rgb_settings, &settings, settings_size);
}
} else {
FURI_LOG_E(TAG, "load failed, %s", storage_file_get_error_desc(file));
}
storage_file_close(file);
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
rgb_settings.settings_is_loaded = true;
}
void rgb_backlight_save_settings(void) {
RGBBacklightSettings settings;
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
const size_t settings_size = sizeof(RGBBacklightSettings);
FURI_LOG_I(TAG, "saving settings to \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH);
memcpy(&settings, &rgb_settings, settings_size);
bool fs_result =
storage_file_open(file, RGB_BACKLIGHT_SETTINGS_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS);
if(fs_result) {
uint16_t bytes_count = storage_file_write(file, &settings, settings_size);
if(bytes_count != settings_size) {
fs_result = false;
}
}
if(fs_result) {
FURI_LOG_I(TAG, "save success");
} else {
FURI_LOG_E(TAG, "save failed, %s", storage_file_get_error_desc(file));
}
storage_file_close(file);
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
}
RGBBacklightSettings* rgb_backlight_get_settings(void) {
if(!rgb_settings.settings_is_loaded) {
rgb_backlight_load_settings();
}
return &rgb_settings;
}
void rgb_backlight_set_color(uint8_t color_index) {
if(color_index > (rgb_backlight_get_color_count() - 1)) color_index = 0;
rgb_settings.display_color_index = color_index;
}
void rgb_backlight_update(uint8_t brightness) {
if(!rgb_settings.settings_is_loaded) {
rgb_backlight_load_settings();
}
static uint8_t last_color_index = 255;
static uint8_t last_brightness = 123;
if(last_brightness == brightness && last_color_index == rgb_settings.display_color_index)
return;
last_brightness = brightness;
last_color_index = rgb_settings.display_color_index;
for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
uint8_t r = colors[rgb_settings.display_color_index].red * (brightness / 255.0f);
uint8_t g = colors[rgb_settings.display_color_index].green * (brightness / 255.0f);
uint8_t b = colors[rgb_settings.display_color_index].blue * (brightness / 255.0f);
SK6805_set_led_color(i, r, g, b);
}
SK6805_update();
}