#include "can_uart.h"


/*****************************************************************************
 * Private types/enumerations/variables
 ****************************************************************************/

/* Transmit and receive ring buffers */
STATIC RINGBUFF_T txring, rxring;

/* Transmit and receive ring buffer sizes */
#define UART_SRB_SIZE 128	/* Send */
#define UART_RRB_SIZE 32	/* Receive */

/* Transmit and receive buffers */
static uint8_t rxbuff[UART_RRB_SIZE], txbuff[UART_SRB_SIZE];

const char inst1[] = "LPC11xx UART example using ring buffers\r\n";
const char inst2[] = "Press a key to echo it back or ESC to quit\r\n";

/*****************************************************************************
 * Public types/enumerations/variables
 ****************************************************************************/

/*****************************************************************************
 * Private functions
 ****************************************************************************/

static void Init_UART_PinMux(void)
{
#if (defined(BOARD_NXP_XPRESSO_11U14) || defined(BOARD_NGX_BLUEBOARD_11U24))
	Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 18, IOCON_FUNC1 | IOCON_MODE_INACT);	/* PIO0_18 used for RXD */
	Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 19, IOCON_FUNC1 | IOCON_MODE_INACT);	/* PIO0_19 used for TXD */
#elif (defined(BOARD_NXP_XPRESSO_11C24) || defined(BOARD_MCORE48_1125))
	Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO1_6, (IOCON_FUNC1 | IOCON_MODE_INACT));/* RXD */
	Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO1_7, (IOCON_FUNC1 | IOCON_MODE_INACT));/* TXD */
#else
#error "No Pin muxing defined for UART operation"
#endif
}

/*****************************************************************************
 * Public functions
 ****************************************************************************/

/**
 * @brief	UART interrupt handler using ring buffers
 * @return	Nothing
 */
void UART_IRQHandler(void)
{
	/* Want to handle any errors? Do it here. */

	/* Use default ring buffer handler. Override this with your own
	   code if you need more capability. */
	Chip_UART_IRQRBHandler(LPC_USART, &rxring, &txring);
}

void UART_Init(void)
{
	Init_UART_PinMux();
	/* Setup UART for 115.2K8N1 */
	Chip_UART_Init(LPC_USART);
	Chip_UART_SetBaud(LPC_USART, 115200);
	Chip_UART_ConfigData(LPC_USART, (UART_LCR_WLEN8 | UART_LCR_SBS_1BIT));
	Chip_UART_SetupFIFOS(LPC_USART, (UART_FCR_FIFO_EN | UART_FCR_TRG_LEV2));
	Chip_UART_TXEnable(LPC_USART);

	/* Before using the ring buffers, initialize them using the ring
	   buffer init function */
	//建立环形缓冲区，参数1为缓冲区结构体，参数2为缓冲区数据，参数3为缓冲区每个数的size，参数4为有效数据的个数
	RingBuffer_Init(&rxring, rxbuff, 1, UART_RRB_SIZE);
	RingBuffer_Init(&txring, txbuff, 1, UART_SRB_SIZE);

	/* Enable receive data and line status interrupt */
	Chip_UART_IntEnable(LPC_USART, (UART_IER_RBRINT | UART_IER_RLSINT));

	/* preemption = 1, sub-priority = 1 */
	NVIC_SetPriority(UART0_IRQn, 1);
	NVIC_EnableIRQ(UART0_IRQn);

	/* Send initial messages */
	//Chip_UART_SendRB(LPC_USART, &txring, inst1, sizeof(inst1) - 1);
	//Chip_UART_SendRB(LPC_USART, &txring, inst2, sizeof(inst2) - 1);
}




void DB_PutCANMsgInfo (uint32_t * p_add)
{
     uint32_t  msg_id;

	    
	    DB_PutStr("Sended CAN message as below:\n\r\n\r");

	    msg_id=*p_add++;
	    if (msg_id & (0x1<<30))	   //extended frame
	    {
                msg_id &= ~ (0x1<<30);
	         DB_PutStr("Extended frame ID: ");
	    }
	    else
	         DB_PutStr("Standard frame ID: ");
			
	     DB_PutHex(msg_id, 32);
						DB_PutStr("\n\r\n\r");
            DB_PutStr("Data Length: ");
	     DB_PutHex(*p_add++, 8);
						DB_PutStr("\n\r\n\r");
            DB_PutStr("Data: ");
	     DB_PutDec(*p_add++);
            DB_PutStr(",  ");
	     DB_PutDec(*p_add++);
            DB_PutStr(",  ");
	     DB_PutDec(*p_add++);
            DB_PutStr(",  ");
	     DB_PutDec(*p_add);
						DB_PutStr("\n\r\n\r\n\r");
						
}

void db_putchar (uint8_t ch)
{
  LPC_USART->THR = ch;
	while(!(LPC_USART->LSR&(0x01<<5)))
	{
		;
	}
}

void DB_PutChar(uint8_t ch)
{
   db_putchar(ch);
}

void DB_PutStr(const void *str)
{
    uint8_t *s = (uint8_t *) str;

    while (*s){
        db_putchar(*s++);
    }
}

/**
  * @brief    Puts a hex number to UART port
  * @param hexnum   Hex number
  * @param type        0:no limit; 8: 8bit; 16: 16bit; 32:32bit 
  * @return None
  */
void DB_PutHex (uint32_t hexnum, uint8_t type)
{
    uint8_t     buff[16];   
    uint32_t    i = 0;
    uint32_t    k = 1;

    db_putchar('0');
    db_putchar('x');

    while(hexnum){
        buff[i++] = hexnum % 16;            
        hexnum = hexnum / 16;
    }
    i--;

    if(type == 8){
       k = 1;
    }else if(type == 16){
       k = 3;
    }else if(type == 32){
       k = 7;
    }else{
       k = i;   
    }   

    while( (k-i) > 0 ){
        db_putchar('0');
        k--;
    }

    while( (i+1) > 0 ){
        if( buff[i] <= 9 ){
            db_putchar(buff[i] + '0');          
        }else{
            db_putchar((buff[i]-10) + 'A');         
        }   
        if(i == 0)break;
        i--;
    }   
}


/**
  * @brief    Puts a decimal number to UART port
  * @param decnum   Decimal number (8-bit long)
  * @return  None
  */
void DB_PutDec(uint32_t decnum)
{
    uint8_t     buff[16];
    uint32_t    i = 0;

    if(decnum == 0){
        buff[0] = 0;
        i = 1;
    }
    while(decnum){
        buff[i++] = decnum % 10;
        decnum = decnum / 10;
    }

    while( i > 0 ){
        db_putchar((buff[i-1] + '0'));
        if(i == 0)break;
        i--;
    }
}


uint8_t DB_GetChar(void)
{
	uint8_t data;
	while(!(LPC_USART->LSR&0x01))
	{
		;
	}
	data = LPC_USART->RBR;
	return data;		
}



uint8_t* DB_GetString(void)
{
	uint8_t *str = 0;
	uint8_t i=1;
	str[0]=DB_GetChar();
	while(str[i-1]!='\0')
	{
		str[i] = DB_GetChar();
		i++;

	}
	DB_PutStr(str);
	return str;
	
}

/******************************************************************************
**                            End Of File
******************************************************************************/
