#include "include.h"
#include "bsp_huart.h"
#include "api.h"
#include "driver_com.h"
#include "driver_hsuart.h"
#include "ble_init.h"

#if LE_DUT_UART_EN

//#define LE_FCC_TONE_EN
#ifdef LE_FCC_TONE_EN
static fcc_cfg_t fcc_cfg;
#endif

ALIGNED(4)
u8 huart_buffer[128];


AT(.com_text.huart.text)
void huart_wait_txdone(void)
{
    while (hsuart_get_flag(HSUART_IT_TX) == RESET);
}

///设置HUART波特率
AT(.text.huart.huart_set_baudrate)
void huart_set_baudrate(uint baud_rate)
{
    hsuart_baud_config(baud_rate);
}

///HUART 发送1Byte数据
AT(.com_text.huart.text)
void huart_putchar(const char ch)
{
    while (hsuart_get_flag(HSUART_IT_TX) == RESET);
    hsuart_send_data((uint16_t)ch);

}

///HUART 获取RXFIFO中的数据个数
AT(.com_text.huart.huart_getchar)
uint huart_get_rxcnt(void)
{
    return hsuart_get_fifo_counter();
}

///HUART 获取1Byte数据
AT(.com_text.huart.huart_getchar)
char huart_getchar(void)
{
    char data = 0;

    hsuart_receive_data_from_fifo((uint8_t *)&data, 1);

    return data;
}

///HUART 发送数据
AT(.com_text.huart.text)
void huart_tx(const void *buf, uint len)
{
    huart_wait_txdone();

    if ((u32)buf >= 0x10000000) {
        HSUT0CON &= ~BIT(7);        //buf mode
        const char *txbuf = buf;
        while (len--) {
            huart_putchar(*txbuf++);
        }
    } else {
        HSUT0CON |= BIT(7);         //dma mode
        hsuart_dma_start(HSUT_TRANSMIT, DMA_ADR(buf), len);
    }
}

void bt_uart_init(void)
{
    gpio_init_typedef gpio_init_structure;
    hsuart_init_typedef hsuart_init_struct;

    clk_gate0_cmd(CLK_GATE0_HSUART, CLK_EN);

/************************************ GPIO Init ************************************/
    if (ble_get_work_mode() == MODE_FCC_TEST) {
        gpio_init_structure.gpio_pin = HSUART_FCC_PIN_SEL;
        gpio_init_structure.gpio_dir = GPIO_DIR_INPUT;
        gpio_init_structure.gpio_fen = GPIO_FEN_PER;
        gpio_init_structure.gpio_fdir = GPIO_FDIR_MAP;
        gpio_init_structure.gpio_mode = GPIO_MODE_DIGITAL;
        gpio_init_structure.gpio_pupd = GPIO_PUPD_PU10K;
        gpio_init(HSUART_FCC_PORT_SEL, &gpio_init_structure);

        /* NOTE: make sure printf_io isn't using PB3 */
        gpio_func_mapping_clear(HSUART_FCC_PORT_SEL, HSUART_FCC_PIN_SEL);
        gpio_func_mapping_config(HSUART_FCC_PORT_SEL, HSUART_FCC_PIN_SEL, GPIO_CROSSBAR_IN_HURRX);
        gpio_func_mapping_config(HSUART_FCC_PORT_SEL, HSUART_FCC_PIN_SEL, GPIO_CROSSBAR_OUT_HURTX);
    } else if (ble_get_work_mode() == MODE_BQB_RF_BLE) {
        gpio_init_structure.gpio_pin = HSUART_BQB_RX_PIN_SEL;
        gpio_init_structure.gpio_dir = GPIO_DIR_INPUT;
        gpio_init_structure.gpio_fen = GPIO_FEN_PER;
        gpio_init_structure.gpio_fdir = GPIO_FDIR_SELF;
        gpio_init_structure.gpio_mode = GPIO_MODE_DIGITAL;
        gpio_init_structure.gpio_pupd = GPIO_PUPD_PU10K;
        gpio_init(HSUART_BQB_RX_PORT_SEL, &gpio_init_structure);

        gpio_init_structure.gpio_pin = HSUART_BQB_TX_PIN_SEL;
        gpio_init_structure.gpio_dir = GPIO_DIR_OUTPUT;
        gpio_init_structure.gpio_fdir = GPIO_FDIR_SELF;
        gpio_init_structure.gpio_drv = GPIO_DRV_6MA;
        gpio_init(HSUART_BQB_TX_PORT_SEL, &gpio_init_structure);

        gpio_func_mapping_config(HSUART_BQB_RX_PORT_SEL, HSUART_BQB_RX_PIN_SEL, GPIO_CROSSBAR_IN_HURRX);
        gpio_func_mapping_config(HSUART_BQB_TX_PORT_SEL, HSUART_BQB_TX_PIN_SEL, GPIO_CROSSBAR_OUT_HURTX);
    }

/*********************************** HSUART Init ***********************************/
    if (ble_get_work_mode() == MODE_FCC_TEST) {
        hsuart_init_struct.baud = HSUART_FCC_BAUD;
        hsuart_init_struct.one_line_en = HSUT_ONELINE_EN;
    } else if (ble_get_work_mode() == MODE_BQB_RF_BLE) {
        hsuart_init_struct.baud = HSUART_BQB_BAUD;
        hsuart_init_struct.one_line_en = HSUT_ONELINE_DIS;
    }
    hsuart_init_struct.tx_mode = HSUT_TX_DMA_MODE;
    hsuart_init_struct.rx_mode = HSUT_RX_DMA_MODE;
    hsuart_init_struct.tx_stop_bit = HSUT_STOP_BIT_2BIT;
    hsuart_init_struct.tx_word_len = HSUT_TX_LENGTH_8b;
    hsuart_init_struct.rx_word_len = HSUT_RX_LENGTH_8b;
    hsuart_init_struct.clk_source = HSUT_24M_CLK;
    hsuart_init_struct.rx_dma_buf_mode = HSUT_DMA_BUF_LOOP;
    hsuart_init(&hsuart_init_struct);

    hsuart_clear_flag(HSUART_IT_RX);

    hsuart_cmd(HSUT_TRANSMIT | HSUT_RECEIVE, ENABLE);

    hsuart_dma_start(HSUT_RECEIVE, (uint32_t)huart_buffer, 128);

#ifdef LE_FCC_TONE_EN
    if (ble_get_work_mode() == MODE_FCC_TEST) {
        fcc_cfg.rf_mode = FCC_TX_TONE;
        fcc_cfg.tx_power = 7;
        fcc_cfg.tx_freq = 1;
        fcc_cfg.todo = 1;
        ble_fcc_cfg_init(&fcc_cfg);
    }
#endif
}

void bt_uart_exit(void)
{
}
#endif
