summaryrefslogtreecommitdiff
path: root/Libraries/NixieDriver
diff options
context:
space:
mode:
Diffstat (limited to 'Libraries/NixieDriver')
-rw-r--r--Libraries/NixieDriver/nixie_driver_config.c209
-rw-r--r--Libraries/NixieDriver/nixie_driver_config.h106
-rw-r--r--Libraries/NixieDriver/nixie_driver_process.c595
-rw-r--r--Libraries/NixieDriver/nixie_driver_process.h67
-rw-r--r--Libraries/NixieDriver/nixie_driver_task.c88
-rw-r--r--Libraries/NixieDriver/nixie_driver_task.h8
6 files changed, 1073 insertions, 0 deletions
diff --git a/Libraries/NixieDriver/nixie_driver_config.c b/Libraries/NixieDriver/nixie_driver_config.c
new file mode 100644
index 0000000..6b5ce8a
--- /dev/null
+++ b/Libraries/NixieDriver/nixie_driver_config.c
@@ -0,0 +1,209 @@
+#include "nixie_driver_config.h"
+
+
+static void NixieDriver_TIMConfig ( void );
+static void NixieDriver_SPIConfig ( void );
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void NixieDriverConfig ( void )
+{
+ NixieDriver_TIMConfig ();
+ NixieDriver_SPIConfig ();
+}
+
+
+// ----------------------------------------------------------------------------
+// Конфигурируем таймер на 100 мкс. В прерывании каждые 100 мкс будет
+// проворачиваться механизм динамической индикации ламп Nixie
+// ----------------------------------------------------------------------------
+static void NixieDriver_TIMConfig ( void )
+{
+ NVIC_InitTypeDef NVIC_InitStructure;
+ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+
+ /* NIX_DRIVER_TIMx clock enable */
+ NIX_DRIVER_RCC_APBxPeriphClockCmd ( NIX_DRIVER_TIM_RCC, ENABLE );
+
+ /* Enable the NIX_DRIVER_TIMx gloabal Interrupt */
+ NVIC_InitStructure.NVIC_IRQChannel = NIX_DRIVER_TIM_IRQx;
+ NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init ( &NVIC_InitStructure );
+
+ /* -----------------------------------------------------------------------
+ In this example TIM7 counter clock (TIM7CLK) is set to APB1 clock (PCLK1), since
+ APB1 prescaler is set to 1 and TIM7 prescaler is set to 0.
+
+ In this example TIM7 input clock (TIM7CLK) is set to APB1 clock (PCLK1),
+ since APB1 prescaler is set to 1.
+ TIM7CLK = PCLK1 = HCLK = SystemCoreClock
+
+ With Prescaler set to 479 and Period to 24999, the TIM7 counter is updated each 250 ms
+ (i.e. and interrupt is generated each 250 ms)
+ TIM7 counter clock = TIM7CLK /((Prescaler + 1)*(Period + 1))
+ = 48 MHz / ((25000)*(480))
+ = 4 Hz
+ ==> TIM7 counter period = 250 ms
+
+ Note:
+ SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f0xx.c file.
+ Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
+ function to update SystemCoreClock variable value. Otherwise, any configuration
+ based on this variable will be incorrect.
+ ----------------------------------------------------------------------- */
+
+ /* Time base configuration */
+ TIM_TimeBaseStructure.TIM_Period = 100; // Это миксросекунды //24999
+ TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock/1000000)-1; //479;
+ TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
+ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+ TIM_TimeBaseInit ( NIX_DRIVER_TIMx, &TIM_TimeBaseStructure );
+
+ /* NIX_DRIVER_TIMx Interrupts enable */
+ TIM_ITConfig ( NIX_DRIVER_TIMx, TIM_IT_Update, ENABLE );
+
+ /* NIX_DRIVER_TIMx enable counter */
+ TIM_Cmd ( NIX_DRIVER_TIMx, ENABLE );
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+static void NixieDriver_SPIConfig ( void )
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+ SPI_InitTypeDef SPI_InitStructure;
+ NVIC_InitTypeDef NVIC_InitStructure;
+
+ /* Enable the SPI periph */
+ NIX_SPIx_RCC_APBxPeriphClockCmd ( NIX_SPIx_CLK, ENABLE );
+
+ /* Enable SCK, MOSI, MISO and NSS GPIO clocks */
+ RCC_AHBPeriphClockCmd ( NIX_SPIx_SCK_GPIO_CLK |
+ NIX_SPIx_MOSI_GPIO_CLK |
+ NIX_SPIx_ST_GPIO_CLK |
+ NIX_GPIOx_TUB_P1_GPIO_CLK |
+ NIX_GPIOx_TUB_P2_GPIO_CLK,
+ ENABLE );
+
+ GPIO_PinAFConfig ( NIX_SPIx_SCK_GPIO_PORT, NIX_SPIx_SCK_SOURCE, NIX_SPIx_SCK_AF );
+ GPIO_PinAFConfig ( NIX_SPIx_MOSI_GPIO_PORT, NIX_SPIx_MOSI_SOURCE, NIX_SPIx_MOSI_AF );
+ //GPIO_PinAFConfig ( NIX_SPIx_ST_GPIO_PORT, NIX_SPIx_ST_SOURCE, NIX_SPIx_ST_AF );
+
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
+
+ /* SPI SCK pin configuration */
+ GPIO_InitStructure.GPIO_Pin = NIX_SPIx_SCK_PIN;
+ GPIO_Init ( NIX_SPIx_SCK_GPIO_PORT, &GPIO_InitStructure );
+
+ /* SPI MOSI pin configuration */
+ GPIO_InitStructure.GPIO_Pin = NIX_SPIx_MOSI_PIN;
+ GPIO_Init ( NIX_SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure );
+
+ /* GPIO ST pin configuration */
+ GPIO_InitStructure.GPIO_Pin = NIX_SPIx_ST_PIN;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
+ //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
+ GPIO_Init ( NIX_SPIx_ST_GPIO_PORT, &GPIO_InitStructure );
+
+ // Пины управления точками на лампах (не хватило ног сдвиговых редисок)
+
+ /* GPIO tub_dp1 pin configuration */
+ GPIO_InitStructure.GPIO_Pin = NIX_GPIOx_TUB_DP1_PIN;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
+ GPIO_Init ( NIX_GPIOx_TUB_DP1_PORT, &GPIO_InitStructure );
+
+ /* GPIO tub_dp2 pin configuration */
+ GPIO_InitStructure.GPIO_Pin = NIX_GPIOx_TUB_DP2_PIN;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
+ GPIO_Init ( NIX_GPIOx_TUB_DP2_PORT, &GPIO_InitStructure );
+
+
+ /* SPI configuration -------------------------------------------------------*/
+ SPI_I2S_DeInit ( NIX_SPIx );
+ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
+ //SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
+ SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
+ SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
+ SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
+ SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
+ //SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
+ SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
+ SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
+ SPI_InitStructure.SPI_CRCPolynomial = 7;
+ SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
+ SPI_Init ( NIX_SPIx, &SPI_InitStructure );
+
+ /* Enable the SPI peripheral */
+ SPI_Cmd ( NIX_SPIx, ENABLE );
+
+ /* Configure the SPI interrupt priority */
+ NVIC_InitStructure.NVIC_IRQChannel = NIX_SPIx_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init ( &NVIC_InitStructure );
+
+ // /* Enable the Tx buffer empty interrupt */
+ SPI_I2S_ITConfig ( NIX_SPIx, SPI_I2S_IT_TXE, ENABLE );
+
+ NIX_DRIVER_RESET_ST_PIN;
+ NIX_DRIVER_RESET_TUB_DP1_PIN;
+ NIX_DRIVER_RESET_TUB_DP2_PIN;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Libraries/NixieDriver/nixie_driver_config.h b/Libraries/NixieDriver/nixie_driver_config.h
new file mode 100644
index 0000000..50c0e5e
--- /dev/null
+++ b/Libraries/NixieDriver/nixie_driver_config.h
@@ -0,0 +1,106 @@
+#ifndef NIXIE_DRIVER_CONFIG_INCLUDED
+#define NIXIE_DRIVER_CONFIG_INCLUDED
+
+#include "stm32f0xx_conf.h"
+
+
+/* Communication boards SPIx Interface */
+#define NIX_SPIx SPI1
+#define NIX_SPIx_CLK RCC_APB2Periph_SPI1
+#define NIX_SPIx_IRQn SPI1_IRQn
+#define NIX_SPIx_IRQHandler SPI1_IRQHandler
+
+#define NIX_SPIx_SCK_PIN GPIO_Pin_5
+#define NIX_SPIx_SCK_GPIO_PORT GPIOA
+#define NIX_SPIx_SCK_GPIO_CLK RCC_AHBPeriph_GPIOA
+#define NIX_SPIx_SCK_SOURCE GPIO_PinSource5
+#define NIX_SPIx_SCK_AF GPIO_AF_0
+
+#define NIX_SPIx_MOSI_PIN GPIO_Pin_7
+#define NIX_SPIx_MOSI_GPIO_PORT GPIOA
+#define NIX_SPIx_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOA
+#define NIX_SPIx_MOSI_SOURCE GPIO_PinSource7
+#define NIX_SPIx_MOSI_AF GPIO_AF_0
+
+#define NIX_SPIx_ST_PIN GPIO_Pin_4
+#define NIX_SPIx_ST_GPIO_PORT GPIOA
+#define NIX_SPIx_ST_GPIO_CLK RCC_AHBPeriph_GPIOA
+#define NIX_SPIx_ST_SOURCE GPIO_PinSource4
+#define NIX_SPIx_ST_AF GPIO_AF_0
+
+//#define NIX_SPIx_ST_EXTI_PIN GPIO_Pin_14
+//#define NIX_SPIx_ST_EXTI_GPIO_PORT GPIOB
+//#define NIX_SPIx_ST_EXTI_GPIO_CLK RCC_AHBPeriph_GPIOB
+
+#define NIX_SPIx_RCC_APBxPeriphClockCmd RCC_APB2PeriphClockCmd
+
+// Определения для таймера NixieDriver -------------------------------------- //
+#define NIX_DRIVER_TIM_IRQHandler TIM16_IRQHandler
+#define NIX_DRIVER_TIMx TIM16
+#define NIX_DRIVER_TIM_RCC RCC_APB2Periph_TIM16
+#define NIX_DRIVER_TIM_IRQx TIM16_IRQn
+#define NIX_DRIVER_RCC_APBxPeriphClockCmd RCC_APB2PeriphClockCmd
+
+#define NIX_DRIVER_SET_ST_PIN GPIO_SetBits ( NIX_SPIx_ST_GPIO_PORT, NIX_SPIx_ST_PIN )
+#define NIX_DRIVER_RESET_ST_PIN GPIO_ResetBits ( NIX_SPIx_ST_GPIO_PORT, NIX_SPIx_ST_PIN )
+
+// Определения для управления точками на лампах (т.к. не хватило ног сдвиговых редисок)
+#define NIX_GPIOx_TUB_P1_GPIO_CLK RCC_AHBPeriph_GPIOB
+#define NIX_GPIOx_TUB_P2_GPIO_CLK RCC_AHBPeriph_GPIOB
+#define NIX_GPIOx_TUB_DP1_PIN GPIO_Pin_14
+#define NIX_GPIOx_TUB_DP2_PIN GPIO_Pin_12
+#define NIX_GPIOx_TUB_DP1_PORT GPIOB
+#define NIX_GPIOx_TUB_DP2_PORT GPIOB
+#define NIX_DRIVER_RESET_TUB_DP1_PIN NIX_GPIOx_TUB_DP1_PORT->BRR = NIX_GPIOx_TUB_DP1_PIN
+#define NIX_DRIVER_RESET_TUB_DP2_PIN NIX_GPIOx_TUB_DP2_PORT->BRR = NIX_GPIOx_TUB_DP2_PIN
+#define NIX_DRIVER_SET_TUB_DP1_PIN NIX_GPIOx_TUB_DP1_PORT->BSRR = NIX_GPIOx_TUB_DP1_PIN
+#define NIX_DRIVER_SET_TUB_DP2_PIN NIX_GPIOx_TUB_DP2_PORT->BSRR = NIX_GPIOx_TUB_DP2_PIN
+
+
+//#define NIX_TEST_SET_PB12_PIN GPIO_SetBits ( GPIOB, GPIO_Pin_12 )
+//#define NIX_TEST_RESET_PB12_PIN GPIO_ResetBits ( GPIOB, GPIO_Pin_12 )
+//#define NIX_TEST_PIN_PB11_TOGGLE GPIOB->ODR ^= GPIO_Pin_11
+//#define NIX_TEST_PIN_PB12_TOGGLE GPIOB->ODR ^= GPIO_Pin_12
+
+void NixieDriverInitProcess ( void );
+void NixieDriverConfig ( void );
+
+
+#endif //NIXIE_DRIVER_CONFIG_INCLUDED
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Libraries/NixieDriver/nixie_driver_process.c b/Libraries/NixieDriver/nixie_driver_process.c
new file mode 100644
index 0000000..ddc728b
--- /dev/null
+++ b/Libraries/NixieDriver/nixie_driver_process.c
@@ -0,0 +1,595 @@
+#include "nixie_driver_process.h"
+#include "nixie_driver_config.h"
+#include "indicate_modes_task.h"
+#include "light_sensor_task.h"
+
+#include <stdint.h>
+
+// FreeRTOS includes
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+// - массив для цифр дешифратора
+// - массив для номера лампы
+// - счетчик номера текущей лампы
+// - таймер1 для времени горения
+// - таймер2 для времени затухания
+
+#define TUBE_HEATING_UP 0
+
+
+static const uint16_t tube_off_digit = 0; // Символ для дешифратора, чтобы лампа не горела
+
+// Массив значений цифр для дешифратора. Если старший байт вперед.
+// И учтено, что все значения сдвинуты на 1 влево
+const uint16_t tube_digits [MAX_DIGITS] = { // Цифра на лампе
+ TUBE_DIGIT_0, // 0
+ TUBE_DIGIT_1, // 1
+ TUBE_DIGIT_2, // 2
+ TUBE_DIGIT_3, // 3
+ TUBE_DIGIT_4, // 4
+ TUBE_DIGIT_5, // 5
+ TUBE_DIGIT_6, // 6
+ TUBE_DIGIT_7, // 7
+ TUBE_DIGIT_8, // 8
+ TUBE_DIGIT_9, // 9
+ TUBE_DIGIT_DP1, // dp1
+ TUBE_DIGIT_DP2, // dp2
+ TUBE_DIGIT_EMPTY // лампа не горит
+};
+
+// Лампы на плате идут слева направо. Значение ячейки массива с учетом, если
+// старший байт идет вперед в SPI
+// И учтено, что все значения сдвинуты на 1 влево
+static const uint16_t tube_num [ MAX_TUBES ] = {
+ TUBE_NUM_1, // 1-я лампа
+ TUBE_NUM_2, // 2-я лампа
+ TUBE_NUM_3, // 3-я лампа
+ TUBE_NUM_4, // 4-я лампа
+ TUBE_NUM_5, // 5-я лампа
+ TUBE_NUM_6 // 6-я лампа
+};
+
+
+// Текущий буфер с данными-цифрами на лампы
+static uint16_t curr_tube_bufer [ MAX_TUBES ] = {
+ TUBE_DIGIT_1, // 0
+ TUBE_DIGIT_1, // 1
+ TUBE_DIGIT_1, // 2
+ TUBE_DIGIT_1, // 3
+ TUBE_DIGIT_1, // 4
+ TUBE_DIGIT_1 // 5
+};
+
+
+// Яркость ------------------------------------------------------------------ //
+
+// горит / не горит
+// time1 / time2
+// 1 9
+// 2 8
+// 3 7
+// 4 6
+// 5 6
+// 6 4
+// 7 3
+// 8 2
+// 9 1
+// 10 0
+
+#define TIME_PERIOD_TCONST (uint32_t)80 // Время полного периода частоты работы ламп. Единица измерения зависит от настройки
+ // таймера. В данном случае таймер тикает раз в 100 мкс, значит Т = 80 => T = 80*100 = 8000мкс = 8мс
+#define TIME_MIN (uint32_t)1 // Минимальный шаг времени таймера = 100 мкс. Минимальное время горения лампы
+
+// - добавить состояния DARK и LIGHT
+// (по сути это только комбинации TIME_ON и TIME_OFF)
+#define TIME_ON 2//5//20
+#define TIME_OFF 23//22
+// Время паузы после вкл/выкл всез ламп поочереди
+#define TIME_OFF_BRIGHT 0
+#define TIME_OFF_DARK 100
+
+#define TIME_TEST 10000
+
+static uint32_t time_on = TIME_ON; // Время горения лампы
+static uint32_t time_off = TIME_OFF; // Время на угасание лампы ( чтобы она успела погаснуть полностью )
+static uint32_t time_off2 = TIME_OFF_DARK;
+// static uint32_t time_on = TIME_OFF;
+// static uint32_t time_off = TIME_ON;
+// static uint32_t time_off2 = TIME_OFF_BRIGHT;
+
+//static uint32_t coef_brightness = 1; // Коэффициент яркости. Не может быть нулем!
+
+// Переменная для проверки первая или вторая пара байт ушла в отправку
+// Нужна т.к. нужно оправить именно 2 пары байт на динам. индикацию
+//static uint8_t first_byte;
+
+// Для сохранения номера лампы при отправке второй пары байт
+//static uint16_t tube_nbr_second_value;
+
+// Сообщения очереди ОСРВ
+QueueHandle_t queue_new_value;
+QueueHandle_t queue_new_data;
+static LightSensorState_t light_sensor_state;
+extern QueueHandle_t queue_light_sensor;
+
+
+// Прототипы функций файла -------------------------------------------------- //
+// Открытые
+void NixieDriver_SendValue ( uint8_t *value_arr );
+// Закрытые
+static void SwitchOnTube ( uint8_t tube_nbr );
+static void SwitchOffTube ( uint8_t tube_nbr );
+// - функция начальной конфигурации времени ( чтение яркости из памяти EE )
+// void NixieDriver_LoadBrightnessFromMemory ( void ); // Ф-я читает из памяти значение коэффициента яркости coef_brightness
+//static void NewTimeCalculate ( uint32_t *time_on, uint32_t *time_off );
+// - ф-я NixieDriver_SetBrightness ( uint32_t ??? ); // Какие будут пределы и количество уровней яркости?
+// - ф-я NixieDriver_IncreaseBrighntness ( void ); // Увеличить яркость на один шаг ( то есть увеличится коэф. яркости на +1 )
+// - ф-я NixieDriver_DecreaseBrighntness ( void ); // Уменьшить яркость на один шаг ( то есть уменьшится коэф. яркости на -1 )
+
+#if TUBE_HEATING_UP == 0
+static uint8_t LoadNextValueToTubes ( void );
+#else
+static uint8_t LoadNextValueToTubes ( void );
+#endif
+
+//static void TestLoadNewValueToClock ( void );
+static void UpdateValueForClock ( void );
+static void CheckLightSensor (void);
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void NixieDriverInitProcess ( void )
+{
+ //first_byte = 0;
+
+ queue_new_value = xQueueCreate ( 1, sizeof (uint8_t*) );
+ configASSERT( queue_new_value );
+ queue_new_data = xQueueCreate ( 1, sizeof (DataToIndicate_t) );
+ configASSERT( queue_new_value );
+}
+
+
+// ----------------------------------------------------------------------------
+// Ф-я, реализующая беспрерывный процесс динамической индикации ламп Nixie
+// Ф-я вызывается из прерывания таймера, настроенного на 100 мкс
+// ----------------------------------------------------------------------------
+void ProcessNixieDriverFromISR ( void )
+{
+ static uint8_t process_indic_state = 0;
+ static uint32_t timer = TIME_ON;
+ static uint8_t curr_tube_num = 0;
+
+ timer++;
+ //timer_test++;
+
+#if TUBE_HEATING_UP == 0
+
+ switch ( process_indic_state )
+ {
+
+ case 0:
+
+ if ( timer >= time_off ) // Ждем время горения лампы
+ {
+ curr_tube_num = LoadNextValueToTubes ();
+ SwitchOnTube ( curr_tube_num );
+ timer = 0;
+ process_indic_state = 1;
+ /*
+ if ( curr_tube_num == (MAX_TUBES - 1) )
+ {
+ UpdateValueForClock ();
+ CheckLightSensor();
+
+ // SwitchOffTube ( curr_tube_num );
+ //process_indic_state = 2;
+ //timer = 0;
+
+ }
+ */
+ }
+
+ break;
+
+ case 1:
+
+ if ( timer >= time_on )
+ {
+ SwitchOffTube ( curr_tube_num );
+ timer = 0;
+ process_indic_state = 0;
+
+ if ( curr_tube_num == (MAX_TUBES - 1) )
+ {
+ UpdateValueForClock ();
+ CheckLightSensor();
+
+ SwitchOffTube ( curr_tube_num );
+ process_indic_state = 2;
+ timer = 0;
+
+ }
+ }
+
+ break;
+
+ case 2:
+
+ if ( timer >= time_off2 )
+ {
+ //SwitchOnTube ( curr_tube_num );
+ timer = time_off;
+ process_indic_state = 0;
+ }
+
+ break;
+
+ } // end switch
+
+#else
+/*
+ switch ( process_indic_state )
+ {
+
+ case 0:
+
+ SwitchOnTube ( curr_tube_num );
+ timer = 0;
+ process_indic_state = 1;
+
+ break;
+
+ case 1:
+
+ if ( timer >= time1 ) // Ждем время горения лампы
+ {
+ curr_tube_num = LoadNextValueToTubes ();
+ timer = 0;
+ process_indic_state = 0;
+ }
+
+ break;
+
+ } // end switch
+ */
+
+#endif
+
+}
+
+// ----------------------------------------------------------------------------
+// Ф-я подготовки и запуска передачи байт по SPI в сдвиговые регистры
+// управеления динамической индикацией. По сути включает нужную лампу
+// Ф-я принимает текущий номер лампы, для которой будет формироваться
+// пакет-кадр
+// ----------------------------------------------------------------------------
+static void SwitchOnTube ( uint8_t tube_nbr )
+{
+ // - сначала отправляем пару байт с номером лампы
+ // - затем отправляем пару байт с номером цифры
+
+ static uint16_t temp;
+
+ temp = 0;
+ temp = tube_num [ tube_nbr ]; //(uint16_t)curr_tube_bufer [ tube_nbr ];
+ temp |= curr_tube_bufer [ tube_nbr ];
+
+ NIX_DRIVER_RESET_ST_PIN;
+
+ // Т.к. точки на лампах управляются напрямую с МК через GPIO,
+ // то нужно проверять вручную идет ли в пакете точка
+ // Маленький нюанс:
+ // Если мы выставим сигнал на точки раньше, чем передадим пакет на включение ламп по SPI,
+ // то по идее точки включатся раньше, чем подастся сигнал ST
+ if (curr_tube_bufer [ tube_nbr ] & TUBE_DIGIT_DP1)
+ {
+ NIX_DRIVER_SET_TUB_DP1_PIN;
+ }
+ else
+ {
+ NIX_DRIVER_RESET_TUB_DP1_PIN;
+ }
+
+ if (curr_tube_bufer [ tube_nbr ] & TUBE_DIGIT_DP2)
+ {
+ NIX_DRIVER_SET_TUB_DP2_PIN;
+ }
+ else
+ {
+ NIX_DRIVER_RESET_TUB_DP2_PIN;
+ }
+
+ SPI_I2S_SendData16 ( NIX_SPIx, temp );
+ SPI_I2S_ITConfig ( NIX_SPIx, SPI_I2S_IT_TXE, ENABLE );
+}
+
+
+// ----------------------------------------------------------------------------
+// Ф-я отключает лампу
+// ----------------------------------------------------------------------------
+static void SwitchOffTube ( uint8_t tube_nbr )
+{
+ //static uint16_t value_to_spi1;
+ //static uint16_t temp1;
+
+ //value_to_spi1 = (uint16_t)tube_off_digit;
+ //value_to_spi1 <<= 8;
+
+ //temp1 = 0;
+ //temp1 = (uint16_t)tube_num [ tube_nbr ];
+
+ //value_to_spi1 |= temp1;
+
+ //first_byte = 1;
+ //tube_nbr_second_value = tube_off_digit;
+ NIX_DRIVER_RESET_ST_PIN;
+
+ NIX_DRIVER_RESET_TUB_DP1_PIN;
+ NIX_DRIVER_RESET_TUB_DP2_PIN;
+ SPI_I2S_SendData16 ( NIX_SPIx, tube_off_digit );
+ SPI_I2S_ITConfig ( NIX_SPIx, SPI_I2S_IT_TXE, ENABLE );
+}
+
+// ----------------------------------------------------------------------------
+// Ф-я проверяет нужно ли зажечь точку на индикаторах сразу после отправки
+// двух байт по SPI
+// Ф-я вызываетяс из прерывания после ухода двух байт из SPI
+// Если есть точка, то зажигаем ее с помощью GPIO
+// ----------------------------------------------------------------------------
+// void NixieDriverCheckDPPins (void)
+// {
+// ;
+// }
+
+
+// ----------------------------------------------------------------------------
+// Ф-я проверяет первые ли 2 байта отправлены по SPI
+// Ф-я вызывается из прерывания NIX_SPIx_IRQHandler
+// ----------------------------------------------------------------------------
+// uint8_t NixieDriverProcessCheckIsFirstByte (void)
+// {
+// //return first_byte;
+// return 0;
+// }
+
+
+// ----------------------------------------------------------------------------
+// Ф-я отправляет вторую пару байт со значением цифр
+// ----------------------------------------------------------------------------
+// void NixieDriverProcessSendSecondByte ( void )
+// {
+// first_byte = 0;
+// SPI_I2S_SendData16 ( NIX_SPIx, tube_nbr_second_value );
+// }
+
+
+#if TUBE_HEATING_UP == 1
+// ----------------------------------------------------------------------------
+// Временная ф-я для прогрева каждой лампы по каждому катоду
+// ----------------------------------------------------------------------------
+static uint8_t LoadNextValueToTubes ( void )
+{
+ static uint8_t curr_tube_num = 0;
+ static uint8_t curr_digit = 0;
+
+ if ( curr_digit == 10 )
+ {
+ if ( curr_tube_num == 5 )
+ {
+ curr_tube_num = 0;
+ }
+ else
+ {
+ curr_tube_num++;
+ if ( curr_tube_num == 1 ) { curr_tube_num++; }
+ }
+ curr_digit = 0;
+ }
+
+ curr_tube_bufer [ curr_tube_num ] = tube_digits [ curr_digit ];
+ curr_digit++;
+
+ return curr_tube_num;
+}
+
+#else
+
+static uint8_t LoadNextValueToTubes ( void )
+{
+ static uint8_t curr_tube_num = 5;
+
+ if ( curr_tube_num == 5 )
+ {
+ curr_tube_num = 0;
+ //NIX_TEST_PIN_PB11_TOGGLE;
+ }
+ else
+ {
+ curr_tube_num++;
+ }
+
+ return curr_tube_num;
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// Ф-я проверки и расчета нового значения яркости для динамической индикации
+// ламп
+// ----------------------------------------------------------------------------
+//static void NewTimeCalculate ( uint32_t *time_on, uint32_t *time_off )
+//{
+//// uint32_t time_check;
+////
+//// time_on = TIME_MIN*coef_brightness;
+////
+//// if ( time_on > TIME_PERIOD_TCONST ) { return; }
+//
+//}
+
+
+// ----------------------------------------------------------------------------
+// Тестовая ф-я перебирает последовательно все цифры одновременно на каждом
+// индикаторе
+// ----------------------------------------------------------------------------
+//static void TestLoadNewValueToClock ( void )
+//{
+// static uint8_t digit_num = 0;
+//
+// //curr_tube_bufer [] = tube_digits [];
+// // Зугружаем в каждую лампу одно и то же значение
+// for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ )
+// {
+// curr_tube_bufer [tube_num] = tube_digits [digit_num];
+// }
+// digit_num++;
+//
+// if ( digit_num == MAX_DIGITS )
+// {
+// digit_num = 0;
+// }
+//}
+
+
+// ----------------------------------------------------------------------------
+// Обновления значения выводимого на индикаторы
+// Ф-я вызывается из ф-ии ProcessNixieDriverFromISR () после вывода одного
+// цикла ( то есть 6-ти индикаторов )
+// ----------------------------------------------------------------------------
+
+// - внимание! нужно сделать два буфера, из которых в прерывании берутся
+// данные на передачу в лампы в SPI. Это нужно, чтобы не тратить время на
+// заполнение данных буфера. Сделать флаг или семафор. Пока из одного
+// буфера данные уходят, то в другой заполняют новые данные. А когда они
+// заполнятся, то просто поменять указатель на массив.
+
+// - сделать защиту от выхода за границы массива tube_digits [10]
+// (не больше 10)
+
+static void UpdateValueForClock ( void )
+{
+ // - проверяем сообщение очереди с новыми данными для отображения
+ // если есть, то заполняем буфер curr_tube_bufer [] новыми значениями
+ //uint8_t *value_arr;
+ DataToIndicate_t data_struct;
+
+// if ( pdPASS == xQueueReceive ( queue_new_value, &value_arr, 0 ) )
+// {
+// for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ )
+// {
+// curr_tube_bufer [tube_num] = tube_digits [ value_arr [tube_num] ];
+// }
+// }
+
+
+ if ( pdPASS == xQueueReceive ( queue_new_data, &data_struct, 0 ) )
+ {
+ curr_tube_bufer [0] = tube_digits [ data_struct.indic_1 ];
+ curr_tube_bufer [1] = tube_digits [ data_struct.indic_2 ];
+ curr_tube_bufer [2] = tube_digits [ data_struct.indic_3 ];
+ curr_tube_bufer [3] = tube_digits [ data_struct.indic_4 ];
+ curr_tube_bufer [4] = tube_digits [ data_struct.indic_5 ];
+ curr_tube_bufer [5] = tube_digits [ data_struct.indic_6 ];
+
+ }
+
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+static void CheckLightSensor (void)
+{
+ //LightSensorState_t light_sensor_state;
+ if ( pdPASS == xQueueReceive ( queue_light_sensor, &light_sensor_state, 0 ) )
+ {
+ if (light_sensor_state == LIGHT_SENSOR_STATE_LIGHT )
+ {
+ time_on = TIME_OFF;
+ time_off = TIME_ON;
+ time_off2 = TIME_OFF_BRIGHT;//TIME_OFF_DARK;
+ }
+ else
+ {
+ time_on = TIME_ON;
+ time_off = TIME_OFF;
+ time_off2 = TIME_OFF_DARK;//TIME_OFF_BRIGHT;
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Ф-я кладет сообщение в очередь ОС и передает указатель на массив с данными
+// Размер массива всегда 6 (количество ламп)
+// ----------------------------------------------------------------------------
+void NixieDriver_SendValue ( uint8_t *value_arr )
+{
+ xQueueSend ( queue_new_value, &value_arr, 0 );
+}
+
+//void NixieDriver_SendValue2 ( uint8_t *value_arr )
+//{
+// xQueueSend ( queue_new_value, &value_arr, 0 );
+//}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Libraries/NixieDriver/nixie_driver_process.h b/Libraries/NixieDriver/nixie_driver_process.h
new file mode 100644
index 0000000..00f08f5
--- /dev/null
+++ b/Libraries/NixieDriver/nixie_driver_process.h
@@ -0,0 +1,67 @@
+#ifndef NIXIE_DRIVER_PROCESS_INCLUDED
+#define NIXIE_DRIVER_PROCESS_INCLUDED
+
+#include <stdint.h>
+#include "FreeRTOS.h"
+#include "queue.h"
+
+// Схема драйвера Никси на трех сдвиговых 8-разрядных регистрах.
+// Первые два регистра для цифр, третий регистр для выбора лампы
+
+#define MAX_TUBES 6
+#define MAX_DIGITS 13//11
+
+// Коды цифр ламп для буфера tube_digit [] Значения 16-разрядные
+#define TUBE_DIGIT_0 8192 //0010 0000 0000 0000
+#define TUBE_DIGIT_1 128 //0000 0000 1000 0000
+#define TUBE_DIGIT_2 64 //0000 0000 0100 0000
+#define TUBE_DIGIT_3 32 //0000 0000 0010 0000
+#define TUBE_DIGIT_4 16 //0000 0000 0001 0000
+#define TUBE_DIGIT_5 8 //0000 0000 0000 1000
+#define TUBE_DIGIT_6 4 //0000 0000 0000 0100
+#define TUBE_DIGIT_7 2 //0000 0000 0000 0010
+#define TUBE_DIGIT_8 32768 //1000 0000 0000 0000
+#define TUBE_DIGIT_9 16384 //0100 0000 0000 0000
+#define TUBE_DIGIT_DP1 1 //0000 0000 0000 0001 любое отличное от остальных число, т.к. точки на лампах управляются от отдельных GPIO
+#define TUBE_DIGIT_DP2 256 //0000 0001 0000 0000 любое отличное от остальных число, т.к. точки на лампах управляются от отдельных GPIO
+#define TUBE_DIGIT_EMPTY 0
+
+#define TUBE_EMPTY_VALUE 0 // Было "10". Число, которое нужно записать в массив
+ // данных на вывод, чтобы получить негорящий
+ // индикатор
+
+// Коды номера лампы для буфера tube_num [ MAX_TUBES ]
+#define TUBE_NUM_6 1
+#define TUBE_NUM_5 256
+#define TUBE_NUM_4 512
+#define TUBE_NUM_3 1024
+#define TUBE_NUM_2 2048
+#define TUBE_NUM_1 4096
+
+// Структура данных на индикацию для передачи целиком всей структуры через
+// очередь ОС
+typedef struct {
+
+ uint8_t indic_1;
+ uint8_t indic_2;
+ uint8_t indic_3;
+ uint8_t indic_4;
+ uint8_t indic_5;
+ uint8_t indic_6;
+
+} DataToIndicate_t;
+
+
+void NixieDriver_SendValue ( uint8_t *value_arr );
+
+extern QueueHandle_t queue_new_data;
+
+#define send(X) xQueueSend ( queue_new_data, &X, 0 )
+#define NixieDriver_SendValue2(X) send(X)
+
+void ProcessNixieDriverFromISR ( void );
+//uint8_t NixieDriverProcessCheckIsFirstByte (void);
+//void NixieDriverCheckDPPins (void);
+//void NixieDriverProcessSendSecondByte (void);
+
+#endif //NIXIE_DRIVER_PROCESS_INCLUDED \ No newline at end of file
diff --git a/Libraries/NixieDriver/nixie_driver_task.c b/Libraries/NixieDriver/nixie_driver_task.c
new file mode 100644
index 0000000..18e554c
--- /dev/null
+++ b/Libraries/NixieDriver/nixie_driver_task.c
@@ -0,0 +1,88 @@
+#include "nixie_driver_task.h"
+#include "nixie_driver_config.h"
+#include "nixie_driver_process.h"
+
+// FreeRTOS includes
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+void NixieDriverInit ( void )
+{
+ NixieDriverInitProcess ();
+ NixieDriverConfig ();
+}
+
+
+// ----------------------------------------------------------------------------
+// - нужна ли эта задача, если все работает в прерывании?
+// ----------------------------------------------------------------------------
+void ProcessFSM_NixieDriver ( void )
+{
+ vTaskDelay (500);
+}
+
+
+// ----------------------------------------------------------------------------
+// Задача ОС, реализующая головную задачу программы NixieClockSimply
+// ----------------------------------------------------------------------------
+void NixieDriver_Task ( void *pvParameters )
+{
+ while(1)ProcessFSM_NixieDriver ();
+ //vTaskDelete(NULL);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Libraries/NixieDriver/nixie_driver_task.h b/Libraries/NixieDriver/nixie_driver_task.h
new file mode 100644
index 0000000..1c9fb39
--- /dev/null
+++ b/Libraries/NixieDriver/nixie_driver_task.h
@@ -0,0 +1,8 @@
+#ifndef NIXIE_DRIVER_TASK_INCLUDED
+#define NIXIE_DRIVER_TASK_INCLUDED
+
+void NixieDriverInit ( void );
+
+void NixieDriver_Task ( void *pvParameters );
+
+#endif //NIXIE_DRIVER_TASK_INCLUDED \ No newline at end of file