#include "msp430x54xA.h"
#include <string.h>

#define LIGAR   		0x10
#define CORRER			0x20
#define APAGAR			0x30
#define PROGRAMAR		0x40
#define PROG_INFO		0x50

#define P_DIR           1
#define P_IN            0
#define P_OUT			4
#define PV1             2
#define PV2             3

#define COMANDO 		0
#define TERMINAL		1

#define NIBBLE_ALTO     0
#define NIBBLE_BAIXO    1

#define P1MASK			0xC6
#define P2MASK			0xFF
#define P3MASK			0x41
#define P4MASK			0x07
#define P9MASK			0xE0
#define P10MASK			0x89
#define P11MASK			0x07

#define P1MASKINV		0x39
#define P2MASKINV		0x00
#define P3MASKINV		0xBE
#define P4MASKINV		0xF8
#define P9MASKINV		0x3E
#define P10MASKINV		0x76
#define P11MASKINV		0xF8

#define START_ADDRESS	0x7000

#define VINTE       	20

#define CODE            1
#define IVT	            2
#define INFO	        3

#define SEG_IVT			0xFFD2
#define SEG_INFOD       0x1800
#define IVUARTADDRESS   0xFFF2
#define IVTIMERADDRESS  0xFFE2
#define IVUART			0x5C00
#define IVTIMER			0x5C6A
#define IVUARTALTO		0x5C
#define IVUARTBAIXO		0x00
#define IVTIMERALTO		0x5C
#define IVTIMERBAIXO	0x6A
#define RESETALTO		0x5C
#define RESETBAIXO		0x48

volatile int vintecontagens;
volatile int bytes_recebidos;
volatile int bytes_a_receber;
volatile int modo;
volatile char receive_Buffer[550];
char p1,p2,p3,p4,p9,p10,p11;

void initialize_clock_system(void);
int info_vazia(void);
void MRM_ivt_test(void);
void activate_switches(void);
void App_ivt_test(void);
void initialize_ports(void);
void initialize_USCI0_UART(void);
void initialize_USCI0_UART1 (void); // Tx1/Rx1 Hirose
void initialize_timerA(void);
void initialize_leds(void);
void welcome_message(void);
void acknowledge(void);
void terminal_nack(void);
void write_char(char in);
void write_char_1(char in);
char byte2ascii(char in, int nibble);
char ascii2byte(char nalto, char nbaixo);
void start_program(void);
void erase_segment(void);
void write_memory(int seg_type);
void PV1toMSP(char alto, char baixo);
void PV2toMSP(char alto, char baixo);
unsigned int MSPtoPV1(int tipo);
unsigned int MSPtoPV2(int tipo);
void readPV(int porto, int tipo);
void writePV(int porto, int tipo);
int verificar_buffer(int in);

