/************************************************************************************
 *  Launchpad demóprogram: uart_soft
 *
 * Egyirányú szoftveres UART kezelés (csak adatküldés) demó.
 * paraméterek: 2400 baud, 8 adatbit, nincs paritásbit, 1 stopbit 
 * A gyárilag kalibrált 1 MHz-es DCO beállítást használjuk: 
 * ACLK = n/a, MCLK = SMCLK = DCO 1 MHz
 * 
 * Hardver követelmények:
 *  - Launchpad MSP430G2xxx mikrovezérlővel
 *
 *                MSP430G2xxx
 *             -----------------
 *         /|\|              XIN|-
 *          | |                 |
 *          --|RST          XOUT|-
 *            |                 |
 *     TxD <--|P1.1             |
 *
 * 
 *  I. Cserny
 *  MTA ATOMKI, Debrecen
 *  June 2012
 *  Fejlesztői környezet: IAR Embedded Workbench for MSP430 v5.30.1 Kickstart Edition
 ************************************************************************************/
#include "io430.h"
#include "stdint.h"

#define TXD       BIT1            // TXD a P1.1 lábon


/**----------------------------------------------
 *   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: 2400 bit/s, 8, N, 1 formátum
 *   DCO = 1 MHz (Bitidő = 416,667 usec)
 *-----------------------------------------------
 * c - a kiküldeni kívánt karakter kódja
 */
void sw_uart_putc(char c) {
  uint8_t i;
  uint16_t TXData;
  TXData = (uint16_t)c | 0x100;   //Add mark stop bit
  TXData = TXData << 1;           //Add space start bit
  for(i=0; i<10; i++) {
    if(TXData & 0x0001) {
      P1OUT |= TXD;
    } else {
      P1OUT &= ~TXD;
    }
    TXData = TXData >> 1;
    __delay_cycles(400);          //<== Itt kell hangolni!
  }
  P1OUT |= TXD;                   //Az alaphelyzet: mark
}

/**----------------------------------------------
 *  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;       //Letiltjuk a watchdog időzítőt
  DCOCTL = CALDCO_1MHZ;           // DCO beállítása a gyárilag kalibrált 
  BCSCTL1 = CALBC1_1MHZ;          // 1 MHz-es frekvenciára  
  P1DIR |= TXD;                   //TXD legyen digitális kimenet
  P1OUT |= TXD;                   //TXD alaphelyzete: mark
  P1DIR &= ~BIT3;                 //P1.3 legyen digitális bemenet
  P1OUT |= BIT3;                  //Felfelé húzzuk, nem lefelé  
  P1REN |= BIT3;                  //Belső felhúzás engedélyezése    
  while(1) {
    delay_ms(1000);
    sw_uart_puts("Hello world!\r\n");
  }
}

