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
// TODO: implement custom 3H handlers
18
typedef void ChannelArgFunc();
19
typedef ChannelArgFunc * ChannelArgFuncPtr;
21
typedef struct Channel {
22
SetLevelFuncPtr set_level;
23
#ifdef USE_SET_LEVEL_GRADUALLY
24
GradualTickFuncPtr gradual_tick;
26
#ifdef USE_CUSTOM_3H_HANDLERS
27
// TODO: implement custom 3H handlers
28
ChannelArgFuncPtr ramp_channel_arg;
30
#ifdef USE_CHANNEL_MODE_ARGS
32
//uint8_t arg; // is in the config struct, not here
36
Channel channels[]; // values are defined in the hwdef-*.c
38
// TODO: size-optimize the case with only 1 channel mode?
39
// (the arrays and stuff shouldn't be needed)
41
#if NUM_CHANNEL_MODES > 1
42
#define USE_CHANNEL_MODES
43
// current multi-channel mode
44
uint8_t channel_mode = DEFAULT_CHANNEL_MODE;
46
#define channel_mode 0
49
#ifdef USE_CUSTOM_CHANNEL_3H_MODES
50
// different 3H behavior per channel?
51
// TODO: move to progmem
52
// TODO: move to Anduril, not FSM
53
StatePtr channel_3H_modes[NUM_CHANNEL_MODES];
56
//#ifdef USE_CHANNEL_MODE_TOGGLES
57
#if NUM_CHANNEL_MODES > 1
58
// user can take unwanted modes out of the rotation
61
#define channel_mode_enabled(n) ((cfg.channel_modes_enabled >> n) & 1)
62
#define channel_mode_enable(n) cfg.channel_modes_enabled |= (1 << n)
63
#define channel_mode_disable(n) cfg.channel_modes_enabled &= ((1 << n) ^ 0xff)
65
uint16_t channel_modes_enabled = CHANNEL_MODES_ENABLED;
66
#define channel_mode_enabled(n) ((channel_modes_enabled >> n) & 1)
67
#define channel_mode_enable(n) channel_modes_enabled |= (1 << n)
68
#define channel_mode_disable(n) channel_modes_enabled &= ((1 << n) ^ 0xff)
72
#ifdef USE_CHANNEL_MODE_ARGS
74
// one byte of extra data per channel mode, like for tint value
75
uint8_t channel_mode_args[NUM_CHANNEL_MODES] = { CHANNEL_MODE_ARGS };
77
// which modes respond to their "arg", and which don't?
78
//const uint8_t channel_has_args = CHANNEL_HAS_ARGS;
79
//#define channel_has_args(n) ((CHANNEL_HAS_ARGS >> n) & 1)
81
#define channel_has_args(n) (channels[n].has_args)
84
#if NUM_CHANNEL_MODES > 1
85
void set_channel_mode(uint8_t mode);
88
#ifdef USE_CALC_2CH_BLEND
92
PWM_DATATYPE brightness,
98
typedef struct RGB_t {
103
RGB_t hsv2rgb(uint8_t h, uint8_t s, uint16_t v);
104
#endif // ifdef USE_HSV2RGB
107
#ifdef USE_SET_LEVEL_1CH
109
void set_level_1ch(uint8_t level);
112
#ifdef USE_SET_LEVEL_2CH_STACKED
114
void set_level_2ch_stacked(uint8_t level);
117
#ifdef USE_SET_LEVEL_3CH_STACKED
119
void set_level_3ch_stacked(uint8_t level);
122
#if defined(USE_TINT_RAMPING) && (!defined(TINT_RAMP_TOGGLE_ONLY))
124
void set_level_2ch_blend();
127
#ifdef USE_GRADUAL_TICK_1CH
129
void gradual_tick_1ch();
132
#ifdef USE_GRADUAL_TICK_2CH_STACKED
134
void gradual_tick_2ch_stacked();
137
#ifdef USE_GRADUAL_TICK_3CH_STACKED
139
void gradual_tick_3ch_stacked();