#include  "msp430g2553.h"

/*  сигналы  */
#define     LED0    BIT0    //p1.0 led0
#define     SW1     BIT3    //p1.3 кнопка 1
#define     secIN   BIT4    //p1.4 вход секунд

/* ходовой шаговик */
#define     M1      BIT0    //p2.0
#define     M2      BIT1    //p2.1
#define     M3      BIT2    //p2.2
#define     M4      BIT3    //p2.3

/* шаговик боя */
#define     B1      BIT1    //p1.1
#define     B2      BIT5    //p1.5
#define     B3      BIT6    //p2.6
#define     B4      BIT7    //p2.7

/* входы энкодера */
#define     ENC1    BIT4    //p2.4 encoder input 1
#define     ENC2    BIT5    //p2.5 encoder input 2
#define     EncMask 0x30


/* разные дефайны */
#define     stepPerMin  14
#define     oddMin      25
#define     oddMinDiff  2
#define     stepDelay   20
#define     stepShift   3
#define     stepBDelay  50

/* FLAGS */
#define     secFlag         BIT0    // событие - пришла секунда
#define     encFlag         BIT1    // событие - подвинулся энкодер
#define     RXed            BIT2    // был прием байта i2c
#define     i2cTX           BIT3    // ждем передачи i2c
#define     bomFlag         BIT4    // не пригодился
#define     SW1ON           BIT5    // событие - изменилось состояние кнопки
#define     SW1Last         BIT6    // последнее состояние кнопки
#define     timeSYN         BIT7    // время в ds3232 синхронизировано с регистрами (после прихода секунды)
#define     bFWDFlag        BIT8    // флаг активности шаговика боя (едем вперёд)
#define     bBWDFlag        BIT9    // флаг активности шаговика боя (едем назад)
#define     trueTime        BITA    // время на стрелках соответствует ds3232
#define     halfBom         BITB    // флаг получасового боя
#define     strikerInitFlag BITC    // флаг парковки шаговика боя


/*  DS3232  RAM   */
#define     stepIndexAddr   0x15
#define     minIndexAddr    0x16
#define     curMinAddr      0x17
#define     curHourAddr     0x18



volatile unsigned char stepArray[16] = {0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};
volatile unsigned char stepArrayB[8] = {0x82,0x80,0xc0,0x40,0x60,0x20,0x22,0x02};

#define     BMask1          0xDD    //маска шаговика боя на порту P1
#define     BMask2          0x3F    //маска шаговика боя на порту P2

// таблица состояний энкодера (для исключения дребезга)
#define encUP   2
#define encDown 1
#define encStay 0
volatile unsigned char encTBL[] = {encStay,encDown,encUP,encStay,encUP,encStay,encStay,encDown,encDown,encStay,encStay,encUP,encStay,encUP,encDown,encStay};

volatile unsigned char i2cBUF, i2cState, stepIndex, minIndex, encLast, SW1cntr, SW1LongCntr, curMin;
volatile unsigned char curHour,stepBIndex,i,bomCnt, rtcMin, rtcHour;
volatile unsigned int  stepsB, FLAGS, encoder, rtcMins, curMins, corrSteps;

/* различные константы шаговика боя */
#define     InitBStepsF     800
#define     InitBStepsB     300
#define     StrikeSteps     576
#define     HalfStrikeSteps 400
#define     StrikeSpeed     5000
#define     HalfStrikeSpeed 1500
#define     beepSpeed       300

void hex2uart(unsigned char byte);
void i2cReadByte(unsigned char addr);
void i2cSendByte(unsigned char addr,unsigned char byte);
float i2cGetTemper(void);
void temper2uart(float);
void initDS3232(void);
void FWDstep(unsigned int steps);
void BWDstep(unsigned int steps);
void delay(unsigned char ms);
void minStepUP(void);
void minStepDOWN(void);
void putChar(unsigned char byte);
void ZeroInit(void);
unsigned int getEnc(void);
void FWDstepB(void);
void BWDstepB(void);
void StrikerInit(void);