void main(void){
	modo = TERMINAL;
	char estado_leds = 0x00;
	vintecontagens = 0;
	bytes_recebidos = 0;
	bytes_a_receber = -1;

	WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

	initialize_clock_system();

	activate_switches();

  	MRM_ivt_test();

	initialize_ports();

	initialize_USCI0_UART();
	initialize_USCI0_UART1();

	initialize_timerA();

	initialize_leds();

	__bis_SR_register(GIE);       // interrupts enabled

	while(bytes_recebidos == 0){
		if(vintecontagens == VINTE){
  			vintecontagens = 0;
  			estado_leds += 0x20;
			P4OUT |= estado_leds;
			if(estado_leds == 0xE0){
				estado_leds = 0x00;
				initialize_leds();
				//start_program();
			}
  		}
	}

	TA1CCTL0 = 0;
	P4DIR = 0x03;
	P4OUT = 0x03;

	if(receive_Buffer[0] == 1){
		modo = COMANDO;
	}


	while(1){
  		if((modo == COMANDO) && (bytes_recebidos == bytes_a_receber)){
  			bytes_recebidos = 0;
			bytes_a_receber = -1;
			switch(receive_Buffer[1]){
				case LIGAR:
					acknowledge();
					break;
				case CORRER:
				    acknowledge();
				    App_ivt_test();
					start_program();
					break;
				case APAGAR:
				    erase_segment();
					acknowledge();
					break;
				case PROGRAMAR:
					write_memory(CODE);
					acknowledge();
					break;
			    case PROG_INFO:
			        write_memory(INFO);
			        acknowledge();
				default:
					break;
			}
 		}
 		else if((modo == TERMINAL) && (bytes_recebidos != 0)){
 			if (receive_Buffer[bytes_recebidos-1] == 13){
 				switch(receive_Buffer[0]){
 					case 's':
 						WDTCTL = 0;
 						break;
 					case 13: // return
 						welcome_message();
 						break;
 					case 114: // r
 						switch(bytes_recebidos){
 							case 2:
 								App_ivt_test();
 								start_program();
 								break;
 							case 3:

 								if(receive_Buffer[1] == '1'){ write_char('l'); write_char_1('l');}      // write_char_1(char in)
 								else if(receive_Buffer[1] == '2'){ write_char_1('y');}
 							else terminal_nack();
 								break;
 							case 4:
 								if(receive_Buffer[1] != 'd') terminal_nack();
 								else{
 									if(receive_Buffer[2] == '1') readPV(PV1, P_DIR);
 									else if(receive_Buffer[2] == '2') readPV(PV2, P_DIR);
 									else terminal_nack();
 								}
 								break;
 							default:
 								terminal_nack();
 								break;
 						}
 						break;
 					case 119: //'w'
 						switch(bytes_recebidos){
 							case 7:
 								if(verificar_buffer(2) != 0){
 									terminal_nack();
 									break;
 								}
 								if(receive_Buffer[1] == '1') writePV(PV1, P_OUT);
 								else if(receive_Buffer[1] == '2') writePV(PV2, P_OUT);
 								else terminal_nack();
 								break;
 							case 8:
 								if(verificar_buffer(3) != 0){
 									terminal_nack();
 									break;
 								}
 								if(receive_Buffer[1] != 'd') terminal_nack();
 								else{
 									if(receive_Buffer[2] == '1') writePV(PV1, P_DIR);
 									else if(receive_Buffer[2] == '2') writePV(PV2, P_DIR);
 									else terminal_nack();
 								}
 								break;
 							default:
 								terminal_nack();
 								break;
 						}
 						break;
 					default:
 						terminal_nack();
 						break;
 				}
 				bytes_recebidos = 0;
 			}
 		}
  	}
}


//repor o estado dos registos do "unified clock system" por omissão
void initialize_clock_system(void){
	UCSCTL0 = 0x0000;
	UCSCTL1 = 0x0020;
	UCSCTL2 = 0x101F;
	UCSCTL3 = 0x0000;
	UCSCTL4 = 0x0044;
	UCSCTL5 = 0x0000;
	UCSCTL6 = 0xC1CD;
	UCSCTL7 = 0x0703;
	UCSCTL8 = 0x0707;
}

//verificar se o segmento InfoD está vazio
int info_vazia(void){
	char *infod_pointer;
	int i;

	infod_pointer = (char *)SEG_INFOD;

	for(i=0; i<46; i++){
		if(*infod_pointer != 0xFF){
			return 1;
		}
		infod_pointer++;
	}

	return 0;
}

//verificar se a tabela de vectores está pronta para o MRM
void MRM_ivt_test(void){
	int i;
	unsigned int uart_actual, timer_actual;

	if(info_vazia() == 1){
		uart_actual = *((unsigned int *) IVUARTADDRESS);
		timer_actual = *((unsigned int *) IVTIMERADDRESS);
		if((uart_actual != IVUART) || (timer_actual != IVTIMER)){
			receive_Buffer[2] = 0xFE;
			receive_Buffer[3] = 0x00;
			erase_segment();
			for(i=4; i<49; i++){
				receive_Buffer[i] = 0xFF;
			}
			receive_Buffer[2] = 0xFF;
			receive_Buffer[3] = 0xD2;
			receive_Buffer[20] = IVTIMERBAIXO;
			receive_Buffer[21] = IVTIMERALTO;
			receive_Buffer[36] = IVUARTBAIXO;
			receive_Buffer[37] = IVUARTALTO;
			write_memory(IVT);
		}
	}
}

