summaryrefslogtreecommitdiff
path: root/Libraries/Indicate/indicate_modes_task.c
diff options
context:
space:
mode:
Diffstat (limited to 'Libraries/Indicate/indicate_modes_task.c')
-rw-r--r--Libraries/Indicate/indicate_modes_task.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/Libraries/Indicate/indicate_modes_task.c b/Libraries/Indicate/indicate_modes_task.c
new file mode 100644
index 0000000..ef237b1
--- /dev/null
+++ b/Libraries/Indicate/indicate_modes_task.c
@@ -0,0 +1,331 @@
+#include "indicate_modes_task.h"
+#include "nixie_driver_process.h"
+#include "ltimers.h"
+
+// FreeRTOS includes
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+
+typedef enum {
+
+ STATE_BLINK_START_OFF,
+ STATE_BLINK_TIMER_OFF,
+ STATE_BLINK_TIMER_ON
+
+} IndicModesBlinkStates_t;
+
+static IndicModesBlinkStates_t state_blink = STATE_BLINK_TIMER_OFF;
+
+static IndicModesNums_t curr_indic_mode = INDIC_MODE_STANDART;
+
+QueueHandle_t queue_data_to_indic;
+QueueHandle_t queue_data_to_blink_mode;
+extern QueueHandle_t queue_switch_indic_mode;
+
+
+// Прототипы функций меню
+static void IndicMode_Standart ( void );
+static void IndicMode_Blink ( void );
+
+void DataCopyToArray ( uint8_t *data_arr, DataToIndicate_t *data_struct );
+void DataCopyToStruct ( DataToIndicate_t *data_struct, uint8_t *data_arr );
+void WriteOffByte ( uint8_t *array, uint8_t mask );
+
+
+// Массив указателей на функции-меню
+typedef void ( *IndicModes_t ) ( void );
+static const IndicModes_t IndicModes[MAX_INDIC_MODES] = {
+
+ IndicMode_Standart,
+ IndicMode_Blink
+
+};
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void IndicateModesInit ( void )
+{
+ queue_data_to_indic = xQueueCreate ( 1, sizeof (DataToIndicate_t) );
+ configASSERT( queue_data_to_indic );
+
+ queue_data_to_blink_mode = xQueueCreate ( 1, sizeof (IndicModesMsgBlink_t) );
+ configASSERT( queue_data_to_indic );
+}
+
+
+// ----------------------------------------------------------------------------
+// Режим инжикации "Стандартный", когда время выводится без эффектов
+// ----------------------------------------------------------------------------
+static void IndicMode_Standart ( void )
+{
+ ;
+
+ // Важное замечание!
+ // При передаче указателя массива через очередь ОС нужно передавать весь
+ // массив целиком, чтобы полученный экземпляр данных не менялся. Для передачи
+ // шести байт можно сделать небольшую структуру
+
+ // - тут проверяем сообщение из очереди ОС на обновление выводимых данных
+ // и если они изменились, то отправляем их в модуль Никси
+
+ static DataToIndicate_t data_struct;
+
+ if ( pdPASS == xQueueReceive ( queue_data_to_indic, &data_struct, 0 ) )
+ {
+ NixieDriver_SendValue2 ( data_struct );
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Режим "моргания" индикаторов
+// В сообщении из очереди принимаются данные, которые нужно вывести, и
+// маска-байт, которая соответствует номеру индикатора, который должен
+// моргать. Если байт установлен, то индикатор моргает. Могут моргать сразу
+// несколько индикаторов. Моргание синхронное.
+// Останавливать задачу в этих функция нельзя
+// - тут лучше было бы сделать ожидание завершения фазы моргания
+// ----------------------------------------------------------------------------
+static void IndicMode_Blink ( void )
+{
+ ;
+ // - принимаем сообщение с данными и маской, и на номер установленного
+ // байта записываем пустой символ, запоминая его. Затем запускаем таймер
+ // и отправляем массив данных с "дыркой" на вывод. После таймера
+ // записываем сохраненное значение и выводим с таймером "чистые" значения
+
+//#if 0
+
+ static const uint32_t TIME_BLINK_OFF = 250; // ms
+ static const uint32_t TIME_BLINK_ON = 250; // ms
+
+ static DataToIndicate_t data_struct;
+ static IndicModesMsgBlink_t data_new_struct;
+
+ static uint8_t indic_data_off [MAX_TUBES];
+ static uint8_t prev_indic_data_off [MAX_TUBES];
+ static uint8_t new_indic_data_off [MAX_TUBES];
+
+ static uint8_t prev_mask_byte = 0;
+ static uint8_t is_blink_tube = 0;
+
+
+ if ( pdPASS == xQueueReceive ( queue_data_to_blink_mode, &data_new_struct, 0 ) )
+ {
+ DataCopyToArray ( &new_indic_data_off[0], &data_new_struct.data );
+
+ DataCopyToArray ( &indic_data_off[0], &data_new_struct.data );
+ WriteOffByte ( &indic_data_off[0], data_new_struct.mask_byte ); // теперь можно вместо пустой цифры отправлять точку
+ DataCopyToStruct ( &data_struct, &indic_data_off[0] );
+
+ // Если изменилась только маска байта, то начинаем моргать с отрицательной
+ // фазы
+ if ( prev_mask_byte != data_new_struct.mask_byte )
+ {
+ prev_mask_byte = data_new_struct.mask_byte;
+ NixieDriver_SendValue2 ( data_struct );
+ StartLTimer ( LTIMER_INDIC_MODE_BLINK_OFF );
+ state_blink = STATE_BLINK_TIMER_OFF;
+ }
+ else
+ {
+ // А если изменились данные моргающей лампы, то начинать с
+ // положительной фазы
+ for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ )
+ {
+ if ( (prev_indic_data_off[tube_num] != new_indic_data_off[tube_num]) )// В этой лампе данные не равны?
+ {
+ if ( data_new_struct.mask_byte & ( 32 >> tube_num ) ) // И эта лампа моргающая?
+ {
+ is_blink_tube = 1;
+ break;
+ }
+ }
+ } // end for
+
+ if ( is_blink_tube == 1 )
+ {
+ NixieDriver_SendValue2 ( data_new_struct.data );
+ StartLTimer ( LTIMER_INDIC_MODE_BLINK_ON );
+ state_blink = STATE_BLINK_TIMER_ON;
+ is_blink_tube = 0;
+ }
+ else
+ {
+ if ( state_blink == STATE_BLINK_TIMER_OFF )
+ {
+ NixieDriver_SendValue2 ( data_struct );
+ }
+ else
+ {
+ NixieDriver_SendValue2 ( data_new_struct.data );
+ }
+ }
+ }
+
+ DataCopyToArray ( &prev_indic_data_off[0], &data_new_struct.data );
+ }
+
+ switch ( state_blink )
+ {
+// case STATE_BLINK_START_OFF:
+//
+// for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ )
+// {
+// if ( data_new_struct.mask_byte & ( 32 >> tube_num ) )
+// {
+// indic_data_off [tube_num] = TUBE_EMPTY_VALUE; // - тут цифра 10 это TUBE_DIGIT_EMPTY
+// }
+// }
+//
+// DataCopyToStruct ( &data_struct, &indic_data_off[0] );
+//
+// NixieDriver_SendValue2 ( data_struct );
+//
+// state_blink = STATE_BLINK_TIMER_OFF;
+// StartLTimer ( LTIMER_INDIC_MODE_BLINK_OFF );
+//
+// break;
+
+ case STATE_BLINK_TIMER_OFF:
+
+ if ( GetLTimer ( LTIMER_INDIC_MODE_BLINK_OFF ) >= TIME_BLINK_OFF )
+ {
+ NixieDriver_SendValue2 ( data_new_struct.data );
+ state_blink = STATE_BLINK_TIMER_ON;
+ StartLTimer ( LTIMER_INDIC_MODE_BLINK_ON );
+ }
+
+ break;
+
+ case STATE_BLINK_TIMER_ON:
+
+ if ( GetLTimer ( LTIMER_INDIC_MODE_BLINK_ON ) >= TIME_BLINK_ON )
+ {
+ NixieDriver_SendValue2 ( data_struct );
+ state_blink = STATE_BLINK_TIMER_OFF;
+ StartLTimer ( LTIMER_INDIC_MODE_BLINK_OFF );
+ }
+
+ break;
+ }
+
+//#endif
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void DataCopyToStruct ( DataToIndicate_t *data_struct, uint8_t *data_arr )
+{
+ data_struct->indic_1 = data_arr[0];
+ data_struct->indic_2 = data_arr[1];
+ data_struct->indic_3 = data_arr[2];
+ data_struct->indic_4 = data_arr[3];
+ data_struct->indic_5 = data_arr[4];
+ data_struct->indic_6 = data_arr[5];
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void DataCopyToArray ( uint8_t *data_arr, DataToIndicate_t *data_struct )
+{
+ data_arr[0] = data_struct->indic_1;
+ data_arr[1] = data_struct->indic_2;
+ data_arr[2] = data_struct->indic_3;
+ data_arr[3] = data_struct->indic_4;
+ data_arr[4] = data_struct->indic_5;
+ data_arr[5] = data_struct->indic_6;
+}
+
+
+// ----------------------------------------------------------------------------
+// Ф-я записи в массив "темной" лампы
+// ----------------------------------------------------------------------------
+void WriteOffByte ( uint8_t *array, uint8_t mask )
+{
+ for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ )
+ {
+ if ( mask & ( 32 >> tube_num ) )
+ {
+ //array [tube_num] = TUBE_EMPTY_VALUE; // - тут цифра 10 это TUBE_DIGIT_EMPTY
+ // Можно поробовать здесь отправлять точку вместо пустого символа
+ array [tube_num] = 12; // Шлем номер значения цифры из массива tube_digits [MAX_DIGITS]
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Режимы работы индикации (моргать, плавно переключаться и тд.)
+// ----------------------------------------------------------------------------
+void ProcessFSM_IndicateModes ( void )
+{
+ // - тут нужно принимать сообщения из модуля Меню и переходить в нужный режим
+ // индикации
+ // При этом нужно помнить, что режим индикации может иметь много состояний,
+ // поэтому нужно сбрасывать это состояние и, возможно, другие переменные
+ // перед переключением в другой режим.
+
+ IndicModesNums_t indic_mode_num;
+
+ if ( pdPASS == xQueueReceive ( queue_switch_indic_mode, &indic_mode_num, 0 ) )
+ {
+ // Сначала переведем состояние отключаемого режима в начальное
+ switch ( curr_indic_mode )
+ {
+ case INDIC_MODE_STANDART:
+
+ break;
+
+ case INDIC_MODE_BLINK:
+ state_blink = STATE_BLINK_TIMER_OFF;
+ break;
+ }
+
+ curr_indic_mode = indic_mode_num;
+ }
+
+ IndicModes [curr_indic_mode]();
+ taskYIELD();
+}
+
+
+// ----------------------------------------------------------------------------
+// Задача ОС, реализующая головную задачу программы NixieClockSimply
+// ----------------------------------------------------------------------------
+void IndicateModes_Task ( void *pvParameters )
+{
+ while(1)ProcessFSM_IndicateModes ();
+ //vTaskDelete(NULL);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+