1
// fsm-channels.h: Channel mode functions for SpaghettiMonster.
2
// Copyright (C) 2023 Selene ToyKeeper
3
// SPDX-License-Identifier: GPL-3.0-or-later
7
// always enable channel modes, even if there is only one
8
#define USE_CHANNEL_MODES
11
typedef void SetLevelFunc(uint8_t level);
12
typedef SetLevelFunc * SetLevelFuncPtr;
14
typedef bool GradualTickFunc(uint8_t gt);
15
typedef GradualTickFunc * GradualTickFuncPtr;
17
typedef struct Channel {
18
SetLevelFuncPtr set_level;
19
#ifdef USE_SET_LEVEL_GRADUALLY
20
GradualTickFuncPtr gradual_tick;
22
#ifdef USE_CHANNEL_MODE_ARGS
24
//uint8_t arg; // is in the config struct, not here
28
Channel channels[]; // values are defined in the hwdef-*.c
30
// TODO: size-optimize the case with only 1 channel mode?
31
// (the arrays and stuff shouldn't be needed)
34
#define CH_MODE cfg.channel_mode
36
// current multi-channel mode
37
uint8_t channel_mode = DEFAULT_CHANNEL_MODE;
38
#define CH_MODE channel_mode
41
// FIXME: remove this?
42
#if NUM_CHANNEL_MODES > 1
43
#define USE_CHANNEL_MODES
46
#ifdef USE_CUSTOM_CHANNEL_3H_MODES
47
// different 3H behavior per channel?
48
// TODO: move to progmem
49
// TODO: move to Anduril, not FSM
50
StatePtr channel_3H_modes[NUM_CHANNEL_MODES];
53
//#ifdef USE_CHANNEL_MODE_TOGGLES
54
#if NUM_CHANNEL_MODES > 1
55
// user can take unwanted modes out of the rotation
58
#define channel_mode_enabled(n) ((cfg.channel_modes_enabled >> n) & 1)
59
#define channel_mode_enable(n) cfg.channel_modes_enabled |= (1 << n)
60
#define channel_mode_disable(n) cfg.channel_modes_enabled &= ((1 << n) ^ 0xff)
62
uint16_t channel_modes_enabled = CHANNEL_MODES_ENABLED;
63
#define channel_mode_enabled(n) ((channel_modes_enabled >> n) & 1)
64
#define channel_mode_enable(n) channel_modes_enabled |= (1 << n)
65
#define channel_mode_disable(n) channel_modes_enabled &= ((1 << n) ^ 0xff)
69
#ifdef USE_CHANNEL_MODE_ARGS
71
// one byte of extra data per channel mode, like for tint value
72
uint8_t channel_mode_args[NUM_CHANNEL_MODES] = { CHANNEL_MODE_ARGS };
74
// which modes respond to their "arg", and which don't?
75
//const uint8_t channel_has_args = CHANNEL_HAS_ARGS;
76
//#define channel_has_args(n) ((CHANNEL_HAS_ARGS >> n) & 1)
78
#define channel_has_args(n) (channels[n].has_args)
81
void set_channel_mode(uint8_t mode);
83
#ifdef USE_CALC_2CH_BLEND
87
PWM_DATATYPE brightness,
93
typedef struct RGB_t {
98
RGB_t hsv2rgb(uint8_t h, uint8_t s, uint8_t v);
99
#endif // ifdef USE_HSV2RGB
102
#ifdef USE_SET_LEVEL_1CH
104
void set_level_1ch(uint8_t level);
107
#ifdef USE_SET_LEVEL_2CH_STACKED
109
void set_level_2ch_stacked(uint8_t level);
112
#ifdef USE_SET_LEVEL_3CH_STACKED
114
void set_level_3ch_stacked(uint8_t level);
117
#if defined(USE_TINT_RAMPING) && (!defined(TINT_RAMP_TOGGLE_ONLY))
119
void set_level_2ch_blend();
122
#ifdef USE_GRADUAL_TICK_1CH
124
void gradual_tick_1ch();
127
#ifdef USE_GRADUAL_TICK_2CH_STACKED
129
void gradual_tick_2ch_stacked();
132
#ifdef USE_GRADUAL_TICK_3CH_STACKED
134
void gradual_tick_3ch_stacked();