void App_ivt_test(void){
	int i;
	char *infod_pointer_char;

	if(info_vazia() == 1){
		receive_Buffer[2] = 0xFE;
		receive_Buffer[3] = 0x00;
		erase_segment();
		infod_pointer_char = (char *)SEG_INFOD;
		for(i=4; i<48; i++){
			receive_Buffer[i] = *infod_pointer_char++;
		}
		receive_Buffer[2] = 0xFF;
		receive_Buffer[3] = 0xD2;
		write_memory(IVT);
	}
}

void activate_switches(void){
	P3SEL |= 0x80;                            // P3.7 - SDA - Assign I2C pins
	P5SEL |= 0x10;							  // P5.4 - SCL

	UCB1CTL1 |= UCSWRST;                      // Enable SW reset

	UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
	UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK
	UCB1BR0 = 144;                            // fSCL = SMCLK/12 = ~100kHz
  	UCB1BR1 = 0;
  	UCB1I2CSA = 0x48;                         // Slave Address is 090h 1001 0000 -> address (7bit, A0=A1=0) + R/!W

  	UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset*/

	while (UCB1CTL1 & UCTXSTP);               // Ensure stop condition got sent
    UCB1CTL1 |= UCTR + UCTXSTT;               // I2C start condition
  	UCB1TXBUF = 0xFF;  	                      // Send init data
  	while(UCB1CTL1 & UCTXSTT);                // Start condition sent?
  	UCB1CTL1 |= UCTXSTP;				      // I2C1 Stop Condition*/
}

void initialize_ports(void){
	P1SEL = 0;
	P2SEL = 0;
	P3SEL = 0;
	P4SEL = 0;
	P5SEL = 0;
	P6SEL = 0;
	P7SEL = 0;
	P8SEL = 0;
	P9SEL = 0;
	P10SEL = 0;
	P11SEL = 0;

	P1DIR = 0;
	P2DIR = 0;
	P3DIR = 0;
	P4DIR = 0;
	P5DIR = 0;
	P6DIR = 0;
	P7DIR = 0;
	P8DIR = 0;
	P9DIR = 0;
	P10DIR = 0;
	P11DIR = 0;

	P1REN = 0xFF;
	P2REN = 0xFF;
	P3REN = 0xFF;
	P4REN = 0xFF;
	P5REN = 0xFF;
	P6REN = 0xFF;
	P7REN = 0xFF;
	P8REN = 0xFF;
	P9REN = 0xFF;
	P10REN = 0xFF;
	P11REN = 0xFF;

	P1OUT = 0;
	P2OUT = 0;
	P3OUT = 0;
	P4OUT = 0;
	P5OUT = 0;
	P6OUT = 0;
	P7OUT = 0;
	P8OUT = 0;
	P9OUT = 0;
	P10OUT = 0;
	P11OUT = 0;
}

//inicializar registos da USCI0 para funcionar como UART a 115200-8-1
void initialize_USCI0_UART(void){
	P3SEL = 0x30;                             // P3.4,5 = USCI_A0 TXD/RXD
	UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
	UCA0CTL1 |= UCSSEL_2;                     // SMCLK
	UCA0BR0 = 9;                              // 1MHz 115200 (see User's Guide)
	UCA0BR1 = 0;                              // 1MHz 115200
	UCA0MCTL |= UCBRS_1 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0
	UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
	UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
}

void initialize_USCI0_UART1(void){
	P5SEL = 0xC0;                             // P5.6,7 = USCI_A1 TXD/RXD
	UCA1CTL1 |= UCSWRST;                      // **Put state machine in reset**
	UCA1CTL1 |= UCSSEL_2;                     // SMCLK
	UCA0BR0 = 9;                              // 1MHz 115200 (see User's Guide)
	UCA0BR1 = 0;                              // 1MHz 115200
	UCA1MCTL |= UCBRS_1 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0
	UCA1CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
	UCA1IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
}

//inicializar timerA para contagem regressiva
void initialize_timerA(void){
	TA1CCTL0 = CCIE;                          // CCR0 interrupt enabled
	TA1CCR0 = 50000;
	TA1CTL = TASSEL_2 + MC_2 + TACLR;         // SMCLK, contmode, clear TAR
}

//inicializar portos e estado dos leds
void initialize_leds(void){
	P4DIR |= 0xE0;
	P4OUT &= 0x1F;
}