/* панЕслась */
void main(void)
{
   /* нинчиализация */
   WDTCTL = WDTPW + WDTHOLD;                  //тормозим WDT
   P1DIR|=LED0;
   P1OUT&=~LED0;

   /* uart */
   BCSCTL1 = CALBC1_1MHZ;               //Set DCO to 1MHz
   DCOCTL = CALDCO_1MHZ;
   P1SEL = BIT2;                        // у uart нам нужна только передача
   P1SEL2 = BIT2;
   UCA0CTL1 |= UCSSEL_2;                //Have USCI use SMCLK AKA 1MHz main CLK
   UCA0BR0 = 8;                         //Baud = 115200
   UCA0BR1 = 0;
   UCA0MCTL = UCBRS2 + UCBRS0;          // Modulation UCBRSx = 5
   UCA0CTL1 &= ~UCSWRST;                //Start USCI

   /* encoder */
   P2REN |= ENC1;
   P2REN |= ENC2;
   encLast=getEnc();
   encoder=1000;

   /* FLAGS */
   FLAGS=0x00;

   /* button 1*/
   P1DIR &= ~SW1;
   P1REN |= SW1;
   P1OUT |= SW1;
   FLAGS &=~SW1Last;
   if (P1IN & SW1)
   {
       FLAGS |=SW1Last;
   }

   initDS3232();

   /* secIN */
   P1IE &=~secIN;   // deny IRQ
   P1DIR &= ~secIN; // in
   P1REN |= secIN;  // pull resistor
   P1OUT |= secIN;  // pullup
   P1IES |= secIN;  // irq Hi/lo edge
   P1IFG &= ~secIN; // irq flag reset cleared
   P1IE |=secIN;    // enable irq

   /* шаговик стрелок */
   P2DIR |= 0x0f;
   P2OUT &= 0xf0;
   i2cReadByte(stepIndexAddr);
   stepIndex = i2cBUF;
   stepIndex &= 0x07;
   i2cReadByte(minIndexAddr);
   minIndex = i2cBUF;
   minIndex &= 0x1f;

   /* шаговик боя */
   P1OUT &= BMask1;
   P2OUT &= BMask2;
   P2SEL &= BMask2;
   P1DIR |= ~BMask1;
   P2DIR |= ~BMask2;
   stepBIndex=0;

   /* timer A*/
   CCTL0 = CCIE;                             // CCR0 interrupt enabled
   CCR0 = StrikeSpeed;
   TACTL = TASSEL_2 + MC_1;                  // SMCLK, upmode


   StrikerInit();

   /* MAIN LOOP */
   while(1)
   {
       while(!(IFG2 & UCA0TXIFG));
    __bis_SR_register(CPUOFF + GIE); // ложимся спать пока не придёт прерывание

    if (FLAGS & secFlag)
    {
        /* пришла секунда */
        if (FLAGS & trueTime)
            {P1OUT |= LED0;}
        else
            {P1OUT ^= LED0;}
        FLAGS &= ~secFlag;
        FLAGS |= timeSYN;
        i2cReadByte(0);
        if (i2cBUF ==0)
        {
          // новая минута
          if (FLAGS & trueTime)
           {
            /* проверка соответствия времени с показаниями */
            // считаем количество минут от 0 часов по ds3232
            i2cReadByte(1);
            rtcMin=i2cBUF;
            i2cReadByte(2);
            rtcHour=i2cBUF;
            rtcMins=((rtcMin & 0xF0)>>4)*10+(rtcMin & 0x0F);
            i=((rtcHour & 0xF0)>>4)*10+(rtcHour & 0x0F);
            if(i>=12){i-=12;}
            rtcMins+=i*60;
            // считаем количество минут от 0 часов на стрелках
            i2cReadByte(curMinAddr);
            curMin=i2cBUF;
            i2cReadByte(curHourAddr);
            curHour=i2cBUF;
            curMins=((curMin & 0xF0)>>4)*10+(curMin & 0x0F);
            i=((curHour & 0xF0)>>4)*10+(curHour & 0x0F);
            if(i>=12){i-=12;}
            curMins+=i*60;
            // вываливаем это в uart
            putChar(0x09);
            putChar(0x09);
            putChar(0x09);
            hex2uart(rtcMins>>12);
            hex2uart(rtcMins>>8);
            hex2uart(rtcMins>>4);
            hex2uart(rtcMins);
            putChar(':');
            hex2uart(curMins>>12);
            hex2uart(curMins>>8);
            hex2uart(curMins>>4);
            hex2uart(curMins);
            putChar(0x0d);

            /* проверяем разницу */
            i=curMins+1;
            if (0x02d0) { i=0;} // 12:00
            if (i != rtcMins )
            {
                P1IE &=~secIN;      // отключаем секундное прерывание
                /* считаем поправку */
                if (rtcMins > curMins)
                {
                    corrSteps=rtcMins-curMins;
                    while (corrSteps > 0)
                    {
                        corrSteps--;
                        minStepUP();
                    }
                }
                else
                {
                    corrSteps=curMins-rtcMins;
                    while (corrSteps > 0)
                    {
                        corrSteps--;
                        minStepDOWN();
                    }
                }
                P1IE |=secIN;       // включаем секундное прерывание
            }
            else
            {
                /* разницы нет. шагаем на 1 минуту */
                minStepUP();
            }

           /* бой */
            i2cReadByte(1); // читаем минуты
            if (i2cBUF == 0x30)
            {
                /* бьём 1 раз каждые полчаса */
                FLAGS |= halfBom;
                bomCnt=1;
            }
            if (i2cBUF == 0)
             {
                /* бьем часы */
                i2cReadByte(2); // читаем часы
                i=((i2cBUF & 0xF0)>>4)*10;
                i+= i2cBUF & 0x0F;
                if(i>12){i-=12;}
                if(i==0){i=12;}
                FLAGS &= ~halfBom;
                bomCnt=i;
                putChar('S');
                hex2uart(i>>4);
                hex2uart(i);
                putChar(' ');
                putChar(0x0a);
                putChar(0x0d);
             }
           }
           else
           {
            putChar('B');
            minStepUP();
           }

        }
        i2cReadByte(2);             //hours
        hex2uart(i2cBUF>>4);
        hex2uart(i2cBUF);
        putChar(':');
        i2cReadByte(1);             //min
        hex2uart(i2cBUF>>4);
        hex2uart(i2cBUF);
        putChar(':');
        i2cReadByte(0);             //sec
        hex2uart(i2cBUF>>4);
        hex2uart(i2cBUF);
        putChar(' ');
        // читаем температуру
        temper2uart(i2cGetTemper());
        putChar(' ');
        putChar(0x0d);
        if (FLAGS & trueTime){P1OUT &= ~LED0;}
        /* проверяем длинное нажатие кнопки*/
        if (!(FLAGS & SW1Last))
        {
          if (SW1LongCntr++==4)
          {
              ZeroInit();
              SW1LongCntr=10;
              FLAGS |= bBWDFlag;
              CCR0=beepSpeed;
              stepsB=1000;
          }
        }
        else
        {
            SW1LongCntr=0;
        }
        /*  отпускаем стрелочный шаговик */
        if (encoder==1000)
        {
            P2OUT &= 0xF0;
        }
    }
    /* энкодер */
    if (FLAGS & encFlag)
    {
        /* берём положение стрелок */
        if (FLAGS & timeSYN)
         {
            i2cReadByte(curMinAddr);
            curMin=i2cBUF;
            i2cReadByte(curHourAddr);
            curHour=i2cBUF;
         }
        i2cSendByte(0,30);      // меняем секунды
        while (encoder>1000)    // по часовой стрелке
        {
            curMin++;
            if ((curMin & 0x0f) == 0x0a)
             {
                curMin &= 0xf0;
                curMin+= 0x10;
                if (curMin == 0x60)
                {
                    curMin = 0x0;
                    if (curHour == 0x23)
                    {
                        curHour=0x0;
                    }
                    else
                    {
                        curHour++;
                        if ((curHour & 0x0f)== 0x0a)
                        {
                            curHour &=0xf0;
                            curHour += 0x10;
                        }
                    }



                }
             }
            i2cSendByte(1,curMin);
            i2cSendByte(2,curHour);
            minStepUP();
            encoder--;
        }
        while (encoder<1000)    // против часовой стрелки
        {
            curMin--;
            if ((curMin & 0x0f) == 0x0f)
             {
                curMin-= 0x06;
                if (curMin == 0xF9)
                {
                    curMin = 0x59;
                    if (curHour == 0x00)
                    {
                        curHour=0x23;
                    }
                    else
                    {
                        curHour--;
                        if ((curHour & 0x0f)== 0x0f)
                        {
                            curHour -= 0x06;
                        }
                    }
                }
             }
            i2cSendByte(1,curMin);
            i2cSendByte(2,curHour);
            minStepDOWN();
            encoder++;
        }
        FLAGS &= ~encFlag;
        putChar(0x09);
        putChar(0x09);
        putChar(' ');
        hex2uart(encoder>>4);
        hex2uart(encoder);
        putChar(0x0d);
        FLAGS &= ~timeSYN;
        i2cSendByte(0,0x01);
        FLAGS &= ~trueTime;

    }
    /* кнопка  */
    if (FLAGS & SW1ON)
    {
        FLAGS &= ~SW1ON;
        putChar(0x09);
        putChar(0x09);
        putChar(0x09);
        putChar(' ');
        hex2uart((FLAGS & SW1Last)>>6);
        putChar(0x0d);
        if (!(FLAGS &SW1Last))
        {
           /* сброс секунд */
           P1IE &=~secIN;   // deny IRQ
           i2cSendByte(0,0);            //reset sec
           delay(250);
           P1IFG &= ~secIN;     // irq flag reset cleared
           FLAGS &= ~secFlag;   // reset secFlag
           P1IE |=secIN;        // enable irq
           FLAGS |= trueTime;   // время установлено
        }
    }
   }
}


