From 1702ce6ce430a66bb7af51644b91b7c196e719d9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 29 Jun 2022 11:03:02 +0300 Subject: =?UTF-8?q?=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D1=8E=20=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D1=8B=D0=B9=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=B9.=20=D0=9F=D1=80=D0=BE=D0=B3=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=BC=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=81=D0=B8=D0=B8=20NixieClock=5Fv2.=20=D0=A0=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82,=20=D1=87=D0=B0=D1=81?= =?UTF-8?q?=D1=8B=20=D1=82=D0=B8=D0=BA=D0=B0=D1=8E=D1=82.=20=D0=95=D1=81?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=D0=B0?= =?UTF-8?q?,=20=D1=87=D1=82=D0=BE=20=D1=81=D0=BA=D0=B0=D1=87=D0=B5=D1=82?= =?UTF-8?q?=20=D0=B2=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20=D1=81=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=80=D0=BD=D0=B0=D1=8F=20=D0=BA=D0=BD=D0=BE=D0=BF?= =?UTF-8?q?=D0=BA=D0=B0=20(=D0=BE=D0=BD=D0=B0=20=D0=B2=20=D0=B4=D1=80?= =?UTF-8?q?=D1=83=D0=B3=D0=BE=D0=BC=20=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB=D0=B5?= =?UTF-8?q?).=20=D0=9F=D0=BE=D1=8D=D1=82=D0=BE=D0=BC=D1=83=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BD=D0=B5=D0=B5=20=D1=81=D0=BE=D0=B1=D0=B8=D1=80=D0=B0?= =?UTF-8?q?=D1=8E=D1=81=D1=8C=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D0=B0=D0=BD=D1=82=D0=B8=D0=B4=D1=80=D0=B5=D0=B1=D0=B5=D0=B7?= =?UTF-8?q?=D0=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Libraries/Head_Task/head_task.c | 447 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 Libraries/Head_Task/head_task.c (limited to 'Libraries/Head_Task/head_task.c') 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); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3