//______________________________________________________________________
void main(void) {

    //____________ menu attribute TTTDDCCC,
    //             TTT toggle option offset/2
    //             DD  digit setup pos,
    static const uint8_t menu_attrs[] = { 0x00,
                                          (3<<2)|(1),	// time
                                          (4<<2)|(1),	// alarm
                                          (0<<2)|(1),	// count down
                                          (4<<2)|(2),	// auto sleep
#ifdef TEMP_SENSE
                                          (5<<2)|(3),	// dimmer, shorted
#else
                                          (0<<2)|(3),	// dimmer, shorted
#endif
                                        };

    WDTCTL = WDTPW + WDTHOLD + WDTNMI + WDTNMIES;	// stop WDT, enable NMI hi/lo

    BCSCTL1 = CALBC1_1MHZ;		// Set DCO to 1MHz
    DCOCTL = CALDCO_1MHZ;

    //____________________ 1mhz clock base
    CCTL0 = CCIE;                             // CCR0 interrupt enabled
    CCR0 = 62500;
    TACTL = TASSEL_2 + MC_2 + TAIE;                  // SMCLK, continous
    _BIS_SR(GIE);

    // 0x1000 0x10ff infomem
#ifdef TEMP_SENSE
    //________ temperature sensing setup G2231 only
    ADC10CTL1 = INCH_10 + ADC10DIV_3;         // Temp Sensor ADC10CLK/4
    ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
#endif


#ifdef TONE
    uint8_t const *mode5 = (uint8_t *) 0;
#endif
    uint16_t mode4 = 0;
    uint16_t *show = 0;
    uint8_t sec=45;

    P1SEL = 0;
    P2SEL = 0;

    uint8_t menu=1;
    uint8_t mode=1;
    uint8_t state=ST_HOLD;
    uint8_t setup=4;
    uint8_t sec2sleep=0;

    while (1) {
        if (!menu && stacked) {
            while (stacked) {
                stacked--;
                if (++sec >= 60) {
                    sec = 0;
                    time[1]++;
                    //________ alarm ?
                    if (__is_alarm_on && time[1] == time[2]) {
                        state |= (ST_BUZZ|ST_REFRESH);
                        state &= ~ST_BUTTON;
                        mode = 1;
                    }//if
                }//if
            }//while
            if (__is_autosleep && mode && mode <= 3) {
                if (sec2sleep) {
                    sec2sleep--;
                    if (!sec2sleep) mode = 0;
                }//if
            }//if
            if ((mode != 1) || !sec) state |= ST_REFRESH;
        }//if

        uint8_t adv = 0;
        uint8_t txt = 0;
        //_____________________________________ check input
        if (state & ST_BUTTON) {	// needs attention
            if (__is_autosleep) sec2sleep = time[4];
            if ((state & ST_BUZZ) || !mode) {	// stop alarm
                state &= ~(ST_BUZZ|ST_BUTTON);
                mode = 1;
                state |= ST_REFRESH;
                continue;
            }//if

            if (setup) {
                if (state & ST_HOLD) {
                    switch (setup) {
                    case 3:
                        menu_attr >>= 2;
                        if (menu_attr) {
                            //______ on to options toggle
                            state |= ST_PRESSED;
                            setup++;
                            break;
                        }//if
                    case 4:
                        switch (menu) {
                        case 3:
                            mode4 = *show;
                            mode = 4;
                            break;
                        default:
                            mode = 1;
                            break;
                        }//switch
                        show = time + 1;
                        menu = 0;
                        setup = 0;
                        break;
                    default:
                        setup++;
                        break;
                    }//switch
                }//if
                if (state & ST_PRESSED) {
                    if (setup == 4) {
                        if (!(state & ST_HOLD))
                            *time ^= 1<<menu;
                        txt = (menu_attr<<1) + ((*time & 1<<menu) ? 1 : 0);
                    }//if
                    else {
                        adv = setup;
                    }//else
                }//if
            }//if
            else {
                if (state & ST_HOLD) {
                    //_______ advance menu
                    if (mode) {
                        //_________ not option, not edit, advance menu
                        menu++;
                        //___________ detect option conditions
                        //while ((menu_attrs[menu]&0x07) && opts&(1<<(menu_attrs[menu]&0x07))) menu++;
                        //while (opts & (1<<4) && ((menu == 2) || (menu == 3))) menu++;
                        while ((opts&BUZZ_PINP) && (menu&0x02)) menu++;
                        if (menu > 5)
                            menu = 0;
                        else
                            txt = menu;
                        menu_attr = menu_attrs[menu];
                        mode = 1;
                    }//if
                }//if
                else {
                    if (menu) {
                        //_______ menu selected
                        //mode = 1;
                        show = time + menu;
                        setup = menu_attr & 0x03;
                    }//if
                    else {
                        //_______ advance display mode
                        mode++;
                        mode &= 0x03;
                        stays = 0;
                    }//else
                }//else
            }//else
        }//if

        if (state&(ST_REFRESH|ST_BUTTON) && !stays) {
            state &= ~(ST_REFRESH|ST_BUTTON);
            if (txt) {
                seg2port(menu_desc[txt], 0x20);
            }//if
            else {
                switch (mode) {
                case 1:		// hour + min
                    if (adv == 1) {
                        *show += 60;
                        adv = 0;
                    }//if
                    while (*show>=(24*60)) *show -= 24*60;
                    *show = seg2port(*show, adv);
                    if (!__is_24hr && menu < 3) {	// 12HR display
                        uint16_t hhmm = *show;
                        if (hhmm>=(12*60)) {
                            //__________ 12Hr mode, pm indicator
                            adv = 1;
                            hhmm -= 12*60;
                        }//if
                        if (hhmm<60) hhmm += 12*60;
                        seg2port(hhmm, 0);
                    }//if
                    break;
                case 2:		// alarm on/off + seconds
                    //seg2port(sec+(POS__*100) + (__is_alarm_on ? POSb1*1600 : 0), 0x10);
                    seg2port(sec, 0);
                    if (__is_alarm_on) adv = 1;
                    break;
#ifdef TEMP_SENSE
                case 3:
                {   // temperature
                    int16_t temp = ADC10MEM;
                    if (temp) {
                        // oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468
                        // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
                        //temp = ((temp - 630) * 761) / 1024; oF
                        //temp = ((temp - 673) * 423) / 1024; C   0 offset
                        //temp = ((temp - 552) * 423) / 1024; C -50 offset
                        // 1.464mv/u 3.55
                        temp = ((temp - 673) * 423) / 1024;
                        if (__is_fahrenheit) temp = (temp * 10 / 8) + 32;
                        temp <<= 4;
                        //
                        if (temp < 0) {
                            temp = -temp;
                            temp += POSb2 * 1600;
                        }//if
                        seg2port(temp|(__is_fahrenheit?POS_f:POS_C), 0x10);

                    }//if
                    ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
                    __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
                }
                break;
#endif
                case 0:			// blank
                    //
                    //_BIS_SR(LPM3_bits + GIE);	// sleep
                    while (ticks%4);// asm("nop");		// sync to 1/4 sec ticks
                    stacked += sec;
                    sec = 0;		// sync to minute for alarm checking
                    //P1DIR = P1OUT = 0;
                    //P2DIR = P2OUT = 0;

                    P1REN = BUTTON_PIN;
                    P1IES &= ~BUTTON_PIN;	// low-high trigger
                    P1IFG &= ~BUTTON_PIN;	// clear
                    P1IE = BUTTON_PIN;	// pin interrupt enable

                    BCSCTL3 = XCAP_3;
                    P2SEL = BIT6|BIT7;		// need xtal
                    CCTL0 = 0;		// stop timer a
                    WDTCTL = WDT_ADLY_250 + WDTNMI + WDTNMIES;	// WDT at 250ms, NMI hi/lo
                    IE1 |= WDTIE;                             // Enable WDT interrupt

                    _BIS_SR(LPM3_bits + GIE);	// now i and deep sleep

                    // we wake up here
                    P1IFG &= ~BUTTON_PIN;	// clear
                    P1IE = 0;
                    while (P1IN&BUTTON_PIN); 	// make sure key is not depressed
                    state |= ST_PRESSED;

                    IE1 &= ~WDTIE;		// Diable WDT interrupt
                    WDTCTL = WDTPW + WDTHOLD + WDTNMI + WDTNMIES;
                    CCTL0 = CCIE;		// CCR0 interrupt enabled, time keep w/ DCO from now on
                    P2SEL = 0;			// turn xtal pins back to gio for led multiplexing
                    //
#ifndef TEMP_SENSE
                case 3:			// no temperature sensor
                    state |= ST_PRESSED;
                    break;
#endif
                case 5:			// blank
                    state |= ST_REFRESH;
                    break;
                case 4:		// counter
                    seg2port(mode4, 0);
                    if (mode4) mode4--;
                    else	   state |= ST_BUZZ;
                default:
                    break;
                }//switch
                if (adv) *(output + (3*3+1)) |= SEG_d_P1;
            }//else
        }//if


        //
        if (state & ST_BUZZ) {
            if (ticks & 0x04) {
                P1DIR  = 0x00;
                P2DIR  = BUZZ_PINP|BUZZ_PINN;
                P2OUT ^= BUZZ_PINP; 	// toggle buzzer
            }//if
        }//if
        //
        //
        if (stays & 0x0f) {
            stays--;
            continue;
        }

        // dimmer
        stays >>= time[5]%10;
        //
        P2DIR = 0;
        P1DIR = 0;
        P2OUT = 0;
        P1OUT = 0;
        //

        if (stays) {
            stays--;
            continue;
        }
        //
        //if (mode == 5) continue;

#ifdef TONE

        if (mode) {
            P2DIR  = BUZZ_PINN;
            P2OUT  = BUZZ_PINP;
            P2REN |= BUZZ_PINP;

            if ((opts&BUZZ_PINP) && !(P2IN&BUZZ_PINP)) {
                //______ user attach buzzer, show menu, may be he wants to setup alarm
                menu = 1;
                state |= ST_HOLD;
            }//if
            opts = P2IN;
            P2REN = 0;
            P2DIR = 0;
            P2OUT = 0;

            P1DIR  = CNTR_PINN;
            P1OUT  = CNTR_PINP;
            P1REN |= CNTR_PINP;

            opts |= P1IN;

            //opts = CNTR_PINP|BUZZ_PINP;
            //opts = CNTR_PINP;
            //
            if (!(opts & CNTR_PINP)) {			// tune player buzzer present
                mode5 = tune;
                P1DIR  = CNTR_PINN;
                P1OUT  = CNTR_PINP;
                P1REN |= CNTR_PINP;
                while (!(P1IN&CNTR_PINP)) {
                    if (!*mode5) mode5 = tune;	// point to 1st note
                    _ccr1 = 0;
                    ticks &= 0x0f;
                    uint8_t wait = ticks + ((*mode5&0x03)<<2);
                    uint8_t i = *mode5>>2;
                    uint8_t const *v = tune_map;
                    while (i) {					// set note frequency
                        //CCR1 += *v>>4;
                        _ccr1 += *v>>4;
                        if (!(--i)) break;
                        //CCR1 += *v&0x0f;
                        _ccr1 += *v&0x0f;
                        v++;
                        i--;
                    }//while
                    //CCR1 <<= 3;
                    CCR1 = _ccr1;
                    if (_ccr1) {
                        CCTL1 = OUTMOD_4|CCIE;
                        P1DIR = CNTR_PINP|CNTR_PINN;
                        P1SEL = CNTR_PINP;
                    }//if
                    P1OUT = 0;
                    P1REN = 0;
                    while (ticks<wait);	//	__asm("nop");			// wait note duration
                    CCTL1 = 0x00;
                    P1SEL = 0x00;
                    mode5++;
                    P1DIR  = CNTR_PINN;
                    P1OUT  = CNTR_PINP;
                    P1REN |= CNTR_PINP;
                }//while
            }//if
            P1REN = 0;
            P1DIR = 0;
            P1OUT = 0;
        }//if
Exemple #2
0
//______________________________________________________________________
void main(void) {

	//____________ menu attribute TTTDD,
	//             TTT toggle option offset/2
	//             DD  digit setup pos,
	static const uint8_t menu_attrs[] = { 0x00,
		(3<<2)|(1),	// time
		(4<<2)|(1),	// alarm
		(0<<2)|(1),	// count down
#ifdef NO_TEMP_CHOICE
		(0<<2)|(2),	// clock gain, no choice for temp units C/F
#else
		(5<<2)|(2),	// clock gain
#endif
		(0<<2)|(3),	// dimmer, shorted
	};

	WDTCTL = WDTPW + WDTHOLD + WDTNMI + WDTNMIES;	// stop WDT, enable NMI hi/lo

	uint8_t use_32khz = 1;		// assume we have crystal 1st

	BCSCTL1 = CALBC1_1MHZ;		// Set DCO to 1MHz
	DCOCTL = CALDCO_1MHZ;
	FCTL2 = FWKEY + FSSEL0 + FN1;	// MCLK/3 for Flash Timing Generator

	CCR0 = 4096-1;
	CCTL0 = CCIE;					// CCR0 interrupt enabled
	TACTL = TASSEL__ACLK + MC__UP + TACLR;	// ACLK, upmode
	WDTCTL = WDT_MDLY_8 + WDTNMI + WDTNMIES;	// WDT at 8ms, NMI hi/lo

	while (!tps) {
		IE1 |= WDTIE;					// Enable WDT interrupt
		_BIS_SR(GIE);					// enable interrupt

		// wait for VLO calibration be done
		// timer interrupt to reduce rounds from 122 to 0
		while (rounds);

		if (tps) break;					// works, must have 32khz crystal
		//______ couldn't get tps, now fallback to use VLO
    //BCSCTL3 |= LFXT1S_2;			// use VLO as ACLK, ~12Khz В оригинале было раскоментировано
    //CCR0 = 64-1;  // В оригинале было раскоментировано
		//_______ VLO calibration,
		// WDT counts 122x8ms (on 1 Mhz MCLK) times and see how many ACLK counts per sec
		// now we got tps as ACLK/64 counts in one sec
		// for 1/8 sec per interrupt we will need to set CCR0 to tps * 8
		// next round up to calibrate VLO
    // use_32khz = 0;  // В оригинале было раскоментировано
	}//while


	// save ticks per second value for later setting
	uint8_t use_tps = tps;

	uint16_t time[6];
	char *flash = (char*) 0x1040;
	char *src   = (char*) time;
	uint8_t i=0;

	// read configuration from flash
	for (i=0;i<12;i++) {
		if (*flash != 0xff) *src = *flash;
		src++;
		flash++;
	}//for

	//________ temperature sensing setup G2231 only
	ADC10CTL1 = INCH_10 + ADC10DIV_3;         // Temp Sensor ADC10CLK/4
	ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;

	uint16_t mode4 = 10; // Было 0

	uint16_t *show;
	uint8_t sec=45;

	P1SEL = 0;
	P2SEL = (1<<6)|(1<<7);		// will use crystal


	uint8_t menu=1;
	uint8_t mode=4;    // Было 1
	uint8_t state=ST_PRESSED;  // Было ST_HOLD
	uint8_t setup=0;  // Было 4

	// ******** Начало главного цикла ****
	while (1) {

		if (!menu && stacked) {
			while (stacked) {
				stacked--;
				// stacked - число непосчитанных секунд накопленных от прерывания кварца
				// здесь обнуляется, превращаясь в секунды и минуты.
				if (++sec >= 60) {
					sec = 0;
					time[1]++;
					//________ alarm ?
					if ((*time & (1<<2)) && time[1] == time[2]) {
						state |= (ST_BUZZ|ST_REFRESH);
						mode = 1;
					}//if
				}//if
			}//while
			if ((mode != 1) || !sec) state |= ST_REFRESH;
#ifdef DEVICE_20P
			*(output + (1*3+1)) &= ~SEG_d_P1;
			if (use_32khz)
			if ((mode==1) && (sec&0x01)) *(output + (1*3+1)) |= SEG_d_P1;
#endif
		}//if

		uint8_t adv = 0;
		uint8_t txt = 0;
		//_____________________________________ check input
		if (state & ST_BUTTON) {	// needs attention
			if ((state & ST_BUZZ) || !mode) {	// stop alarm
				state &= ~(ST_BUZZ|ST_BUTTON);
				mode = 1;
				state |= ST_REFRESH;
				continue;
			}//if
            // Режим настройки
			if (setup) {
				if (state & ST_HOLD) {
					// Меню настройки
					switch (setup) {
						case 3:
							menu_attr >>= 2;
							if (menu_attr) {
								//______ on to options toggle
								state |= ST_PRESSED;
								setup++;
								break;
							}//if
						case 4:
							{
							//___________ done, flash
							char *flash = (char*) 0x1040;
							char *src   = (char*) time;
							FCTL1 = FWKEY + ERASE;
							FCTL3 = FWKEY;
							*flash = 0x0000;
							FCTL1 = FWKEY + WRT;
							for (i=0;i<12;i++) *flash++ = *src++;
							FCTL1 = FWKEY;
							FCTL3 = FWKEY + LOCK;
							//_________ load fresh parameters
							// you can save a lot by omitting boundary checks
							//time[4] %= 100;
							//time[5] %= 10;
							time[4] &= 0x003f;
							time[5] &= 0x0007;
							if (!use_32khz)
                            CCR0 = (use_tps-time[4])*8;
							CCTL0 = CCIE;					// CCR0 interrupt enabled
							TACTL = TASSEL__ACLK + MC__UP + TACLR;	// ACLK, upmode
							switch (menu) {
								case 3:
									mode4 = *show;
									mode = 4;
									break;
								default:
									mode = 1;
									break;
							}//switch
							show = time + 1;
							menu = 0;
							setup = 0;
							break;
							}
						default:
							setup++;
							break;
					}//switch
				}//if
				if (state & ST_PRESSED) {
					if (setup == 4) {
						if (!(state & ST_HOLD))
							*time ^= 1<<menu;
						txt = (menu_attr<<1) + ((*time & 1<<menu) ? 1 : 0);
					}//if
					else {
						adv = setup;
					}//else
				}//if
			}//if
			else {
				if (state & ST_PRESSED) {
					if (menu) {
						//_______ menu selected
						//mode = 1;
						show = time + menu;
						setup = menu_attr & 0x03;
					}//if
					else {
						//_______ advance display mode
						mode++;
						mode &= 0x03;
						seg2port(menu_desc[0], 0x20);
						stays = 0;
					}//else
				}//if
				else {
					//_______ advance menu
					if (mode) {
						//_________ not option, not edit, advance menu
						menu++;
//___________ see if we need alarm function (buzzer attached?)
						//while (opts & (1<<2) && (menu & 0x02)) menu++;
						if (menu > 5)
							menu = 0;
						else
							txt = menu;
						menu_attr = menu_attrs[menu];
						mode = 1;
					}//if
				}//else
			}//else
		}//if

		if (state&(ST_REFRESH|ST_BUTTON) && !stays) {
			state &= ~(ST_REFRESH|ST_BUTTON);
			if (txt) {
				seg2port(menu_desc[txt], 0x20);
			}//if
			else {
				if (adv == 1) {
					*show += 60;
					adv = 0;
				}//if
				if (*show>=(24*60)) *show -= 24*60;
				switch (mode) {
					case 1:		// hour + min
						*show = seg2port(*show, adv);
						if (!(*time & (1<<1)) && menu < 3) {	// 12HR display
							uint16_t hhmm = *show;
							if (hhmm>=(12*60)) {
								//__________ 12Hr mode, pm indicator
								adv = 1;
								hhmm -= 12*60;
							}//if
							if (hhmm<60) hhmm += 12*60;
							seg2port(hhmm, 0);
						}//if
						break;
					case 2:		// alarm on/off + seconds
						//seg2port(sec+(POS__*100) + ((*time & (1<<2)) ? POSb1*1600 : 0), 0x10);
						seg2port(sec, 0);
						if (*time & (1<<2)) adv = 1;
						break;
					case 3:
						{ // temperature
						int16_t temp = ADC10MEM;
						if (temp) {
							// oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468
							// oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
							//temp = ((temp - 630) * 761) / 1024; oF
							//temp = ((temp - 673) * 423) / 1024; C   0 offset
							//temp = ((temp - 552) * 423) / 1024; C -50 offset
							// 1.464mv/u 3.55
#ifdef NO_TEMP_CHOICE
							temp = ((temp - 673) * 423) / 1024;
#ifndef METRIC_TEMP
							temp = (temp * 10 / 8) + 32;
#endif
							temp <<= 4;
#ifdef METRIC_TEMP
							if (temp < 0) {
								temp = -temp;
								temp += POSb2 * 1600;
							}//if
#endif
#else
							temp = ((temp - 673) * 423) / 1024;
							if (*time & (1<<4))		// imperial temperature
								temp = (temp * 10 / 8) + 32;
							temp <<= 4;
							//
							if (temp < 0) {
								temp = -temp;
								temp += POSb2 * 1600;
							}//if
#endif

#ifdef NO_TEMP_CHOICE
#ifdef METRIC_TEMP
							seg2port(temp|POS_C, 0x10);
#else
							seg2port(temp|POS_f, 0x10);
#endif
#else
							seg2port(temp|((*time & (1<<4))?POS_f:POS_C), 0x10);
#endif
						}//if
						ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
						__bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
						}
						break;
					case 0:			// blank
						_BIS_SR(LPM3_bits + GIE);	// sleep
					case 5:			// blank
						state |= ST_REFRESH;
						break;
					case 4:		// counter
						seg2port(mode4, 0);
						if (mode4) mode4--;
						else	   state |= ST_BUZZ;
					default:
						break;
				}//switch
				if (adv) *(output + (3*3+1)) |= SEG_d_P1;
			}//else
		}//if

		if (state & ST_BUZZ) {
			if (ticks & 0x02) {
				P2DIR  = _P2DIR;
				P1DIR  = BUZZ_PINP|BUZZ_PINN;
				P1OUT ^= BUZZ_PINP; 	// toggle buzzer
			}//if
		}//if

		// allow led segments stays on
		if (stays & 0x0f) { stays--; continue; }

		// time[5] contains dimmer value
		stays >>= time[5];
		// turn off all io pins, led blanks
		P2DIR = _P2DIR;
		P1DIR = 0;
		P2OUT = 0;
		P1OUT = 0;

		// allow led segments stays blank out, dimming
		if (stays) { stays--; continue; }

		P1REN = BTNP_P1;
		if (mode) {
			//____________ only if we are not asleep
			P1DIR = BUZZ_PINN;
			P1OUT = BUZZ_PINP;
			P1REN |= BUZZ_PINP;

//------------- ОПРЕДЕЛЕНИЕ, ПОДКЛЮЧЕН ЛИ ДИНАМИК и переключение на меню !!!!
			/* if ((opts & BUZZ_PINP) && !(P1IN & BUZZ_PINP)) {
				menu = 1;
				state |= ST_HOLD;

			}*/
//----------------------------------------------------------------------

			// store port 1 pin status
			opts = P1IN;
		}//if

		//___________ check button
		//            button must be position at P1.2 as it's tied to RESET pin
		//            we need it be pressed after power's been applied (boot)
		uint16_t wait=0;
		do {
			if (wait == 0x0040) {
				state |= ST_PRESSED;
			}//if
			else {
				if (wait++ > 0x6000) {
					state &= ~ST_PRESSED;
					state |= ST_HOLD;
					//if (wait&0x0f) P1DIR ^= 0x30;
#ifdef DEVICE_20P
					P2DIR ^= 0x06;
#else
					P1DIR ^= 0x30;
#endif
				}//if
			}//else
			wait++;
		} while (P1IN & BTNP_P1);
		P1REN = 0; //P1DIR = 0; P1OUT = 0;

		if ((state & ST_BUTTON) || !mode) continue;

		static uint8_t pos=0;
		static const uint8_t digit_map1[] = { DIGIT_0_P1, DIGIT_1_P1, DIGIT_2_P1, DIGIT_3_P1, };
		static const uint8_t digit_map2[] = { DIGIT_0_P2, DIGIT_1_P2, DIGIT_2_P2, DIGIT_3_P2, };

		// flasher during individual digit setup
		//___________ load segments and turn on 1 of 4 digits
		//uint8_t setup = state & ST_SETUP;
		uint8_t *ioptr = output + (pos*3);
		if (!setup || !(ticks & 0x02) || (pos != setup && (pos|setup) != 0x01)) {
			// use this (w/ negate) if led is common anode
			//P2OUT = ~(*ioptr & ~digit_map2[pos]);
			P2OUT = *ioptr & ~digit_map2[pos];
			P2DIR = (*ioptr++ | digit_map2[pos]) | _P2DIR;
			// use this (w/ negate) if led is common anode
			//P1OUT = ~(*ioptr & ~digit_map1[pos]);
			P1OUT = *ioptr & ~digit_map1[pos];
			P1DIR = *ioptr++ | digit_map1[pos];
			stays = *ioptr;
		}//if

		pos++;
		pos &= 0x03;

	}//while Конц главного цикла