diff options
Diffstat (limited to 'Libraries/Head_Task')
-rw-r--r-- | Libraries/Head_Task/head_task.c | 447 | ||||
-rw-r--r-- | Libraries/Head_Task/head_task.h | 9 |
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 |