#define _UART_BAUD_RATE (9600ul*16ul)

static volatile char TXBuf[32];
static volatile signed char TX1=0; //sendpointer
static volatile signed char TX2=0; //endpointer	
static volatile char RXBuf[32];
static volatile signed char RX1=0;
static volatile char RX_Idle=0;

void uart_init(void) {
UBRR0  = sysclock/_UART_BAUD_RATE-1;;
#if USE_2X
    UCSR0A |= _BV(U2X0);
#else
    UCSR0A &= ~(_BV(U2X0));
#endif
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
UCSR0B = _BV(RXCIE0) |_BV(RXEN0) | _BV(TXEN0);   /* Enable RX and TX */
RXBuf[31]=0;
}

void uart_send_poll(void) {
if (TX1==TX2) return;
if (bit_is_clear(UCSR0A, UDRE0)) return; /* Wait until data register empty. */
UDR0 = TXBuf[TX1];
TX1++;
}

void uart_queue_str(const char *data){
TX1=0;
TX2=0;
while (*data!=0) TXBuf[TX2++]=*data++;
TXBuf[TX2++]=0x0d;
TXBuf[TX2++]=0x0a;
}


ISR(USART_RX_vect)
{
int a;
unsigned char b;
char t[8];
b = UDR0;
if (b<' ') b=0;
if (RX1 < 31){
	RXBuf[RX1]=b;
	RX1++;
	}
if (b==0){ //string received, do something with it
	if (RX_Idle==1){
		RX1=0; 
		return;
		}	
	if (RXBuf[0]==0){	//ignore LF
		RX1=0; 
		return;
		}
	if ((strcmp((char*)RXBuf,"ID")==0) || (strcmp((char*)RXBuf,"id")==0))
		{
		RX1=0; 
		RXBuf[0]=0;
		uart_queue_str(ID);
		return;
		}
	if ((strcmp((char*)RXBuf,"SER")==0) || (strcmp((char*)RXBuf,"ser")==0))
		{
		RX1=0; 
		RXBuf[0]=0;
		a=eeprom_read_byte(&nvSERIAL);
		itoa(a,t,10);
		uart_queue_str(t);
		return;
		}
	if ((strcmp((char*)RXBuf,"MINAT")==0) || (strcmp((char*)RXBuf,"minat")==0))
		{
		RX1=0; 
		RXBuf[0]=0;
		itoa(MIN_ATTEN,t,10);
		uart_queue_str(t);
		return;
		}
	if ((strcmp((char*)RXBuf,"MAXAT")==0) || (strcmp((char*)RXBuf,"maxat")==0))
		{
		RX1=0; 
		RXBuf[0]=0;
		itoa(MAX_ATTEN,t,10);
		uart_queue_str(t);
		return;
		}
	if ((strcmp((char*)RXBuf,"MINST")==0) || (strcmp((char*)RXBuf,"minst")==0))
		{
		RX1=0; 
		RXBuf[0]=0;
		itoa(MIN_STEP,t,10);
		uart_queue_str(t);
		return;
		}
	if ((strcmp((char*)RXBuf,"AT")==0) || (strcmp((char*)RXBuf,"at")==0))
		{
		RX1=0; 
		RXBuf[0]=0;
		itoa(atten,t,10);
		uart_queue_str(t);
		return;
		}
	if ((strcmp((char*)RXBuf,"ST")==0) || (strcmp((char*)RXBuf,"st")==0))
		{
		RX1=0; 
		RXBuf[0]=0;
		itoa(pgm_read_byte(&steps[step]),t,10);
		uart_queue_str(t);
		return;
		}
	if ((strcmp((char*)RXBuf,"VB")==0) || (strcmp((char*)RXBuf,"vb")==0))
		{
		RX1=0; 
		RXBuf[0]=0;
		itoa(voltage,t,10);
		uart_queue_str(t);
		return;
		}
    if ((RXBuf[0]<0x30) || (RXBuf[0]>0x39)){
		RX1=0; 
		RXBuf[0]=0;
		uart_queue_str("illegal command");
		return;
		}
	a=atoi((char *)RXBuf);
	RXBuf[0]=0;
	RX1=0;
	if (a<0){
		uart_queue_str("underrun");
		return;
		}
	if (a>MAX_ATTEN){
		uart_queue_str("overrun");
		return;
		}
	atten=a;
	menu=MENU_ATT;
	select=0;
	channel='B';
	uart_queue_str("OK");
	}
}
