DIGILIGHT
control.c
См. документацию.
1 
13 #include <avr/io.h>
14 #include "avr_helper.h"
15 #include <avr/eeprom.h>
16 #include <avr/pgmspace.h>
17 #include <avr/interrupt.h>
18 #include "power_control.h"
19 #include <string.h>
20 #include <stdlib.h>
21 #include "gain_ctrl.h"
22 #include "encoder.h"
23 #include "lcd.h"
24 
25 #include "pixel.h"
26 #include "control.h"
27 #include "global.h"
28 #include "main_effect.h"
29 #include "lcd_show.h"
30 #include "ir_remote.h"
31 #include "menu.h"
32 #include "setup.h"
33 
34 #if defined(_FFT_DEBUG_)
35 #include "fft_debug.h"
36 #endif
37 
44 static void change_val(int8_t *v, uint8_t lim, int8_t d){
45  int16_t tmp = *v;
46  tmp += d;
47  if(tmp >= lim) tmp = lim-1;
48  if(tmp < 0) tmp = 0;
49  *v = tmp;
50 }
51 
57 };
58 
60 typedef struct{
61  uint8_t state : 2;
62  uint8_t div : 1;
63 } btn_state_t;
64 
69 static void change_level(int8_t delta){
70  if(cfg.agc_enabled)
71  return; // при включении АРУ ручное регулирование не работает
72  int8_t lvl = cfg.sensitivity;
73  change_val(&lvl, MAX_LEVEL, delta);
74  cfg.sensitivity = lvl;
75 }
76 
81 uint8_t get_btn_state(void){
82  return ~PIN(BTN_PORT) & (BTN_CHANGE | BTN_MENU);
83 }
84 
85 // признак нахождения внутри системы меню, т.е. индикация "не обычная"
86 static uint8_t in_menu;
87 
94 static uint8_t get_pressed_btn(void){
95  static btn_state_t st = {.state = BTN_WAIT_RELEASED};
96  static uint8_t old;
97  uint8_t btn = get_btn_state();
98 
99  switch(st.state){
100  case BTN_WAIT_RELEASED:
101  if(!btn){
102  st.state = BTN_WAIT_PRESSED;
103  st.div = 1;
104  old = 0;
105  }
106  break;
107  case BTN_WAIT_PRESSED:
108  if(btn){
109  old = btn;
110  st.div = 1;
112  }
113  break;
114  case BTN_WAIT_DEBOUNCE:
115  if(st.div){
116  st.div = 0;
117  break;
118  }
119  if(old == btn){
121  return btn;
122  }
123  }
124  return BTN_NONE;
125 }
126 
133 control_t get_control(void){
134  // сначала кнопки
135  uint8_t btn = get_pressed_btn();
136  if(btn != BTN_NONE){
137  switch(btn){
138  case BTN_CHANGE:
139  return CTRL_ENC_BTN;
140  case BTN_MENU:
141  return CTRL_BTN_SET;
142  }
143  }
144  // затем энкодер
145  int8_t enc = get_encoder();
146  if(enc != 0){
147  if(enc > 0)
148  return btn == BTN_CHANGE ? CTRL_ENC_BTN_UP : CTRL_ENC_UP;
149  else
150  return btn == BTN_CHANGE ? CTRL_ENC_BTN_DN : CTRL_ENC_DN;
151  } else {
152  if(btn == BTN_CHANGE) return CTRL_BTN_SET;
153  }
154 
155  return CTRL_NONE;
156 }
157 
164 static control_cmd_t get_command(control_t ctrl){
165  // сначала обработка физических органов управления
166  switch(ctrl){
167  case CTRL_BTN_PWR:
168  return CMD_POWER;
169  case CTRL_BTN_SET:
170  return CMD_SETUP;
171  case CTRL_ENC_BTN_UP:
172  case CTRL_ENC_BTN:
173  return CMD_EFFECT_PLUS;
174  case CTRL_ENC_BTN_DN:
175  return CMD_EFFECT_MINUS;
176  case CTRL_ENC_UP:
177  return CMD_PRESET_PLUS;
178  case CTRL_ENC_DN:
179  return CMD_PRESET_MINUS;
180  default:
181  break;
182  }
183  // TODO добавить ввод команд из UART
184  // а затем - пульт IR
185  return get_ir_command();
186 }
187 
188 // вспомогательный тип режима индикации
189 typedef enum{
190  EXEC_NO_SHOW, // ничего не обновлять на ЖКИ
191  EXEC_SHOW, // обновить ЖКИ в текущем режиме
192  EXEC_SCALE // показать шкалу чувствительности на ЖКИ
193 } exec_result_t;
194 
200 static exec_result_t exec_cmd(signal_t *s){
201  control_cmd_t cmd = get_command(get_control());
202  exec_result_t result = EXEC_SHOW;
203 
204  switch(cmd){
205  case CMD_POWER:
206  power_off();
207  break;
208  case CMD_VOLUME_PLUS:
209  change_level(1);
210  result = EXEC_SCALE;
211  break;
212  case CMD_VOLUME_MINUS:
213  change_level(-1);
214  result = EXEC_SCALE;
215  break;
216  case CMD_EFFECT_PLUS:
217  change_effect(s, 1);
218  break;
219  case CMD_EFFECT_MINUS:
220  change_effect(s, -1);
221 #if !defined(ONLY_BASE_CMD)
222  case CMD_EFFECT_1 ... CMD_EFFECT_10:
223  // TODO выбор конкретного эффекта
224  //select_fg_effect(s, cmd - CMD_EFFECT_1);
225  //select_bg_effect(s, cmd - CMD_PRESET_1);
226  break;
227 #endif
228  case CMD_PRESET_PLUS:
229  change_preset(s, 1);
230  break;
231  case CMD_PRESET_MINUS:
232  change_preset(s, -1);
233  break;
234 #if !defined(ONLY_BASE_CMD)
235  case CMD_PRESET_1 ... CMD_PRESET_10:
236  // TODO выбор конкретного пресета
237  break;
238 #endif
239  case CMD_SETUP:
240  in_menu = 1;
241  break;
242  default:
243  result = EXEC_NO_SHOW;
244  }
245 
246  return result;
247 }
248 
255  static uint8_t timeout;
256  uint8_t do_show = 0;
257  exec_result_t exer;
258 
259  if(in_menu && cfg.lcd_enabled){
260  // отрабатываем систему меню
261  switch(do_menu()){
262  case MENU_CONTINUE:
263  // продолжение меню
264  return;
265  case MENU_DONE:
266  // выход из меню
267  in_menu = 0;
268  do_show = 1;
269  break;
270  case MENU_DONE_MSG:
271  // выход из меню с сообщением
272  in_menu = 0;
273  timeout = IND_TIMEOUT;
274  break;
275  }
276  }
277 
278  // получаем и обрабатываем команду
279  exer = exec_cmd(s);
280  if(!do_show)
281  do_show = exer != EXEC_NO_SHOW;
282  // если ЖКИ будет обновляться, сбрасываем таймаут автовыключения питания
283  if(do_show) reset_power_timeout();
284 
285 #if !defined(_FFT_DEBUG_)
286  do_show = do_show || effect_auto_changed(s);
287 
288  if(cfg.lcd_enabled){
289  if(do_show || !timeout){
290  if(exer == EXEC_SCALE){
291  show_rpad_str_p(0, VOL_NAME);
292  show_scale(1, cfg.sensitivity);
293  } else {
295  //preset_name = get_preset_name(s);
296  if(do_show) //center_str(1, preset_name);
297  show_info(s);
298  else
299  show_spectrum(s);
300  }
301  timeout = (do_show) ? IND_TIMEOUT : 0;
302  }
303  if(timeout) timeout--;
304  }
305 #else
306  _fft_debug_show(s);
307 #endif
308 }
309 
311 INIT(7){
312  // кнопки
313  DDR(BTN_PORT) &= ~BTN_ANY;
314  PORT(BTN_PORT) |= BTN_ANY;
315 }
316 
button_state
Флаги автомата состояния опроса кнопок
Definition: control.c:53
void do_control(signal_t *s)
Обработка органов управления
Definition: control.c:254
отладочный модуль
#define BTN_PORT
Символ порта, к оторому подключены кнопки управления
Definition: hardware.h:40
#define MAX_LEVEL
фиксированное количество уровней регулирования чувствительности
Definition: global.h:81
INIT(7)
Инициализация модуля
Definition: control.c:311
void center_str(uint8_t row, char *src)
вывод строки по центру дисплея
Definition: lcd_show.c:123
uint8_t state
Состояние автомата
Definition: control.c:61
void show_info(signal_t *s)
Название текущего пресета для текущего эффекта
Definition: main_effect.c:136
control_t get_control(void)
получение управляющей команды
Definition: control.c:133
void show_scale(uint8_t row, uint8_t val)
отображение псевдографической горизонтальной шкалы
Definition: lcd_show.c:201
uint8_t lcd_enabled
ЖКИ присутствует
Definition: global.h:91
Вспомогательные эффекты ЖКИ
Общие описания
uint8_t get_btn_state(void)
получение кода нажатых кнопок
Definition: control.c:81
Вспомогательный тип для автомата состояний опроса кнопок
Definition: control.c:60
uint8_t sensitivity
уровень регулировки чувствительности
Definition: global.h:89
структура параметров звукового сигнала
Definition: global.h:72
Ожидание нажатия кнопки
Definition: control.c:55
сервисный модуль для реализации эффектов Набор вспомогательных функций для базовых манипуляций над це...
uint8_t div
Флаг повторного входа вопрос
Definition: control.c:62
void reset_power_timeout(void)
сброс таймаута автоотключения питания
Definition: power_control.c:49
int8_t change_preset(signal_t *s, int8_t delta)
Смена пресета для текущегоэффекта последовательно
Definition: main_effect.c:94
#define BTN_ANY
Маска всех кнопок
Definition: hardware.h:50
Управление питанием
Ожидание отпускания кнопки
Definition: control.c:54
void show_spectrum(signal_t *s)
отображение "мгновенного спектра" на 2-й строке ЖКИ
Definition: lcd_show.c:162
int8_t get_encoder(void)
Состояние энкодера
Definition: encoder.c:57
uint8_t agc_enabled
АРУ включено
Definition: global.h:90
#define BTN_MENU
Кнопка настроек
Definition: hardware.h:48
Настройки цветомузыки
Обработка энкодера
void power_off(void)
выключение питания
Definition: power_control.c:64
Интерфейс визуальных эффектов
описания модуля дистанционного управления
описания урганов управления
Модуль управления усилением
#define BTN_CHANGE
Кнопка изменения основного эффекта
Definition: hardware.h:46
#define IND_TIMEOUT
таймаут "заморозки" изображения на ЖКИ после исполнения команд в 10мс интервалах
Definition: control.h:22
Подавление дребезга
Definition: control.c:56
void change_effect(signal_t *s, int8_t delta)
Смена эффекта последовательно
Definition: main_effect.c:218
char * get_effect_name(signal_t *s)
Название текущего эффекта
Definition: main_effect.c:112
control_cmd_t get_ir_command(void)
поиск запрограммированной команды
Definition: ir_remote.c:140
uint8_t effect_auto_changed(signal_t *s)
Проверка смены фонового эффекта на основной или наоборот
Definition: main_effect.c:146
void show_rpad_str_p(uint8_t line, const char *src)
вывод строки из flash с очисткой дисплея справа
Definition: lcd_show.c:135