/* обработчики прерываний */
// прерывание от порта 1
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
    _bic_SR_register(GIE);
    /* секунда? */
    if (P1IFG & secIN)
     {
        P1IFG &= ~secIN;    // сброс флага прерывания
        FLAGS |= secFlag;   // пришла секунда
     }
    _bis_SR_register(GIE);
    __bic_SR_register_on_exit(CPUOFF); // просыпаемся на выходе
}


// прерывание от i2c
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
    if (FLAGS & i2cTX)
    {
        UCB0TXBUF=i2cBUF;
        __bic_SR_register_on_exit(CPUOFF);

    }else{
        if (!(FLAGS & RXed))
        {
            i2cBUF=UCB0RXBUF;
            FLAGS |= RXed;
            UCB0CTL1 |= UCTXSTP;
            IFG2 &= ~UCB0TXIFG;
            __bic_SR_register_on_exit(CPUOFF);
        }else{
            IFG2 &= ~UCB0RXIFG;
        }
    }
}


// переывание от таймера 0
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0(void)
{
    TA0CCTL2 &= ~CCIFG;
    /* проверяем энкодер */
    encLast<<=2;
    encLast|=getEnc();
    if (encTBL[(encLast&0x0f)]==encUP)
     {
        encoder++;
        FLAGS |= encFlag;
        __bic_SR_register_on_exit(CPUOFF);
     }
    if (encTBL[(encLast&0x0f)]==encDown)
     {
        encoder--;
        FLAGS |= encFlag;
        __bic_SR_register_on_exit(CPUOFF);
     }
    /* проверяем кнопку */
    if (((FLAGS & SW1Last)>>6)^((P1IN & SW1)>>3))
        {
            SW1cntr++;
            if (SW1cntr==5)
            {
                /* save state */
                SW1cntr=10;
                FLAGS |= SW1ON;
                FLAGS &= ~SW1Last;
                if (P1IN & SW1)
                {
                    FLAGS |= SW1Last;
                }
                __bic_SR_register_on_exit(CPUOFF);
            }
            if (SW1cntr>10)
            {
                SW1cntr=10;
            }
        }else{
            SW1cntr=0;
        }
    /* обрабатываем бой */
    if (bomCnt>0)
    {
        if (!(FLAGS & bFWDFlag) & !(FLAGS & bBWDFlag))
         {
            bomCnt--;
            FLAGS |= bFWDFlag;
            if (FLAGS & halfBom)
            {
                stepsB=StrikeSteps;
                CCR0 = HalfStrikeSpeed;

            }
            else
            {
                stepsB=StrikeSteps;
            }
         }

    }
    if (FLAGS & bFWDFlag){FWDstepB();}
    if (FLAGS & bBWDFlag){BWDstepB();}
}