void welcome_message(void){
	char menu[14][50];
	int i,j,lim;

	strcpy(menu[0],"\r\n\r\nWelcome to the Mote Resident Monitor\r\n");
	strcpy(menu[1],"The available operations are:\r\n");
	strcpy(menu[2],"1. print the menu (just press return)\r\n");
	//strcpy(menu[3],"2. read virtual port 1 (r1)\r\n");
	strcpy(menu[3],"2. SenseCam (l)\r\n");
	strcpy(menu[4],"3. SenseCam (y)\r\n");
	//strcpy(menu[4],"3. read virtual port 2 (r2)\r\n");
	strcpy(menu[5],"4. write virtual port 1 (w1XXXX)\r\n");
	strcpy(menu[6],"5. write virtual port 2 (w2XXXX)\r\n");
	strcpy(menu[7],"6. read virtual port 1 directions (rd1)\r\n");
	strcpy(menu[8],"7. read virtual port 2 directions (rd2)\r\n");
	strcpy(menu[9],"8. set virtual port 1 directions (wd1XXXX)\r\n");
	strcpy(menu[10],"9. set virtual port 2 directions (wd2XXXX)\r\n");
	//strcpy(menu[11],"10. set the 7 segment display (w7XX)\r\n");
	strcpy(menu[11],"10. run the pre-programmed code (r)\r\n");
	strcpy(menu[12],"11. reset the microcontroller (s)\r\n");
	strcpy(menu[13],"To exit just close the terminal application\r\n\r\n\r\n");

	for(i=0; i<14; i++){
		lim = strlen(menu[i]);
		for(j=0; j<lim; j++){
			write_char(menu[i][j]);
		}
	}
}

//enviar resposta afirmativa de envio de mensagem processada
void acknowledge(void){
	write_char(1);
}

void terminal_nack(void){
	char msg[]="Wrong command\r\n";
	int i;

	for(i=0; i<strlen(msg); i++){
		write_char(msg[i]);
	}
}

void write_char(char in){
	while (!(UCA0IFG&UCTXIFG));             // USCI_A0 TX buffer ready?
	UCA0TXBUF = in;                  		// TX -> RXed character
}


void write_char_1(char in){
	while (!(UCA1IFG&UCTXIFG));             // USCI_A1 TX buffer ready?
	UCA1TXBUF = in;                  		// TX -> RXed character
}

char byte2ascii(char in, int nibble){
	char asc = 0;

	switch(nibble){
		case NIBBLE_ALTO:
			in = in & 0xF0;
			in = in >> 4;
			break;
		case NIBBLE_BAIXO:
			in = in & 0x0F;
			break;
		default:
			break;
	}

	if(in <10){
		asc = in + '0';
	}
	else{
		asc = in + 'A' - 10;
	}

	return asc;
}

char ascii2byte(char nalto, char nbaixo){
	char retorno;

	if((nalto >= '0') && (nalto <= '9')){
		nalto -= '0';
	}
	else if((nalto >= 'a') && (nalto <='f')){
		nalto = nalto - 'a' + 10;
	}
	else if((nalto >= 'A') && (nalto <='F')){
		nalto = nalto - 'A' + 10;
	}

	if((nbaixo >= '0') && (nbaixo <= '9')){
		nbaixo -= '0';
	}
	else if((nbaixo >= 'a') && (nbaixo <='f')){
		nbaixo = nbaixo - 'a' + 10;
	}
	else if((nbaixo >= 'A') && (nbaixo <='F')){
		nbaixo = nbaixo - 'A' + 10;
	}

	nalto = nalto << 4;

	retorno = nbaixo | nalto;

	return retorno;
}

//arrancar programa contido em memória
void start_program(void){
	((void (*)())START_ADDRESS)();
}

//apagar um segmento de memória
void erase_segment(void){
	char *Flash_pointer;
	unsigned int aux;

  	__disable_interrupt();                    // 5xx Workaround: Disable global
                                              // interrupt while erasing
    aux = receive_Buffer[2];
    aux = aux << 8;
    aux += receive_Buffer[3];
    Flash_pointer = (char*) aux;

	FCTL3 = FWKEY;                            // Clear Lock bit
	FCTL1 = FWKEY+ERASE;                      // Set Erase bit
	*Flash_pointer = 0;                       // Dummy write to erase Flash seg

	FCTL1 = FWKEY;                            // Clear WRT bit
  	FCTL3 = FWKEY+LOCK;                       // Set LOCK bit

	__bis_SR_register(GIE);
}

