#include "bsp_uart.h"

/********************** 环形缓存区 *************************/
static const int  RxLen = 1024;
static volatile unsigned char RxBuf[RxLen];
static volatile unsigned char* RxW=RxBuf;
static volatile unsigned char* RxR=RxBuf;

void UART0_Push(unsigned char* p,int len)
{
	volatile unsigned char *W=RxW; //这里要与上面指针相同
	if(len<=0) return;
	for(int i=0;i<len;i++){
		W=RxW+1; if(W>=RxBuf+RxLen) W=RxBuf;        //取下一位置(到顶转到底)
		if(W!=RxR){*RxW=*(p+i); RxW=W;}
		else break;
	}
}

unsigned int UART0_CheckLen(void) //检查RX接收了多少数据
{   
	unsigned int Len; //short 
	volatile unsigned char *W=RxW; volatile unsigned char *R=RxR; 
	if(W>=R)Len=W-R;else Len=(W+RxLen)-R;         //这样正确(中途中断改变也变不了结果)
    return Len; 
}

unsigned char UART0_ReadByte(void)   //读RX中数锯,地指加一,和丢弃
{	
	unsigned char R=*RxR;       //读数
	if(RxR!=RxW){	if(RxR+1>=(RxBuf+RxLen))RxR =RxBuf; else RxR++;}//下标
	return R; 
}

unsigned char UART0_CheckByte(unsigned short n) //看RX中数锯,地指不变, 
{  	
	volatile unsigned char *R=RxR+n; 
	if(R>=(RxBuf+RxLen))R-=RxLen; 
	return *R; 
}	

void UART0_Discard(unsigned short n) //丢弃RX数据几位  
{	
	while(n){ n--;  
		if(RxR==RxW) return; 
		if(RxR+1>=RxBuf+RxLen){RxR=RxBuf;} else RxR++; //下标 
	}	
}

void UART0_SendChar(unsigned char ch)//发送一位数锯
{	
	NRF_UART0->TXD = (unsigned int)ch;
	while(NRF_UART0->EVENTS_TXDRDY == 0x0UL);
	NRF_UART0->EVENTS_TXDRDY = 0x0UL;
}	

void UART0_SendBuff(unsigned char *p,int L)//发送缓存
{	
	unsigned int len = L;
    while (len>0){len--;
		UART0_SendChar(*p++);
    }
}   

void UART0_SendStr(char *p)//发送字符串
{	
	while (*p){
		UART0_SendChar(*p++);
    }
} 

void UART0_Test(void)
{
	while(UART0_CheckLen()>0){
//		DEBUG_LOG("%02X ",UART0_ReadByte());
		DEBUG_LOG("%c",UART0_ReadByte());
	}
}

//*****************************************************************//
void UARTE0_UART0_IRQHandler(void)
{
	volatile unsigned char *W=RxW; //这里要与上面指针相同
	if(NRF_UART0->EVENTS_RXDRDY!=0){NRF_UART0->EVENTS_RXDRDY=0;	
		W=RxW+1; if(W>=RxBuf+RxLen) W=RxBuf;        //取下一位置(到顶转到底)
		if(W!=RxR){*RxW=NRF_UART0->RXD; RxW=W;}
	}
	if(NRF_UART0->EVENTS_RXTO!=0){NRF_UART0->EVENTS_RXTO=0;
		//DEBUG_LOG("EVENTS_RXTO\n");
	}
	if(NRF_UART0->EVENTS_CTS!=0){NRF_UART0->EVENTS_CTS=0;
		//DEBUG_LOG("EVENTS_CTS\n");
	}
	if(NRF_UART0->EVENTS_NCTS!=0){NRF_UART0->EVENTS_NCTS=0;
		//DEBUG_LOG("EVENTS_NCTS\n");
	}
	if(NRF_UART0->EVENTS_TXDRDY!=0){//NRF_UART0->EVENTS_TXDRDY=0;
		//DEBUG_LOG("EVENTS_TXDRDY\n");
	}
	if(NRF_UART0->EVENTS_ERROR!=0){NRF_UART0->EVENTS_ERROR=0;
		//DEBUG_LOG("EVENTS_ERROR=%d\n",NRF_UART0->EVENTS_ERROR);
	}
}





uint32_t get_baud(uint32_t baud)
{
	switch(baud){
		case 1200:		return UART_BAUDRATE_BAUDRATE_Baud1200; 	
		case 2400: 		return UART_BAUDRATE_BAUDRATE_Baud2400; 	
		case 4800: 		return UART_BAUDRATE_BAUDRATE_Baud4800; 	
		case 9600: 		return UART_BAUDRATE_BAUDRATE_Baud9600; 	
		case 14400: 	return UART_BAUDRATE_BAUDRATE_Baud14400; 	
		case 19200: 	return UART_BAUDRATE_BAUDRATE_Baud19200; 	
		case 28800: 	return UART_BAUDRATE_BAUDRATE_Baud28800; 	
		case 31250: 	return UART_BAUDRATE_BAUDRATE_Baud31250; 	
		case 38400: 	return UART_BAUDRATE_BAUDRATE_Baud38400; 	
		case 56000: 	return UART_BAUDRATE_BAUDRATE_Baud56000; 	
		case 57600: 	return UART_BAUDRATE_BAUDRATE_Baud57600; 	
		case 76800: 	return UART_BAUDRATE_BAUDRATE_Baud76800; 	
		case 115200: 	return UART_BAUDRATE_BAUDRATE_Baud115200; 	
		case 230400: 	return UART_BAUDRATE_BAUDRATE_Baud230400; 	
		case 250000: 	return UART_BAUDRATE_BAUDRATE_Baud250000; 	
		case 460800: 	return UART_BAUDRATE_BAUDRATE_Baud460800; 	
		case 921600: 	return UART_BAUDRATE_BAUDRATE_Baud921600; 	
		case 1000000: 	return UART_BAUDRATE_BAUDRATE_Baud1M; 		
		default: 		return UART_BAUDRATE_BAUDRATE_Baud115200; 	
	}
}

void UART0_Init(uint32_t baud)
{
	NRF_UART0->INTENCLR = UART_INTENCLR_CTS_Msk | UART_INTENCLR_RXTO_Msk | UART_INTENCLR_NCTS_Msk | UART_INTENCLR_ERROR_Msk;
	NRF_UART0->INTENSET = UART_INTENSET_RXDRDY_Enabled << UART_INTENSET_RXDRDY_Pos;
	NRF_UART0->PSELTXD = PIN_TXD_BLE;
	NRF_UART0->PSELRXD = PIN_RXD_BLE;
	
	NRF_UART0->BAUDRATE = get_baud(baud);
	NRF_UART0->ENABLE |= UART_ENABLE_ENABLE_Enabled;
	NRF_UART0->TASKS_STARTTX = 0XFFFFFFFF;
	NRF_UART0->TASKS_STARTRX = 0XFFFFFFFF;
	NVIC_SetPriority(UARTE0_UART0_IRQn, 7);
	NVIC_EnableIRQ(UARTE0_UART0_IRQn);
	NRF_UART0->EVENTS_TXDRDY = 0x0UL;
}

