mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
222 lines
7.4 KiB
C
222 lines
7.4 KiB
C
/*
|
|
RGB BackLight Service based on
|
|
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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <furi.h>
|
|
#include <furi_hal.h>
|
|
#include <storage/storage.h>
|
|
#include "rgb_backlight.h"
|
|
|
|
#define COLOR_COUNT (sizeof(colors) / sizeof(RGBBacklightColor))
|
|
|
|
#define TAG "RGB_BACKLIGHT_SRV"
|
|
|
|
static const RGBBacklightColor colors[] = {
|
|
{"Orange", 255, 60, 0},
|
|
{"Yellow", 255, 144, 0},
|
|
{"Spring", 167, 255, 0},
|
|
{"Lime", 0, 255, 0},
|
|
{"Aqua", 0, 255, 127},
|
|
{"Cyan", 0, 210, 210},
|
|
{"Azure", 0, 127, 255},
|
|
{"Blue", 0, 0, 255},
|
|
{"Purple", 127, 0, 255},
|
|
{"Magenta", 210, 0, 210},
|
|
{"Pink", 255, 0, 127},
|
|
{"Red", 255, 0, 0},
|
|
{"White", 254, 210, 200},
|
|
{"Custom", 0, 0, 0},
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
// use RECORD for acces to rgb service instance and update current colors by static
|
|
void rgb_backlight_set_static_color(uint8_t index) {
|
|
RGBBacklightApp* app = furi_record_open(RECORD_RGB_BACKLIGHT);
|
|
|
|
//if user select "custom" value then set current colors by custom values
|
|
if(index == 13) {
|
|
app->current_red = app->settings->custom_red;
|
|
app->current_green = app->settings->custom_green;
|
|
app->current_blue = app->settings->custom_blue;
|
|
} else {
|
|
app->current_red = colors[index].red;
|
|
app->current_green = colors[index].green;
|
|
app->current_blue = colors[index].blue;
|
|
}
|
|
furi_record_close(RECORD_RGB_BACKLIGHT);
|
|
}
|
|
|
|
// use RECORD for acces to rgb service instance and update current colors by custom
|
|
void rgb_backlight_set_custom_color(uint8_t red, uint8_t green, uint8_t blue) {
|
|
RGBBacklightApp* app = furi_record_open(RECORD_RGB_BACKLIGHT);
|
|
app->current_red = red;
|
|
app->current_green = green;
|
|
app->current_blue = blue;
|
|
furi_record_close(RECORD_RGB_BACKLIGHT);
|
|
}
|
|
|
|
// use RECORD for acces to rgb service instance, use current_* colors and update backlight
|
|
void rgb_backlight_update(float brightness) {
|
|
RGBBacklightApp* app = furi_record_open(RECORD_RGB_BACKLIGHT);
|
|
|
|
for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
|
|
uint8_t r = app->current_red * (brightness / 1.0f);
|
|
uint8_t g = app->current_green * (brightness / 1.0f);
|
|
uint8_t b = app->current_blue * (brightness / 1.0f);
|
|
SK6805_set_led_color(i, r, g, b);
|
|
}
|
|
SK6805_update();
|
|
furi_record_close(RECORD_RGB_BACKLIGHT);
|
|
}
|
|
|
|
//start furi timer for rainbow
|
|
void rainbow_timer_start(RGBBacklightApp* app) {
|
|
furi_timer_start(app->rainbow_timer, furi_ms_to_ticks(app->settings->rainbow_speed_ms));
|
|
}
|
|
|
|
//stop furi timer for rainbow
|
|
void rainbow_timer_stop(RGBBacklightApp* app) {
|
|
furi_timer_stop(app->rainbow_timer);
|
|
}
|
|
|
|
// if rgb_mod_installed then apply rainbow colors to backlight and start/restart/stop rainbow_timer
|
|
void rainbow_timer_starter(RGBBacklightApp* app) {
|
|
|
|
if((app->settings->rainbow_mode > 0) && (app->settings->rgb_mod_installed)) {
|
|
rainbow_timer_start(app);
|
|
} else {
|
|
if(furi_timer_is_running(app->rainbow_timer)) {
|
|
rainbow_timer_stop(app);
|
|
}
|
|
}
|
|
}
|
|
static void rainbow_timer_callback(void* context) {
|
|
furi_assert(context);
|
|
RGBBacklightApp* app = context;
|
|
|
|
// if rainbow_mode is rainbow do rainbow effect
|
|
if(app->settings->rainbow_mode == 1) {
|
|
switch(app->rainbow_stage) {
|
|
// from red to yellow (255,0,0) - (255,255,0)
|
|
case 1:
|
|
app->current_green += app->settings->rainbow_step;
|
|
if(app->current_green >= 255) {
|
|
app->current_green = 255;
|
|
app->rainbow_stage++;
|
|
}
|
|
break;
|
|
// yellow to green (255,255,0) - (0,255,0)
|
|
case 2:
|
|
app->current_red -= app->settings->rainbow_step;
|
|
if(app->current_red <= 0) {
|
|
app->current_red = 0;
|
|
app->rainbow_stage++;
|
|
}
|
|
break;
|
|
// from green to light blue (0,255,0) - (0,255,255)
|
|
case 3:
|
|
app->current_blue += app->settings->rainbow_step;
|
|
if(app->current_blue >= 255) {
|
|
app->current_blue = 255;
|
|
app->rainbow_stage++;
|
|
}
|
|
break;
|
|
//from light blue to blue (0,255,255) - (0,0,255)
|
|
case 4:
|
|
app->current_green -= app->settings->rainbow_step;
|
|
if(app->current_green <= 0) {
|
|
app->current_green = 0;
|
|
app->rainbow_stage++;
|
|
}
|
|
break;
|
|
//from blue to violet (0,0,255) - (255,0,255)
|
|
case 5:
|
|
app->current_red += app->settings->rainbow_step;
|
|
if(app->current_red >= 255) {
|
|
app->current_red = 255;
|
|
app->rainbow_stage++;
|
|
}
|
|
break;
|
|
//from violet to red (255,0,255) - (255,0,0)
|
|
case 6:
|
|
app->current_blue -= app->settings->rainbow_step;
|
|
if(app->current_blue <= 0) {
|
|
app->current_blue = 0;
|
|
app->rainbow_stage = 1;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
rgb_backlight_update(app->settings->brightness);
|
|
|
|
// if rainbow_mode is ..... do another effect
|
|
// if(app->settings.rainbow_mode == ...) {
|
|
// }
|
|
}
|
|
|
|
int32_t rgb_backlight_srv(void* p) {
|
|
UNUSED(p);
|
|
|
|
// Define object app (full app with settings and running variables),
|
|
// allocate memory and create RECORD for access to app structure from outside
|
|
RGBBacklightApp* app = malloc(sizeof(RGBBacklightApp));
|
|
furi_record_create(RECORD_RGB_BACKLIGHT, app);
|
|
|
|
//define rainbow_timer and they callback
|
|
app->rainbow_timer = furi_timer_alloc(rainbow_timer_callback, FuriTimerTypePeriodic, app);
|
|
|
|
// settings load or create default
|
|
app->settings = malloc(sizeof(RGBBacklightSettings));
|
|
rgb_backlight_settings_load(app->settings);
|
|
|
|
// Init app variables
|
|
app->rainbow_stage = 1;
|
|
|
|
// if rgb mod installed - start rainbow or set static color from settings (default index = 0)
|
|
if(app->settings->rgb_mod_installed) {
|
|
if(app->settings->rainbow_mode > 0) {
|
|
rainbow_timer_starter(app);
|
|
} else {
|
|
rgb_backlight_set_static_color(app->settings->static_color_index);
|
|
rgb_backlight_update(app->settings->brightness);
|
|
}
|
|
// if rgb mod not installed - set default static orange color (index=0)
|
|
} else {
|
|
rgb_backlight_set_static_color(0);
|
|
rgb_backlight_update(app->settings->brightness);
|
|
}
|
|
|
|
while(1) {
|
|
// place for message queue and other future options
|
|
furi_delay_ms(5000);
|
|
FURI_LOG_I(TAG, "Service is running");
|
|
}
|
|
return 0;
|
|
}
|