#include "stdio.h"
#include "lprintf.h"
#include "chip.h"
#include "dev_pins.h"
#include "lprintf_config.h"

#define DEBUG_PORT_UART_NUM LPRINTF_UART_NUM

#define DEBUG_UART                     DEBUG_UART_NUM(DEBUG_PORT_UART_NUM)
#define DEBUG_UART_NUM(tnum)           _DEBUG_UART_NUM(tnum)
#if DEBUG_PORT_UART_NUM == 0 || DEBUG_PORT_UART_NUM == 5 || DEBUG_PORT_UART_NUM == 1 || DEBUG_PORT_UART_NUM == 2
    #define _DEBUG_UART_NUM(tnum)          USART##tnum
#else
    #define _DEBUG_UART_NUM(tnum)          USART##tnum
#endif

#define DEBUG_UART_RCU              DEBUG_UART_RCU_NUM(DEBUG_PORT_UART_NUM)
#define DEBUG_UART_RCU_NUM(tnum)    _DEBUG_UART_RCU_NUM(tnum)
#if DEBUG_PORT_UART_NUM == 0 || DEBUG_PORT_UART_NUM == 5 || DEBUG_PORT_UART_NUM == 1 || DEBUG_PORT_UART_NUM == 2
    #define _DEBUG_UART_RCU_NUM(tnum)   RCU_USART##tnum
#else
    #define _DEBUG_UART_RCU_NUM(tnum)   RCU_UART##tnum
#endif

int lprintf_uart_init(unsigned baud, unsigned databits, t_lprintf_uart_parity parity) {
    (void)(databits); // реализовано только 8 бит

    CHIP_PIN_CONFIG_AF(PIN_UART_DEBUG_RX);
    CHIP_PIN_CONFIG_AF(PIN_UART_DEBUG_TX);


    /* enable USART clock */
    rcu_periph_clock_enable(DEBUG_UART_RCU);

    /* USART configure */
    usart_deinit(DEBUG_UART);
    usart_baudrate_set(DEBUG_UART, baud);

    uint32_t paritycfg = USART_PM_NONE;
    if (parity==LPRINTF_UART_PARITY_ODD)
        paritycfg = USART_PM_ODD;
    else if (parity==LPRINTF_UART_PARITY_EVEN)
        paritycfg = USART_PM_EVEN;

    usart_parity_config(DEBUG_UART, paritycfg);
    usart_receive_config(DEBUG_UART, USART_RECEIVE_ENABLE);
    usart_transmit_config(DEBUG_UART, USART_TRANSMIT_ENABLE);
    usart_enable(DEBUG_UART);
    return 0;
}

/* TODO: возможно нужно реализовать для выхода в бутлоадер*/
void lprintf_close(void) {
}

void lprintf_putchar(char c) {
    while(RESET == usart_flag_get(DEBUG_UART, USART_FLAG_TBE));
    usart_data_transmit(DEBUG_UART, (uint8_t)c);
}