//escrever código na memória Flash
void write_memory(int seg_type){
	char *Flash_pointer;
	unsigned int aux;
	int i;
	int limit;

  	__disable_interrupt();                    // 5xx Workaround: Disable global
                                              // interrupt while erasing
    if(seg_type == CODE){
    	limit = 516;
    }
    else if(seg_type == IVT){
    	limit = 50;
    	receive_Buffer[48] = RESETBAIXO;
		receive_Buffer[49] = RESETALTO;
    }
    else if(seg_type == INFO){
    	limit = 48;
    }

    aux = receive_Buffer[2];
    aux = aux << 8;
    aux += receive_Buffer[3];
    Flash_pointer = (char*) aux;

	FCTL3 = FWKEY;                            // Clear Lock bit

  	FCTL1 = FWKEY+WRT;                        // Set WRT bit for write operation

	for (i = 4; i < limit; i++) {
    	*Flash_pointer = receive_Buffer[i];   // Write value to flash
  		Flash_pointer++;
  	}

	FCTL1 = FWKEY;                            // Clear WRT bit
  	FCTL3 = FWKEY+LOCK;                       // Set LOCK bit

	__bis_SR_register(GIE);
}

void PV1toMSP(char alto, char baixo){
	p2 = ((alto & 0x0F) << 4) | ((baixo & 0xE0) >> 4) | ((baixo & 0x08) >> 3);
	p3 = ((alto & 0x10) >> 4) | ((baixo & 0x10) << 2);
	p4 = ((baixo & 0x04) >> 2) | (baixo & 0x02) | ((baixo & 0x01) << 2);
}

void PV2toMSP(char alto, char baixo){
	p1 = (baixo & 0xC0) | ((baixo & 0x30) >> 3);
	p9 = ((alto & 0x01) << 7) | ((alto & 0x02) << 5);
	p10 = ((alto & 0x08) >> 3) | (baixo & 0x08) | ((baixo & 0x01) << 7);
	p11 = (alto & 0x04) | ((baixo & 0x06) >> 1);
}

unsigned int MSPtoPV1(int tipo){
	unsigned int pv1;
	char alto,baixo;
	char auxp2,auxp3,auxp4;

	switch(tipo){
		case P_DIR:
			auxp2 = P2DIR;
			auxp3 = P3DIR;
			auxp4 = P4DIR;
			break;
		case P_IN:
			auxp2 = P2IN;
			auxp3 = P3IN;
			auxp4 = P4IN;
			break;
		default:
			break;
	}

	alto = ((auxp3 & 0x01) << 4) | ((auxp2 & 0xF0) >> 4);
	baixo = ((auxp2 & 0x0E) << 4) | ((auxp2 & 0x01) << 3) | ((auxp3 & 0x40) >> 2) | ((auxp4 & 0x01) << 2) | (auxp4 & 0x02) | ((auxp4 & 0x04) >> 2);

	pv1 = alto;
	pv1 = pv1 << 8;
	pv1 = pv1 | baixo;
	return pv1;
}

unsigned int MSPtoPV2(int tipo){
	unsigned int pv2;
	char alto,baixo;
	char auxp1,auxp9,auxp10,auxp11;

	switch(tipo){
		case P_DIR:
			auxp1  = P1DIR;
			auxp9  = P9DIR;
			auxp10 = P10DIR;
			auxp11 = P11DIR;
			break;
		case P_IN:
			p1  = P1IN;
			auxp9  = P9IN;
			auxp10 = P10IN;
			auxp11 = P11IN;
			break;
		default:
			break;
	}

	alto = ((auxp10 & 0x01) << 3) | (auxp11 & 0x04) | ((auxp9 & 0x40) >> 5) | ((auxp9 & 0x80) >> 7);
	baixo = (auxp1 & 0xC0) | ((auxp1 & 0x06) << 3) | (auxp10 & 0x08) | ((auxp11 & 0x03) << 1) | ((auxp10 & 0x80) >> 7);

	pv2 = alto;
	pv2 = pv2 << 8;
	pv2 = pv2 | baixo;
	return pv2;
}

