diff options
Diffstat (limited to 'Libraries/NixieDriver')
-rw-r--r-- | Libraries/NixieDriver/nixie_driver_config.c | 209 | ||||
-rw-r--r-- | Libraries/NixieDriver/nixie_driver_config.h | 106 | ||||
-rw-r--r-- | Libraries/NixieDriver/nixie_driver_process.c | 595 | ||||
-rw-r--r-- | Libraries/NixieDriver/nixie_driver_process.h | 67 | ||||
-rw-r--r-- | Libraries/NixieDriver/nixie_driver_task.c | 88 | ||||
-rw-r--r-- | Libraries/NixieDriver/nixie_driver_task.h | 8 |
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 |