
#include "io430.h"
#include "in430.h"
#include "stdint.h"

#define TXD       BIT1            // TXD a P1.1 lábon
#define frequency 985000

unsigned int old_capture = 0;
unsigned int capture_buffer[6];
unsigned char count=0;
//long captured=0, cap_val=0;
char uart=0;
unsigned int new_capture;

/**----------------------------------------------
 *   Késleltető eljárás (1 - 65535 ms)
 *-----------------------------------------------
 * delay - a késleltetés ms egységben megadva
 */
void delay_ms(uint16_t delay) {
  uint16_t i;
  for(i=0; i<delay; i++) {
    __delay_cycles(1000);
  }
}

/**------------------------------------------------------------
 *   Egy karakter kiküldése a soros portra
 *   SW_UART: 9600 bit/s, 8, N, 2 formátum
 *   DCO = 1 MHz (Bitidő = 104.167 usec)
 *-------------------------------------------------------------
 * c - a kiküldeni kívánt karakter kódja
 */
void sw_uart_putc(char c) {
  uint8_t i;
  uint16_t TXData;                //Adatregiszter (11 bites)
  TXData = (uint16_t)c | 0x300;   //2 Stop bit (mark)
  TXData = TXData << 1;           //Start bit (space)
  for(i=0; i<11; i++) {           //11 bitet küldünk ki
    if(TXData & 0x0001) {         //Soron következő bit vizsgálata
      P1OUT |= TXD;               //Ha '1'
    } else {
      P1OUT &= ~TXD;              //Ha '0'
    }
    TXData = TXData >> 1;         //Adatregiszter léptetés jobbra
    __delay_cycles(89);           //<== Itt kell hangolni!
  }
  P1OUT |= TXD;                   //Az alaphelyzet: mark
}
/**------------------------------------------------------------
 * Decimális kiíratás adott számú tizedesjegyre.
 *-------------------------------------------------------------
 * data - a kiírandó szám (előjelesen)
 * ndigits - a kiírandó tizedesek száma
 */
void sw_uart_outdec(int32_t data, uint8_t ndigits) {
  static char s[12];
  int8_t i;
  i=0;

    do {
      s[i]=data%10 + '0';              //A számjegyek meghatározása
      data=data/10;                    //hátulról visszafelé
      i++;
      if(i==ndigits) {s[i]='.'; i++;}  //A tizedespont beszúrása
    } while(data>0 || i<(ndigits+2));

    do {
      sw_uart_putc(s[--i]);            //A számjegyek kiírása
    } while(i);
}
/**----------------------------------------------
 *  Karakterfüzér kiírása a soros portra
 *-----------------------------------------------
 * p_str - karakterfüzér mutató (nullával lezárt stringre mutat)
 */
void sw_uart_puts(char* p_str) {
  char c;
  while ((c=*p_str)) {
      sw_uart_putc(c);
      p_str++;
  }
}

void main(void){
     
     WDTCTL = WDTPW + WDTHOLD;           // Stop WDT
     
     BCSCTL1 = CALBC1_1MHZ;              // Set DCO to 1MHz
     DCOCTL = CALDCO_1MHZ;
    
     P1DIR |= (BIT0 + BIT4);                      // P1.0 LED output
     P1OUT &= ~(BIT0);
     P1DIR |= TXD;                        //TXD legyen digitális kimenet
     P1OUT |= TXD;                        //TXD alaphelyzete: mark
     P1DIR &= ~BIT2;                     //Port 1.2/TACCR0 - Input
     P1SEL |= (BIT2 + BIT4);                      // Select Timer Capture option
     
     TACCTL1 = CM_2 + CCIS_0 + SCS + CAP + CCIE; // CCR1 timer capture
     TACTL |= TASSEL_2 + MC_2 + TACLR;      // SMCLK = 1 Mhz
     _EINT();
     
     while(1){
          if(uart){
               _DINT();
               P1OUT ^= BIT0;
               long captured=0, cap_val=0;
               unsigned int captured_rpm=0, captured_hz=0;
               for(char j=1; j<6;j++){
                    cap_val += capture_buffer[j];
               }
               captured = cap_val / 5;
               captured_hz = frequency / captured;
               captured_rpm = (captured_hz<<2)+(captured_hz<<1);
               sw_uart_puts("\r\nFrequency = ");
               sw_uart_outdec(captured_hz,0);
               sw_uart_puts(" Hz Fordulat = ");
               sw_uart_outdec(captured_rpm,0);
               sw_uart_puts(" RPM");
          }
          __low_power_mode_0();
     }
}

#pragma vector=TIMERA1_VECTOR
__interrupt void TimerA1(void){
     new_capture = TACCR1;
     capture_buffer[count++] = new_capture - old_capture;
     if (count==6){
          count=0;
          uart=1;
          TACCTL1 &= ~CCIFG;
          __low_power_mode_off_on_exit();
     }
     old_capture = new_capture;
     TACCTL1 &= ~CCIFG;
}



