123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871 |
- /**
- * My Nixie Clock IN-4x6
- * Vladimir N. Shilov <shilow@ukr.net>
- * 2020.01.06
- */
- /* Compiler libs */
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <avr/sleep.h>
- #include <avr/eeprom.h>
- #include <avr/pgmspace.h>
- /* Project libs */
- #include "i2c.h"
- #include "ds3231.h"
- #include "rtos.h"
- #include "event-system.h"
- #include "main.h"
- #include "common.h"
- /* Defines */
- /* Timer2 settings
- * Prescaler (CS22/CS21/CS20 - value):
- * 0/0/0 - stop
- * 0/0/0 - 1 (no prescale)
- * 0/1/0 - 8
- * 0/1/1 - 32
- * 1/0/0 - 64
- * 1/0/1 - 128
- * 1/1/0 - 256
- * 1/1/1 - 1024
- */
- #define TIMER2_HZ 360
- #if F_CPU == 16000000
- #define TIMER2_PRESCALER 256
- #define TIMER2_CS (1<<CS22 | 1<<CS21 | 0<<CS20)
- #elif F_CPU == 8000000
- #define TIMER2_PRESCALER 64
- #define TIMER2_CS (0<<CS22 | 1<<CS21 | 1<<CS20)
- #endif // F_CPU
- #define TIMER2_CNT (0x100 - (F_CPU / TIMER2_PRESCALER / TIMER2_HZ))
- /* Display timeout, sec */
- #define DISP_WDT_TIME 10
- #ifdef USE_UART
- /* USART */
- #define BAUD 19200UL
- #define BAUD_PRESCALE (uint8_t)((F_CPU / BAUD / 16UL) - 1)
- #define CHAR_NEWLINE '\n'
- #define CHAR_RETURN '\r'
- #define RETURN_NEWLINE "\r\n"
- #endif // USE_UART
- #ifdef USE_BRIGHT_CONTROL
- //static void startADC(void);
- //volatile uint8_t resultADC = 0;
- /* Lamp brightness */
- #define BRIGHT_IDX_MAX 4
- #define LIGHT_LEVEL 100
- #define FULL_BRIGHT_ON 0x06
- #define FULL_BRIGHT_OFF 0x22
- static const uint8_t PROGMEM brightConv[BRIGHT_IDX_MAX+1] = {
- #if F_CPU == 16000000
- /* 155, 164, 181, 211, 255 */
- /* for 83: */
- 117, 151, 185, 219, 255
- #elif F_CPU == 8000000
- 54, 71, 106, 165, 255
- #endif // F_CPU
- };
- #endif // USE_BRIGHT_CONTROL
- /* Variables */
- static volatile uint8_t Digit[LAMP_NUM] = {1, 2, 3, 4, 5, 6};
- static rtc_t RTC, setRTC;
- static volatile struct {
- uint8_t RTC_Int: 1;
- uint8_t blinkC: 1; // флаг задающий ритм мигания
- uint8_t blink0: 1; // мигать разрядами 1-2
- uint8_t blink1: 1; // мигать разрядами 3-4
- uint8_t blink2: 1; // мигать разрядами 5-6
- uint8_t saveEEP: 1;
- uint8_t rezerv: 2;
- } Flag;
- static btn_t Button[BTN_NUM] = {
- {0, evBTN1Pressed, evBTN1Holded, BUTTON1_PIN},
- {0, evBTN2Pressed, evBTN2Pressed, BUTTON2_PIN},
- {0, evBTN3Pressed, evBTN3Pressed, BUTTON3_PIN}
- };
- static volatile uint8_t DISP_WDT = 0;
- static EEMEM uint8_t EEP_BrightIdx;
- static uint8_t brightIdx;
- static EEMEM uint8_t EEP_SummerTime;
- /* Function prototypes */
- static void Board_Init(void);
- static void btnProcess(void);
- static void valIncrease(uint8_t * val, uint8_t max);
- static void valDecrease(uint8_t * val, uint8_t max);
- static void blink(void);
- static void setSummerWinterTime(void);
- #ifdef LAMP_TEST
- static void lampTest(void);
- #endif // LAMP_TEST
- #ifdef USE_UART
- void usart_putc (char send);
- void usart_puts (const char *send);
- #endif // USE_UART
- void main(void) {
- /**
- * Локальные переменные
- */
- uint8_t event = 0;
- Flag.RTC_Int = 0;
- Flag.blink0 = 0;
- Flag.blink1 = 0;
- Flag.blink2 = 0;
- Flag.blinkC = 0;
- Flag.saveEEP = 0;
- #ifdef USE_BRIGHT_CONTROL
- brightIdx = eeprom_read_byte(&EEP_BrightIdx);
- if (brightIdx > BRIGHT_IDX_MAX) {
- brightIdx = BRIGHT_IDX_MAX;
- }
- #endif // USE_BRIGHT_CONTROL
- /**
- * Инициализация, настройка...
- */
- Board_Init();
- /* Initialize Scheduler */
- RTOS_Init();
- tdelay_ms(2000);
- #ifdef LAMP_TEST
- lampTest();
- tdelay_ms(5000);
- #endif // LAMP_TEST
- /* Initialize I2C Bus and RTC */
- I2C_Init();
- RTC_Init();
- RTC_ReadAll(&RTC);
- /* Initialize Event State Machine */
- ES_Init(stShowTime);
- RTOS_SetTask(btnProcess, 3, BTN_SCAN_PERIOD);
- #ifdef USE_BRIGHT_CONTROL
- // RTOS_SetTask(startADC, 10, 500);
- #endif // USE_BRIGHT_CONTROL
- showTime();
- /** main loop */
- do {
- /* new second interrupt from RTC */
- if (Flag.RTC_Int != 0) {
- Flag.RTC_Int = 0;
- ES_PlaceEvent(evNewSecond);
- RTC_ReadTime(&RTC);
- if (RTC.Sec == 0 && RTC.Min == 0) {
- // begin of new hour
- if (RTC.Hr == 0) {
- // begin of new day
- RTC_ReadCalendar(&RTC);
- ES_PlaceEvent(evRefreshCal);
- }
- #ifdef USE_BRIGHT_CONTROL
- if (RTC.Hr >= FULL_BRIGHT_ON && RTC.Hr < FULL_BRIGHT_OFF) {
- // if (resultADC < LIGHT_LEVEL) {
- OCR2 = pgm_read_byte(&brightConv[BRIGHT_IDX_MAX]);
- } else {
- OCR2 = pgm_read_byte(&brightConv[brightIdx]);
- }
- #endif // USE_BRIGHT_CONTROL
- setSummerWinterTime();
- } // begin new hour
- if (DISP_WDT != 0) {
- DISP_WDT --;
- if (DISP_WDT == 0) {
- ES_PlaceEvent(evDisplayWDT);
- if (Flag.saveEEP != 0) {
- Flag.saveEEP = 0;
- eeprom_update_byte(&EEP_BrightIdx, brightIdx);
- }
- }
- }
- } // End of New Second
- event = ES_GetEvent();
- if (event) {
- ES_Dispatch(event);
- }
- // крутим диспетчер
- RTOS_DispatchTask();
- // делать нечего -- спим, ждём прерывание
- set_sleep_mode(SLEEP_MODE_IDLE);
- sleep_mode();
- } while(1);
- }
- /**
- * П о д п р о г р а м м ы
- */
- /**
- * @brief Initializy perephireal
- */
- static void Board_Init(void) {
- /* power off Analog Comparator */
- ACSR = ACD;
- /* GPIO */
- DDRB = ANODB_PINS; // as output
- PORTB = BUTTON_PINS; // enable pull-up
- DDRC = DIGIT_PINS; // as output
- DDRD = (DOT_PIN | ANODD_PINS); // as output
- /* Timer2 - refresh Nixie values */
- TCCR2 = TIMER2_CS;
- TCNT2 = TIMER2_CNT;
- TIMSK = _BV(TOIE2);
- #ifdef USE_BRIGHT_CONTROL
- /* ADC init */
- // ADMUX = (1<<REFS0 | 1<<ADLAR | 1<<MUX2 | 1<<MUX1 | 1<<MUX0); // Vref = AVcc, channel ADC7, Left adjusted result
- // ADCSRA = (1<<ADEN | 1<<ADSC | 1<<ADIE | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0); // enable ADC, prescaler = 128
- OCR2 = pgm_read_byte(&brightConv[BRIGHT_IDX_MAX]);
- TIMSK |= _BV(OCIE2);
- #endif // USE_BRIGHT_CONTROL
- /* Interrupt from RTC */
- MCUCR = _BV(ISC11); // falling edge
- GICR = _BV(INT1);
- #ifdef USE_UART
- /* USART */
- // Turn on USART hardware (no RX, TX)
- UCSRB |= (0 << RXEN) | (1 << TXEN);
- // 8 bit char sizes
- UCSRC |= (1 << UCSZ0) | (1 << UCSZ1);
- // Set baud rate
- UBRRH = (BAUD_PRESCALE >> 8);
- UBRRL = BAUD_PRESCALE;
- #endif // USE_UART
- /* Enable Interrupts */
- sei();
- }
- /**
- * @brief Correct current time for Sun or Winter
- */
- static void setSummerWinterTime(void) {
- uint8_t sunTime = eeprom_read_byte(&EEP_SummerTime);
- /* Переход на летнее время */
- if ((RTC.Mon == 3) && (RTC.WD == 7) && (RTC.Hr == 3) && (sunTime != 0)) {
- if ((RTC.Day + 7) > 31) {
- RTC.Hr = 4;
- RTC_WriteHH(&RTC);
- sunTime = 0;
- eeprom_update_byte(&EEP_SummerTime, sunTime);
- }
- }
- /* Переход на зимнее время */
- if ((RTC.Mon == 10) && (RTC.WD == 7) && (RTC.Hr == 4) && (sunTime == 0)) {
- if ((RTC.Day + 7) > 31) {
- RTC.Hr = 3;
- RTC_WriteHH(&RTC);
- sunTime = 1;
- eeprom_update_byte(&EEP_SummerTime, sunTime);
- }
- }
- }
- void dotOn(void) {
- PORTD |= DOT_PIN;
- }
- void dotOff(void) {
- PORTD &= ~(DOT_PIN);
- }
- void dotOnPersistent(void) {
- RTOS_DeleteTask(dotOff);
- dotOn();
- }
- /**
- * @brief Обработка кнопок.
- * @param : None
- * @retval : None
- */
- static void btnProcess(void) {
- uint8_t i;
- for (i=0; i<BTN_NUM; i++) {
- if (Button[i].pin != 0) {
- // button pressed
- if (BUTTON_STATE(Button[i].pin) == 0) {
- Button[i].time ++;
- if (Button[i].time >= BTN_TIME_HOLDED) {
- Button[i].time -= BTN_TIME_REPEATED;
- if (Button[i].holded == Button[i].pressed) {
- // if pressed and holded - same function, then button pressed auto repeat
- ES_PlaceEvent(Button[i].pressed);
- }
- }
- } else {
- // button released
- if (Button[i].time >= (BTN_TIME_HOLDED - BTN_TIME_REPEATED)) {
- ES_PlaceEvent(Button[i].holded); // process long press
- } else if (Button[i].time >= BTN_TIME_PRESSED) {
- ES_PlaceEvent(Button[i].pressed); // process short press
- }
- Button[i].time = 0;
- RTOS_SetTask(btnProcess, BTN_TIME_PAUSE, BTN_SCAN_PERIOD);
- }
- } /* end (pin == 0) */
- } /* end FOR */
- }
- void showTime(void) {
- /*
- Digit[0] = DIGIT_BLANK;
- Digit[1] = DIGIT_BLANK;
- Digit[2] = DIGIT_BLANK;
- Digit[3] = resultADC / 100;
- Digit[4] = (resultADC % 100) / 10;
- Digit[5] = resultADC % 10;
- */
- dotOn();
- RTOS_SetTask(dotOff, 500, 0);
- if (RTC.Hr > 0x09) {
- Digit[0] = RTC.Hr >> 4;
- } else {
- Digit[0] = DIGIT_BLANK;
- }
- Digit[1] = RTC.Hr & 0x0F;
- Digit[2] = RTC.Min >> 4;
- Digit[3] = RTC.Min & 0x0F;
- Digit[4] = RTC.Sec >> 4;
- Digit[5] = RTC.Sec & 0x0F;
- }
- void showWDM(void) {
- DISP_WDT = DISP_WDT_TIME;
- Digit[0] = RTC.WD & 0x0F;
- Digit[1] = DIGIT_BLANK;
- Digit[2] = RTC.Day >> 4;
- Digit[3] = RTC.Day & 0x0F;
- Digit[4] = RTC.Mon >> 4;
- Digit[5] = RTC.Mon & 0x0F;
- }
- void showYear(void) {
- DISP_WDT = DISP_WDT_TIME;
- Digit[0] = DIGIT_BLANK;
- Digit[1] = DIGIT_BLANK;
- Digit[2] = 0x02;
- Digit[3] = 0x00;
- Digit[4] = RTC.Year >> 4;
- Digit[5] = RTC.Year & 0x0F;
- }
- #ifdef USE_BRIGHT_CONTROL
- void showBright(void) {
- DISP_WDT = DISP_WDT_TIME;
- Digit[0] = DIGIT_BLANK;
- Digit[1] = DIGIT_BLANK;
- Digit[2] = DIGIT_BLANK;
- Digit[3] = brightIdx;
- Digit[4] = DIGIT_BLANK;
- Digit[5] = DIGIT_BLANK;
- }
- void incBright(void) {
- if (brightIdx < BRIGHT_IDX_MAX) {
- brightIdx ++;
- OCR2 = pgm_read_byte(&brightConv[brightIdx]);
- Flag.saveEEP = 1;
- }
- }
- void decBright(void) {
- if (brightIdx > 0 ) {
- brightIdx --;
- OCR2 = pgm_read_byte(&brightConv[brightIdx]);
- Flag.saveEEP = 1;
- }
- }
- /*
- static void startADC(void) {
- // enable interrupt and start conversion
- ADCSRA |= ((1<<ADSC) | (1<<ADIE));
- }*/
- #endif // USE_BRIGHT_CONTROL
- static void blink(void) {
- static uint8_t s = 0;
- switch (s) {
- case 0:
- Flag.blinkC = 0;
- RTOS_SetTask(blink, 750, 0);
- s = 1;
- break;
- case 1:
- Flag.blinkC = 1;
- RTOS_SetTask(blink, 250, 0);
- s = 0;
- break;
- default:
- s = 0;
- }
- }
- void setTimeShow(void) {
- DISP_WDT = DISP_WDT_TIME;
- dotOnPersistent();
- RTOS_SetTask(dotOff, 500, 0);
- Digit[0] = setRTC.Hr >> 4;
- Digit[1] = setRTC.Hr & 0x0F;
- Digit[2] = setRTC.Min >> 4;
- Digit[3] = setRTC.Min & 0x0F;
- Digit[4] = 0x0;
- Digit[5] = 0x0;
- }
- void setTimeBegin(void) {
- RTC_ReadTime(&setRTC);
- RTOS_SetTask(btnProcess, 500, BTN_SCAN_PERIOD);
- }
- void setHHBegin(void) {
- Flag.blink0 = 1;
- Flag.blink1 = 0;
- Flag.blink2 = 0;
- RTOS_SetTask(blink, 0, 0);
- setTimeShow();
- }
- void setHHInc(void) {
- valIncrease(&setRTC.Hr, 23);
- }
- void setHHDec(void) {
- valDecrease(&setRTC.Hr, 23);
- }
- void setMMBegin(void) {
- Flag.blink0 = 0;
- Flag.blink1 = 1;
- Flag.blink2 = 0;
- RTOS_SetTask(blink, 0, 0);
- setTimeShow();
- }
- void setMMInc(void) {
- valIncrease(&setRTC.Min, 59);
- }
- void setMMDec(void) {
- valDecrease(&setRTC.Min, 59);
- }
- void setTimeEnd(void) {
- RTOS_SetTask(btnProcess, 500, BTN_SCAN_PERIOD);
- setRTC.Sec = 0;
- RTC_WriteTime(&setRTC);
- RTOS_DeleteTask(blink);
- Flag.blink0 = 0;
- Flag.blink1 = 0;
- Flag.blink2 = 0;
- Flag.blinkC = 0;
- RTC_ReadTime(&RTC);
- }
- /**
- * Setup Calendar functions
- */
- void setDateBegin(void) {
- RTC_ReadCalendar(&setRTC);
- RTOS_SetTask(btnProcess, 500, BTN_SCAN_PERIOD);
- }
- void setDateEnd(void) {
- RTOS_SetTask(btnProcess, 500, BTN_SCAN_PERIOD);
- RTC_WriteCalendar(&setRTC);
- Flag.blink0 = 0;
- Flag.blink1 = 0;
- Flag.blink2 = 0;
- Flag.blinkC = 0;
- RTC_ReadCalendar(&RTC);
- dotOff();
- }
- void setWDMShow(void) {
- DISP_WDT = DISP_WDT_TIME;
- dotOnPersistent();
- Digit[0] = setRTC.WD & 0x0F;
- Digit[1] = DIGIT_BLANK;
- Digit[2] = setRTC.Day >> 4;
- Digit[3] = setRTC.Day & 0x0F;
- Digit[4] = setRTC.Mon >> 4;
- Digit[5] = setRTC.Mon & 0x0F;
- }
- void setYearShow(void) {
- DISP_WDT = DISP_WDT_TIME;
- dotOff();
- Digit[0] = DIGIT_BLANK;
- Digit[1] = DIGIT_BLANK;
- Digit[2] = 0x02;
- Digit[3] = 0x00;
- Digit[4] = setRTC.Year >> 4;
- Digit[5] = setRTC.Year & 0x0F;
- }
- void setWDayBegin(void) {
- Flag.blink0 = 1;
- Flag.blink1 = 0;
- Flag.blink2 = 0;
- RTOS_SetTask(blink, 0, 0);
- setWDMShow();
- }
- void setMDayBegin(void) {
- Flag.blink0 = 0;
- Flag.blink1 = 1;
- Flag.blink2 = 0;
- RTOS_SetTask(blink, 0, 0);
- setWDMShow();
- }
- void setMonthBegin(void) {
- Flag.blink0 = 0;
- Flag.blink1 = 0;
- Flag.blink2 = 1;
- RTOS_SetTask(blink, 0, 0);
- setWDMShow();
- }
- void setYearBegin(void) {
- Flag.blink0 = 0;
- Flag.blink1 = 0;
- Flag.blink2 = 1;
- RTOS_SetTask(blink, 0, 0);
- setYearShow();
- }
- void setIncWDay(void) {
- if (setRTC.WD < 7) {
- setRTC.WD ++;
- } else {
- setRTC.WD = 1;
- }
- }
- void setDecWDay(void) {
- if (setRTC.WD > 1) {
- setRTC.WD --;
- } else {
- setRTC.WD = 7;
- }
- }
- void setIncMDay(void) {
- valIncrease(&setRTC.Day, 31);
- if (setRTC.Day == 0) {
- setRTC.Day = 1;
- }
- }
- void setDecMDay(void) {
- valDecrease(&setRTC.Day, 31);
- if (setRTC.Day == 0) {
- setRTC.Day = 0x31;
- }
- }
- void setIncMonth(void) {
- valIncrease(&setRTC.Mon, 12);
- if (setRTC.Mon == 0) {
- setRTC.Mon = 1;
- }
- }
- void setDecMonth(void) {
- valDecrease(&setRTC.Mon, 12);
- if (setRTC.Mon == 0) {
- setRTC.Mon = 0x12;
- }
- }
- void setIncYear(void) {
- valIncrease(&setRTC.Year, 99);
- }
- void setDecYear(void) {
- valDecrease(&setRTC.Year, 99);
- }
- /**
- * @brief Increase BCD value.
- * @param : val, max
- * @retval : None
- */
- static void valIncrease(uint8_t * val, uint8_t max) {
- uint8_t bin = 10 * (*val >> 4) + (*val & 0x0f);
- if (bin < max) {
- bin ++;
- } else {
- bin = 0;
- }
- *val = ((bin / 10 ) << 4) | (bin % 10);
- }
- /**
- * @brief Decrease BCD value.
- * @param : value, max
- * @retval : None
- */
- static void valDecrease(uint8_t * val, uint8_t max) {
- uint8_t bin = 10 * (*val >> 4) + (*val & 0x0f);
- if (bin > 0) {
- bin --;
- } else {
- bin = max;
- }
- *val = ((bin / 10 ) << 4) | (bin % 10);
- }
- #ifdef USE_UART
- void usart_putc (char send) {
- // Do nothing for a bit if there is already
- // data waiting in the hardware to be sent
- while ((UCSRA & (1 << UDRE)) == 0) {};
- UDR = send;
- }
- void usart_puts (const char *send) {
- // Cycle through each character individually
- while (*send) {
- usart_putc(*send++);
- }
- }
- #endif // USE_UART
- #ifdef LAMP_TEST
- /**
- * Lamp Test
- */
- static void lampValInc(uint8_t n)
- {
- if (Digit[n] != DIGIT_BLANK) {
- Digit[n] ++;
- } else {
- Digit[n] = 1;
- }
- if (Digit[n] > 9) {
- Digit[n] = 0;
- if (n > 0) {
- lampValInc(n-1);
- }
- }
- }
- static void lampTest(void)
- {
- uint8_t i=0;
- uint8_t k, x;
- dotOn();
- for (k = 0; k<LAMP_NUM; k++) {
- Digit[k] = DIGIT_BLANK;
- }
- while (true) {
- Digit[LAMP_NUM-1] = i;
- i ++;
- if (i > 9) {
- dotOn();
- i = 0;
- lampValInc(LAMP_NUM-2);
- }
- tdelay_ms(10);
- if (i == 5) {
- dotOff();
- }
- x = 1;
- for (k = 0; k<LAMP_NUM; k++) {
- if (Digit[k] == 9) {
- x ++;
- }
- }
- if (x == LAMP_NUM) {
- tdelay_ms(2000);
- break;
- }
- }
- }
- #endif // LAMP_TEST
- /**
- * П р е р ы в а н и я
- */
- /**
- * @brief RTC one seconds interrupt
- */
- ISR (INT1_vect) {
- Flag.RTC_Int = 1;
- }
- /**
- * @brief Refresh Nixie output
- * @note Digit[] must be in range 0x00 - 0x0F
- */
- #pragma GCC optimize ("O3")
- ISR(TIMER2_OVF_vect) {
- static uint8_t idx = 0;
- // reload timer
- TCNT2 = TIMER2_CNT;
- // read current register value and clean bits
- uint8_t pb = PORTB & ~ANODB_PINS;
- uint8_t pd = PORTD & ~ANODD_PINS;
- uint8_t pc = PORTC & ~DIGIT_PINS;
- #ifndef USE_BRIGHT_CONTROL
- // power off lamps
- PORTB = pb;
- PORTD = pd;
- PORTC = pc;
- #endif
- switch (idx) {
- case 0:
- // output lamp value
- PORTC = pc | Digit[0];
- // power on lamp
- if (Digit[0] != DIGIT_BLANK) {
- if (Flag.blink0 == 0 || Flag.blinkC == 0) {
- PORTD = pd | ANOD1;
- }
- }
- idx = 1;
- break;
- case 1:
- PORTC = pc | Digit[1];
- if (Digit[1] != DIGIT_BLANK) {
- if (Flag.blink0 == 0 || Flag.blinkC == 0) {
- PORTD = pd | ANOD2;
- }
- }
- idx = 2;
- break;
- case 2:
- PORTC = pc | Digit[2];
- if (Digit[2] != DIGIT_BLANK) {
- if (Flag.blink1 == 0 || Flag.blinkC == 0) {
- PORTD = pd | ANOD3;
- }
- }
- idx = 3;
- break;
- case 3:
- PORTC = pc | Digit[3];
- if (Digit[3] != DIGIT_BLANK) {
- if (Flag.blink1 == 0 || Flag.blinkC == 0) {
- PORTB = pb | ANOD4;
- }
- }
- idx = 4;
- break;
- case 4:
- PORTC = pc | Digit[4];
- if (Digit[4] != DIGIT_BLANK) {
- if (Flag.blink2 == 0 || Flag.blinkC == 0) {
- PORTB = pb | ANOD5;
- }
- }
- idx = 5;
- break;
- case 5:
- PORTC = pc | Digit[5];
- if (Digit[5] != DIGIT_BLANK) {
- if (Flag.blink2 == 0 || Flag.blinkC == 0) {
- PORTB = pb | ANOD6;
- }
- }
- idx = 0;
- break;
- default:
- idx = 0;
- break;
- }
- }
- #ifdef USE_BRIGHT_CONTROL
- /**
- * @brief Power Off Nixie output
- * @note For Brightnes dimming
- */
- #pragma GCC optimize ("O3")
- ISR(TIMER2_COMP_vect) {
- // power off lamps
- PORTB &= ~ANODB_PINS;
- PORTD &= ~ANODD_PINS;
- PORTC &= ~DIGIT_PINS;
- }
- /*
- ISR(ADC_vect) {
- resultADC = ADCH;
- ADCSRA &= ~(1<<ADIE); // disable interrupt
- }*/
- #endif // USE_BRIGHT_CONTROL
- /**
- * @brief заглушка для неиспользуемых прерываний
- */
- ISR(__vector_default,ISR_NAKED) {
- reti();
- }
|