void readPV(int porto, int tipo){
	unsigned int pv;
	char pv_baixo,pv_alto;

	switch(porto){
		case PV1:
			pv = MSPtoPV1(tipo);break;
		case PV2:
			pv = MSPtoPV2(tipo);break;
	}

	pv_alto = ((pv & 0xFF00) >> 8);
	pv_baixo = (pv & 0x00FF);

	write_char(byte2ascii(pv_alto,NIBBLE_ALTO));
	write_char(byte2ascii(pv_alto,NIBBLE_BAIXO));
	write_char(byte2ascii(pv_baixo,NIBBLE_ALTO));
	write_char(byte2ascii(pv_baixo,NIBBLE_BAIXO));
	write_char('\r');
	write_char('\n');
	write_char('\r');
	write_char('\n');
}

void writePV(int porto, int tipo){
	char naltoalto, naltobaixo, nbaixoalto, nbaixobaixo;

	switch(tipo){
		case P_OUT:
			naltoalto = receive_Buffer[2];
			naltobaixo = receive_Buffer[3];
			nbaixoalto = receive_Buffer[4];
			nbaixobaixo = receive_Buffer[5];
			break;
		case P_DIR:
			naltoalto = receive_Buffer[3];
			naltobaixo = receive_Buffer[4];
			nbaixoalto = receive_Buffer[5];
			nbaixobaixo = receive_Buffer[6];
			break;
	}

	switch(porto){
		case PV1:
			PV1toMSP(ascii2byte(naltoalto,naltobaixo),ascii2byte(nbaixoalto,nbaixobaixo));
			switch(tipo){
				case P_OUT:
					P2OUT = ((P2OUT & P2MASKINV) | p2);
					P3OUT = ((P3OUT & P3MASKINV) | p3);
					P4OUT = ((P4OUT & P4MASKINV) | p4);
					break;
				case P_DIR:
					P2DIR = ((P2DIR & P2MASKINV) | p2);
					P3DIR = ((P3DIR & P3MASKINV) | p3);
					P4DIR = ((P4DIR & P4MASKINV) | p4);
					break;
			}
			break;
		case PV2:
			PV2toMSP(ascii2byte(naltoalto,naltobaixo),ascii2byte(nbaixoalto,nbaixobaixo));
			switch(tipo){
				case P_OUT:
					P1OUT = (P1OUT & P1MASKINV) | p1;
					P9OUT = (P9OUT & P9MASKINV) | p9;
					P10OUT = (P10OUT & P10MASKINV) | p10;
					P11OUT = (P11OUT & P11MASKINV) | p11;
					break;
				case P_DIR:
					P1DIR = (P1DIR & P1MASKINV) | p1;
					P9DIR = (P9DIR & P9MASKINV) | p9;
					P10DIR = (P10DIR & P10MASKINV) | p10;
					P11DIR = (P11DIR & P11MASKINV) | p11;
					break;
			}
			break;
	}

	write_char('O');
	write_char('K');
	write_char('\r');
	write_char('\n');
	write_char('\r');
	write_char('\n');
}

int verificar_buffer(int in){
	int i;
	int lim = in+4;

	for(i=0; i<lim; i++){
		if((receive_Buffer[i] < '0') || ((receive_Buffer[i] > '9') && (receive_Buffer[i] < 'A'))
			|| ((receive_Buffer[i] > 'Z') && (receive_Buffer[i] < 'a'))
			|| (receive_Buffer[i] > 'z')){
				return -1;
			}
	}

	return 0;
}


#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
	switch(__even_in_range(UCA0IV,4)) {
		case 0:break;                             // Vector 0 - no interrupt
		case 2:                                   // Vector 2 - RXIFG
			receive_Buffer[bytes_recebidos] = UCA0RXBUF;
			bytes_recebidos++;
			if(bytes_recebidos == 1){
				if(receive_Buffer[0] == 0x00){ //special programming case
					bytes_a_receber = 518; //512 dados segmento + 2 end segmento + 4 sinc
				}
				else{
					bytes_a_receber = receive_Buffer[0] + 3; //comando + 3 sinc
				}
			}
			break;
		case 4:break;                             // Vector 4 - TXIFG
		default: break;
	}
}

// Timer A0 interrupt service routine
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
	vintecontagens++;
	TA1CCR0 += 50000;                         // Add Offset to CCR0
}
