summaryrefslogtreecommitdiff
path: root/Libraries/Head_Task
diff options
context:
space:
mode:
Diffstat (limited to 'Libraries/Head_Task')
-rw-r--r--Libraries/Head_Task/head_task.c447
-rw-r--r--Libraries/Head_Task/head_task.h9
2 files changed, 456 insertions, 0 deletions
diff --git a/Libraries/Head_Task/head_task.c b/Libraries/Head_Task/head_task.c
new file mode 100644
index 0000000..ff70a9c
--- /dev/null
+++ b/Libraries/Head_Task/head_task.c
@@ -0,0 +1,447 @@
+#include "head_task.h"
+
+// FreeRTOS includes
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+#include "ltimers.h"
+
+#include "indicate_modes_task.h"
+#include "nixie_driver_process.h"
+#include "button_handler.h"
+
+
+// Номера функций меню
+typedef enum {
+
+ MENU_FUNC_SIMPLE_TIME_VIEW = 0,
+ MENU_ADJ_TIME,
+
+ MAX_MENU_FUNCTIONS
+
+} MenuFunctionsNums_t;
+
+// Состояния режима меню AdjTime
+typedef enum {
+
+ STATE_MENU_ADJ_TIME_START,
+ STATE_MENU_ADJ_TIME_TIMER_OUT
+
+} MenuAdjTimeStates_t;
+
+static MenuFunctionsNums_t curr_menu_func = MENU_FUNC_SIMPLE_TIME_VIEW;
+
+// Прототипы функций меню
+static void MenuFunc_SimpleTimeView ( void );
+static void MenuFunc_AdjTime ( void );
+
+
+// Массив указателей на функции-меню
+typedef void ( *MenuFunctions_t ) ( void );
+static const MenuFunctions_t MenuFunctions[MAX_MENU_FUNCTIONS] = {
+
+ MenuFunc_SimpleTimeView,
+ MenuFunc_AdjTime
+
+};
+
+void GetCurrTime ( DataToIndicate_t* indic_data );
+void SetTime ( DataToIndicate_t* indic_data );
+void AdjTimeChangeTube ( ButtonCombName_t but_comb_name, uint8_t *position );
+void AdjTimeChangeValue ( ButtonCombName_t but_comb_name, IndicModesMsgBlink_t* data, uint8_t position_mask );
+void ChangeValue ( uint8_t increase, uint8_t *data, uint8_t limit );
+
+
+DataToIndicate_t indic_data;
+extern QueueHandle_t queue_data_to_indic; // indicate_modes_task.c
+extern QueueHandle_t queue_but_comb; // button_handler.c
+extern QueueHandle_t queue_data_to_blink_mode;
+ QueueHandle_t queue_switch_indic_mode;
+
+static MenuAdjTimeStates_t state_adj_time = STATE_MENU_ADJ_TIME_START;
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void HeadTaskInit ( void )
+{
+ queue_switch_indic_mode = xQueueCreate ( 1, sizeof (IndicModesNums_t) );
+ configASSERT( queue_switch_indic_mode );
+
+ curr_menu_func = MENU_FUNC_SIMPLE_TIME_VIEW;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void MenuFunc_SimpleTimeView ( void )
+{
+ //static uint8_t prev_time = 0;
+ //static uint8_t curr_time = 1;
+
+ RTC_TimeTypeDef RTC_TimeStructure;
+
+ /* Get the current Time */
+ RTC_GetTime(RTC_Format_BCD, &RTC_TimeStructure);
+
+// curr_time = RTC_TimeStructure.RTC_Seconds;
+//
+// if ( prev_time != curr_time )
+// {
+// prev_time = curr_time;
+//
+ GetCurrTime ( &indic_data );
+ xQueueSend ( queue_data_to_indic, &indic_data, 0 );
+// }
+}
+
+
+// ----------------------------------------------------------------------------
+// Ф-я-меню настройки времени
+// ----------------------------------------------------------------------------
+void MenuFunc_AdjTime ( void )
+{
+ static const uint32_t TIME_ADJ_OUT = 5000; //ms
+
+ static IndicModesMsgBlink_t blink_data_struct;
+ static ButtonCombName_t but_comb_name;
+ IndicModesNums_t indic_mode_num;
+ static uint8_t position_mask;
+
+ //uint8_t prev_time = 1;
+ //uint8_t curr_time = 0;
+
+ // - при этом нужно постоянно слать текущее время на вывод, то есть
+ // при настройке времени оно тикает как в обычном режиме, только
+ // пользователь может его изменять при этом
+
+ switch ( state_adj_time )
+ {
+ case STATE_MENU_ADJ_TIME_START:
+
+ indic_mode_num = INDIC_MODE_BLINK;
+ // Отправляем сообщение на переключение режима индикации
+ xQueueSend ( queue_switch_indic_mode, &indic_mode_num, 0 );
+
+ // Отправляем сообщение с данными для индикации
+ // Но сначала, сотрем, вдруг прошлое собщение не было прочитано
+ xQueueReceive ( queue_data_to_blink_mode, &blink_data_struct, 0 );
+
+ GetCurrTime ( &blink_data_struct.data );
+ blink_data_struct.mask_byte = 32;
+ position_mask = blink_data_struct.mask_byte;
+
+ xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 );
+
+ state_adj_time = STATE_MENU_ADJ_TIME_TIMER_OUT;
+ StartLTimer ( LTIMER_MENU_ADJ_TIME_OUT );
+
+ break;
+
+ case STATE_MENU_ADJ_TIME_TIMER_OUT:
+
+ if ( GetLTimer (LTIMER_MENU_ADJ_TIME_OUT) >= TIME_ADJ_OUT )
+ {
+ state_adj_time = STATE_MENU_ADJ_TIME_START;
+ // Выходим из этого меню режима
+ curr_menu_func = MENU_FUNC_SIMPLE_TIME_VIEW;
+ indic_mode_num = INDIC_MODE_STANDART;
+ xQueueSend ( queue_switch_indic_mode, &indic_mode_num, 0 );
+ // При выходе из настройки времени нужно послать сообщ. на обновление
+ // данных в простой режим, т.к. фаза в моргающем режиме могла быть
+ // отрицательной, а данные обновляются только раз в секунду, и поэтому
+ // лампа может быть потухшей 1 секунду.
+ // - тут лучше сделать завершение фазы моргания
+ GetCurrTime ( &indic_data );
+ xQueueSend ( queue_data_to_indic, &indic_data, 0 );
+ }
+ else
+ {
+ // Если жмакнули кнопушку, то сбрасываем таймер, затем смотрим
+ // какую кнопушку жмакнули
+ if ( pdPASS == xQueueReceive ( queue_but_comb, &but_comb_name, 0 ) )
+ {
+ StartLTimer ( LTIMER_MENU_ADJ_TIME_OUT );
+
+ // Тут в зависимости от того, какую кнопушку жмакнули
+ switch ( but_comb_name )
+ {
+ case BUTTON_SINGLE_FORWARD:
+ case BUTTON_SINGLE_BACKWARD:
+ // Меняем позицию времени
+ AdjTimeChangeTube (but_comb_name, &position_mask);
+ GetCurrTime ( &blink_data_struct.data );
+ blink_data_struct.mask_byte = position_mask;
+ xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 );
+ break;
+
+ case BUTTON_HOLD_FORWARD:
+ case BUTTON_HOLD_BACKWARD:
+ // Меняем значение времени
+ GetCurrTime ( &blink_data_struct.data );
+ AdjTimeChangeValue ( but_comb_name, &blink_data_struct, position_mask );
+ SetTime ( &blink_data_struct.data );
+ xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 );
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ // - тут, если время изменилось, то отправляем его на вывод
+ GetCurrTime ( &blink_data_struct.data );
+
+ //curr_time = blink_data_struct.data.indic_6;
+
+ //if ( curr_time != prev_time )
+ //{
+ // prev_time = curr_time;
+ xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 );
+ //}
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void ProcessFSM_Head ( void )
+{
+
+ // - тут можно совершать внешние переключения функций меню:
+ // - ловить сообщения от внешних источников для перехода в нужный пункт
+ // меню (сообщения от gps модуля, wifi и тд.)
+
+ // 1. Ловим сообщение из модуля-обработчика нажатий кнопушек с командой
+ // на переход в меню настройки (две кнопки зажать на 3 сек)
+
+ // - перед отправкой сообщения в режим индикации сначала стираем сообщение
+
+ static ButtonCombName_t but_comb_name;
+
+ if ( pdPASS == xQueuePeek ( queue_but_comb, &but_comb_name, 0 ) )
+ {
+ if ( but_comb_name == BUTTON_LONG )
+ {
+ // - при изменении состояния меню или режима, нужно также сбрасывать
+ // внутреннее состояние текущего режима
+
+ xQueueReceive ( queue_but_comb, &but_comb_name, 0 );
+ curr_menu_func = MENU_ADJ_TIME;
+ }
+ }
+
+ MenuFunctions [curr_menu_func]();
+ taskYIELD();
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+
+//static DataToIndicate_t const_time;
+
+
+void GetCurrTime ( DataToIndicate_t *indic_data )
+{
+ RTC_TimeTypeDef RTC_TimeStructure;
+
+ /* Get the current Time */
+ RTC_GetTime ( RTC_Format_BCD, &RTC_TimeStructure );
+
+ indic_data->indic_1 = RTC_TimeStructure.RTC_Hours>>4;
+ indic_data->indic_2 = RTC_TimeStructure.RTC_Hours&0x0F;
+
+ indic_data->indic_3 = RTC_TimeStructure.RTC_Minutes>>4;
+ indic_data->indic_4 = RTC_TimeStructure.RTC_Minutes&0x0F;
+
+ indic_data->indic_5 = RTC_TimeStructure.RTC_Seconds>>4;
+ indic_data->indic_6 = RTC_TimeStructure.RTC_Seconds&0x0F;
+
+// indic_data->indic_1 = const_time.indic_1;
+// indic_data->indic_2 = const_time.indic_2;
+//
+// indic_data->indic_3 = const_time.indic_3;
+// indic_data->indic_4 = const_time.indic_4;
+//
+// indic_data->indic_5 = const_time.indic_5;
+// indic_data->indic_6 = const_time.indic_6;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void SetTime ( DataToIndicate_t* indic_data )
+{
+// const_time.indic_1 = indic_data->indic_1;
+// const_time.indic_2 = indic_data->indic_2;
+// const_time.indic_3 = indic_data->indic_3;
+// const_time.indic_4 = indic_data->indic_4;
+// const_time.indic_5 = indic_data->indic_5;
+// const_time.indic_6 = indic_data->indic_6;
+
+ RTC_TimeTypeDef RTC_TimeStructure;
+
+ RTC_TimeStructure.RTC_Hours = indic_data->indic_1 << 4;
+ RTC_TimeStructure.RTC_Hours |= indic_data->indic_2 & 0x0F;
+
+ RTC_TimeStructure.RTC_Minutes = indic_data->indic_3 << 4;
+ RTC_TimeStructure.RTC_Minutes |= indic_data->indic_4 & 0x0F;
+
+ RTC_TimeStructure.RTC_Seconds = indic_data->indic_5 << 4;
+ RTC_TimeStructure.RTC_Seconds |= indic_data->indic_6 & 0x0F;
+
+ RTC_SetTime ( RTC_Format_BCD, &RTC_TimeStructure );
+}
+
+
+// ----------------------------------------------------------------------------
+// Ф-я изменения текущего положения моргающей лампы при настройке времени
+// Ф-я вызывается из MenuFunc_AdjTime
+// Номер лампы соотносится с номером лампы ( левый бит - нулевой, и лампа тоже )
+// ----------------------------------------------------------------------------
+void AdjTimeChangeTube ( ButtonCombName_t but_comb_name, uint8_t *position_mask )
+{
+ if ( but_comb_name == BUTTON_SINGLE_FORWARD )
+ {
+ if ( !(*position_mask & ( 1 << 0 )) ) { *position_mask >>= 1; }
+ else { *position_mask = 32; } // 0010 0000
+ }
+ else
+ {
+ if ( *position_mask & ( 1 << 5 ) ) { *position_mask = 1; }
+ else { *position_mask <<= 1; }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Ф-я изменения значения цифры в текущем положении
+// То есть тут настраиваем время "поцифирно"
+// ----------------------------------------------------------------------------
+void AdjTimeChangeValue ( ButtonCombName_t but_comb_name, IndicModesMsgBlink_t *data_struct, uint8_t position_mask )
+{
+ uint8_t increase;
+
+ if ( but_comb_name == BUTTON_HOLD_FORWARD ) { increase = 1; }
+ else { increase = 0; }
+
+ switch ( position_mask & 0x3F )
+ {
+ case 0x01: // Секунды единицы
+ ChangeValue ( increase, &data_struct->data.indic_6, 9 );
+ break;
+
+ case 0x04: // Минуты единицы
+ ChangeValue ( increase, &data_struct->data.indic_4, 9 );
+ break;
+
+ case 0x02: // Секунды десятки
+ ChangeValue ( increase, &data_struct->data.indic_5, 5 );
+ break;
+
+ case 0x08: // Минуты десятки
+ ChangeValue ( increase, &data_struct->data.indic_3, 5 );
+ break;
+
+ case 0x10: // Часы единицы
+ if ( data_struct->data.indic_1 == 2 )
+ {
+ ChangeValue ( increase, &data_struct->data.indic_2, 3 );
+ }
+ else
+ {
+ ChangeValue ( increase, &data_struct->data.indic_2, 9 );
+ }
+ break;
+
+ case 0x20: // Часы десятки
+ if ( data_struct->data.indic_2 <= 3 )
+ {
+ ChangeValue ( increase, &data_struct->data.indic_1, 2 );
+ }
+ else
+ {
+ ChangeValue ( increase, &data_struct->data.indic_1, 1 );
+ }
+ break;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//static uint8_t temp;
+
+void ChangeValue ( uint8_t increase, uint8_t *data, uint8_t limit )
+{
+ //temp = *data;
+
+ if ( increase )
+ //if ( temp )
+ {
+ if ( *data < limit ) { *data += 1; }
+ else { *data = 0; }
+ }
+ else
+ {
+ if ( *data > 0 ) { *data -= 1; }
+ else { *data = limit; }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Задача ОС, реализующая головную задачу программы NixieClockSimply
+// ----------------------------------------------------------------------------
+void Head_Task ( void *pvParameters )
+{
+ while(1)ProcessFSM_Head ();
+ //vTaskDelete(NULL);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Libraries/Head_Task/head_task.h b/Libraries/Head_Task/head_task.h
new file mode 100644
index 0000000..613516c
--- /dev/null
+++ b/Libraries/Head_Task/head_task.h
@@ -0,0 +1,9 @@
+#ifndef HEAD_TASK_INCLUDED
+#define HEAD_TASK_INCLUDED
+
+#include "stm32f0xx.h"
+
+void HeadTaskInit (void);
+void Head_Task ( void *pvParameters );
+
+#endif //HEAD_TASK_INCLUDED \ No newline at end of file