/* пульнуть в uart 16-тиричным ниблом */
static void hex2uart(unsigned char n) {
    static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
            '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    while (!(IFG2&UCA0TXIFG));
    UCA0TXBUF=(hex[n & 15]);
}

// читаем байт из i2c из адреса addr
static void i2cReadByte(unsigned char addr)
{
    while (UCB0CTL1 & UCTXSTP);
    UCB0CTL1 |= UCSWRST;                     //Enable SW reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;         //I2C Master, synchronous mode
    UCB0CTL1 = UCSSEL_2 + UCSWRST;               //Use SMCLK, keep SW reset
    UCB0BR0 = 12;                           //fSCL = SMCLK/12 = ~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = 0x68;                     //Slave Address
    UCB0CTL1 &= ~UCSWRST;                     //Clear SW reset, resume operation
    IE2 |= UCB0TXIE;                        //Enable TX interrupt
    IE2 &= ~UCB0RXIE;                        //Enable RX interrupt
    FLAGS |=i2cTX;
    i2cBUF=addr;
    CCTL0 &= ~CCIE;                             //disable timer interrupt
    P1IE &= ~secIN;
    UCB0CTL1 |= UCTR + UCTXSTT;                 //tx+start
    __bis_SR_register(CPUOFF + GIE);            // Enter LPM0 w/ interrupts
    FLAGS &= ~i2cTX;
    IE2 &= ~UCB0TXIE;
    UCB0CTL1 &=~UCTR;                           //rx
    UCB0CTL1 |= UCTXSTT;
    FLAGS &= ~RXed;
    IE2 |= UCB0RXIE;                            //Enable RX interrupt
    __bis_SR_register(CPUOFF + GIE);            // Enter LPM0 w/ interrupts
    UCB0CTL1 |= UCTXSTP;
    while (!(FLAGS & RXed));
    CCTL0 |= CCIE;
    P1IE |=secIN;
    while (UCB0CTL1 & UCTXSTP);            // Ensure stop condition got sent
}

