#include "platform.h"
#include <stdio.h>
#include <stdarg.h>
#include "hal_headfile.h"
#include "board.h"
#include "debug.h"
#include "config.h"

int put_free(int c);

#ifdef USING_BOARD_DBUART

void debug_uart_init(void)
{
	user_function_def *addr = HARD_WARE_CFG_ADDR;
	//if(addr->codec_bus == NONE_BUS)
	if(1)
	{
	    DEV_RMU->RSTEN0 &= ~DEV_RMU_RSTEN0_UART0;
		DEV_CMU->CLKEN0 &= ~DEV_CMU_CLKEN0_UART0;
		DEV_CMU->CLKEN0 |= DEV_CMU_CLKEN0_UART0;
		DEV_CMU->UARTnCLK[0] = DEV_CMU_UARTnCLK_SEL_OSC_XTAL;
		DEV_RMU->RSTEN0 |= DEV_RMU_RSTEN0_UART0;
		DEV_GPIO->CTL[DBUART_PIN] = 3;      //TX

#ifdef DDUART_RXD_PIN
		DEV_GPIO->CTL[DDUART_RXD_PIN] = 3;      //RX
#endif

		DBUART0->CFG =
			DEV_UARTn_CFG_DATA_WIDTH_8BIT |
			DEV_UARTn_CFG_STOP_BIT_1BIT |
			(1 << 12) |
			(1 << 8);
		uint32_t baud_div = 24000000 / DBUART_BAUD - 1;
		DBUART0->DIV = baud_div | (baud_div << 16);
		DBUART0->CTL = DEV_UARTn_CTL_TX_EN_ENABLE;

#ifdef DDUART_RXD_PIN
		DBUART0->CTL |= DEV_UARTn_CTL_RX_EN_ENABLE;
		DBUART0->PD  =  DEV_UARTn_PD_RX_FIFO_THR;
		DBUART0->IE  |= DEV_UARTn_IE_RX_FIFO_THR;
#endif

		DEV_GLOBAL->DVDD_GLOBAL4 = (uint32_t)putchar;
	}
	else
	{
		DEV_GLOBAL->DVDD_GLOBAL4 = (uint32_t)put_free;
	}
}

int putchar(int c)
{
    while (DBUART0->STA & DEV_UARTn_STA_TX_FIFO_FULL);
    DBUART0->TX_DAT = c;
    return c;
}

int put_free(int c)
{
	return c;
}

void debug_puts_hex(uint8_t *addr, uint32_t len)
{
    for (uint32_t i = 0; i < len; i++)
    {
        while (DBUART0->STA & DEV_UARTn_STA_TX_FIFO_FULL);

        DBUART0->TX_DAT = addr[i];
    }
}

void debug_console_putc(char c)
{
    while (DBUART0->STA & DEV_UARTn_STA_TX_FIFO_FULL);

    DBUART0->TX_DAT = c;
}

void debug_console_sendstr(const char *string)
{
    while (*string)
    {
        debug_console_putc(*string++);
    }
}

/*uart0 as deubg port*/
void printk(const char *fmt, ...)
{
    va_list ap;
    char string[128];
    va_start(ap, fmt);
    vsprintf(string, fmt, ap);
    string[127] = 0;
    debug_console_sendstr(string);
    va_end(ap);
}

void show_uart_wave(uint16_t ch0, uint16_t ch1, uint16_t ch2, uint16_t ch3, uint16_t ch4)
{
    uint16_t sum = 0;
    uint8_t send_arry[20] = {0};
    send_arry[0] = 0XAA;
    send_arry[1] = ch0;
    send_arry[2] = ch0 >> 8;
    send_arry[3] = ch1;
    send_arry[4] = ch1 >> 8;
    send_arry[5] = ch2;
    send_arry[6] = ch2 >> 8;
    send_arry[7] = ch3;
    send_arry[8] = ch3 >> 8;
    send_arry[9] = ch4;
    send_arry[10] = ch4 >> 8;

    for (uint16_t i = 1; i < 17; i++)
    {
        sum += send_arry[i];
    }

    send_arry[17] = sum;
    send_arry[18] = sum >> 8;
    send_arry[19] = 0xBB;
    debug_puts_hex((uint8_t *)send_arry, 20);
}

#ifdef DDUART_RXD_PIN
void uart0_rxd_listen_handle(void)
{
	uint8_t data;
    if ((DEV_UART0->PD & DEV_UARTn_PD_RX_FIFO_THR) == DEV_UARTn_PD_RX_FIFO_THR)
    {
    	data = DEV_UART0->RX_DAT;
        DEV_UART0->PD = DEV_UARTn_PD_RX_FIFO_THR;
        debug_console_putc(data);
    }
}
#endif

#else
int put_free(int c)
{
	return c;
}

void debug_uart_init(void)
{
	DEV_GLOBAL->DVDD_GLOBAL4 = (uint32_t)put_free;
}

void printk(const char *fmt, ...)
{
    ;
}

int putchar(int c)
{
    return c;
}
#endif