// пишем байт в i2c по адресу addr
void i2cSendByte(unsigned char addr, unsigned char byte)
{
    while (UCB0CTL1 & UCTXSTP); // wait stop condition is sent
    UCB0CTL1 |= UCSWRST;                     //Enable SW reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;         //I2C Master, synchronous mode
    UCB0CTL1 = UCSSEL_2 + UCSWRST;               //Use SMCLK, keep SW reset
    UCB0BR0 = 12;                           //fSCL = SMCLK/12 = ~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = 0x68;                       //Slave Address
    UCB0CTL1 &= ~UCSWRST;                   //Clear SW reset, resume operation
    IE2 |= UCB0TXIE;                        //Enable TX interrupt
    IE2 &= ~UCB0RXIE;                       //Enable RX interrupt
    FLAGS |=i2cTX;
    i2cBUF=addr;
    CCTL0 &= ~CCIE;                         //disable T0 interrupt
    P1IE &= ~secIN;                         //
    UCB0CTL1 |= UCTR + UCTXSTT; //tx+start
    __bis_SR_register(CPUOFF + GIE);            // Enter LPM0 w/ interrupts
    UCB0TXBUF=byte;
    __bis_SR_register(CPUOFF + GIE);
    UCB0CTL1 |= UCTXSTP;               // I2C stop condition
    CCTL0 |= CCIE;
    P1IE |= secIN;
    while (UCB0CTL1 & UCTXSTP);            // Ensure stop condition got sent
}

// конвертируем температуру в градусы Цельсия
float i2cGetTemper()
{
    unsigned char i, whole,frac;
    float tempC;
    // set flag
    i=0;

    // Read whole part of temperature
    i2cReadByte(0x11);
    whole = i2cBUF;
    // Read Fractional part of temperature
    i2cReadByte(0x12);
    frac = i2cBUF>>6;
    // Reading for whole is in two's complement so if it is negative, convert.
    if(whole & (1<<7))
    {
        // xor with 0b11111111 to get complement then add 1
        whole ^= 0xFF;
        whole ++;
        // set flag to indicate temp is negative
        i=1;
    }
    // Combine whole and fractional parts while converting to Farenheit.
    tempC = whole+frac*.25;
    // Make negative if needed
    if(i==1){tempC *=-1;};
    return tempC;
}

// пуляем температуру в uart
void temper2uart(float temp)
{
    if(temp<0)
    {
     while (!(IFG2&UCA0TXIFG));
     UCA0TXBUF='-';
    }else if(temp==0)
    {
     while (!(IFG2&UCA0TXIFG));
     UCA0TXBUF=' ';
    }else{
     while (!(IFG2&UCA0TXIFG));
     UCA0TXBUF='+';
    }
     while (!(IFG2&UCA0TXIFG));
     UCA0TXBUF=temp/10+0x30;
     while (!(IFG2&UCA0TXIFG));
     UCA0TXBUF=0x30+temp-((unsigned char)(temp/10))*10;
}


void initDS3232(void)
{
    // ждем пока отпустит sda
    P1DIR &= ~BIT7; //SDA input
    P1REN &= 0x3F;
    if (!(P1IN & BIT7))
    {
        P1OUT |= BIT6;
        P1DIR |= BIT6;  //SCL на выход
        while (!(P1IN & BIT7))
        {
            //тикаем SCL
            P1OUT &= ~BIT6;
            delay(1);
            P1OUT |= BIT6;
            delay(1);
        }
        P1DIR &=~BIT6; //SCL на вход
    }

    //init i2c
    P1SEL |= BIT6 + BIT7;                     //Set I2C pins
    P1SEL2|= BIT6 + BIT7;

    i2cReadByte(0x20);      //читаем секунды пару раз
    i2cReadByte(0x20);
    i2cSendByte(0x0e,0x20); //  00100000
    i2cReadByte(0x0f);      //  проверяем регистр состояния на предмет флага остановки таймера
    if (i2cBUF & BIT7)
    {
        /* была остановка таймера. м.б. ионистор сел */
        FLAGS &= ~trueTime;
        putChar('B');
        putChar(0x0a);
        putChar(0x0d);
    }else{
        FLAGS |= trueTime;
        putChar('G');
        putChar(0x0a);
        putChar(0x0d);
    }
    i2cSendByte(0x0f,0);    // 00000000
}
/* шаг стрелочного мотора по часовой */
void FWDstep (unsigned int steps)
{
    while(steps>0)
    {
        stepIndex++;
        if (stepIndex>7){stepIndex=0;}
        P2OUT =0x30 | stepArray[stepIndex+stepShift];
        i2cSendByte(stepIndexAddr, stepIndex);
        steps--;
        delay(stepDelay);
    }
}


/* шаг стрелочного мотора против часовой */
void BWDstep (unsigned int steps)
{
    while(steps>0)
    {
        if (stepIndex==0){stepIndex=8;}
        stepIndex--;
        P2OUT = 0x30 | stepArray[stepIndex+stepShift];
        i2cSendByte(stepIndexAddr, stepIndex);
        steps--;
        delay(stepDelay);
    }

}

/* прямое вращение мотора боя на stepsB шагов */
void FWDstepB (void)
{
    if (stepsB>0)
    {
        stepBIndex++;
        if (stepBIndex>7){stepBIndex=0;}
        P1OUT &= BMask1;
        P2OUT &= BMask2;
        P1OUT |= ~BMask1 & stepArrayB[stepBIndex];
        P2OUT |= ~BMask2 & stepArrayB[stepBIndex];;
        stepsB--;
    }
    else
    {
        P1OUT &= BMask1;
        P2OUT &= BMask2;
        FLAGS &= ~bFWDFlag;
        if(FLAGS & halfBom)
        {
            FLAGS &= ~halfBom;
            CCR0=StrikeSpeed;
        }
    }
}

/* обратное вращение мотора боя на stepsB шагов */
void BWDstepB (void)
{
    if (stepsB>0)
    {
        if (stepBIndex==0){stepBIndex=8;}
        stepBIndex--;
        P1OUT &= BMask1;
        P2OUT &= BMask2;
        P1OUT |= ~BMask1 & stepArrayB[stepBIndex];
        P2OUT |= ~BMask2 & stepArrayB[stepBIndex];
        stepsB--;
    }
    else
    {
        P1OUT &= BMask1;
        P2OUT &= BMask2;
        FLAGS &= ~bBWDFlag;
    }
}

/* задержка */
void delay(unsigned char ms)
{
    while(ms>0)
    {
        i = 500;
        while(i>0){i++;}
        ms--;
    }
}

/* стрелки на минуту вперед */
void minStepUP(void)
{
    minIndex++;
    if (minIndex >= oddMin) //проверяем поправку
    {
        FWDstep(stepPerMin+oddMinDiff);
        minIndex=0;
    }
    else
    {
        FWDstep(stepPerMin);
    }
    // обновляем
    i2cSendByte(minIndexAddr, minIndex);
    // ждем и выключаем мотор
    if (FLAGS & timeSYN)
    {
        i2cReadByte(1);
        i2cSendByte(curMinAddr, i2cBUF);
        i2cReadByte(2);
        i2cSendByte(curHourAddr, i2cBUF);
        delay(100);
        P2OUT &= 0xF0;
    }else{
        i2cSendByte(curMinAddr,curMin);
        i2cSendByte(curHourAddr,curHour);
        delay(100);
    }
}

/* стрелки на минуту назад */
void minStepDOWN(void)
{
    minIndex--;
    if (minIndex == 0)  //проверяем поправку
    {
        BWDstep(stepPerMin+oddMinDiff);
        minIndex=oddMin;
    }
    else
    {
        BWDstep(stepPerMin);
    }
    // обновляем
    i2cSendByte(minIndexAddr, minIndex);
    i2cReadByte(1);
    i2cSendByte(curMinAddr, i2cBUF);
    i2cReadByte(2);
    i2cSendByte(curHourAddr, i2cBUF);
    // ждем и выключаем мотор
    if (!encFlag)
    {
        delay(100);
        P2OUT &= 0xF0;
    }
}


/* байт в uart */
void putChar(unsigned char byte)
{
    while(!(IFG2 & UCA0TXIFG));
    UCA0TXBUF = byte;
}

/* состояние входов энкодера */
unsigned int getEnc(void)
{
    return (P2IN & EncMask)>>4;
}

/* привязка времени к стрелкам (стрелки на 00:00) */
void ZeroInit(void)
{
        i2cSendByte(1,0);               //reset min
        i2cSendByte(2,0);               //reset hour
        i2cSendByte(curMinAddr,0);      //reset curMin
        i2cSendByte(curHourAddr,0);     //reset CurHour
        i2cSendByte(0,0);               //reset sec

}

/* парковка шаговика боя */
void StrikerInit(void)
{
       stepsB=InitBStepsF;
       FLAGS |= bBWDFlag;
       while(FLAGS & bBWDFlag);
       stepsB=InitBStepsB;
       FLAGS |= bFWDFlag;
       while(FLAGS & bFWDFlag);
       FLAGS &= ~strikerInitFlag;
}
