/*! * \file xc6xxx_hal_uart.c * * \brief Target xc6xxx hal uart implementation * * \copyright Revised BSD License, see section \ref LICENSE. * * \code * * _ __ _ ________ _ * | |/ /(_)___ / ____/ /_ (_)___ * | // / __ \/ / / __ \/ / __ \ * / |/ / / / / /___/ / / / / /_/ / * /_/|_/_/_/ /_/\____/_/ /_/_/ .___/ * /_/ * (C) 2022-2025 XinChip * * \endcode * * \author ( XinChip ) Alex-J * * \author ( XinChip ) */ /*----------------------------------------------------------------------------------- INCLUDE HEADE FILES ------------------------------------------------------------------------------------*/ #include "xc_drv_uart.h" /*------------------------------------------------------------------------------------ Macros -------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------ Local Variables -------------------------------------------------------------------------------------*/ uint8_t __attribute__((aligned(4))) uart_txdmabuff[UART_BUFF_LEN]; uint8_t __attribute__((aligned(4))) uart_rxdmabuff[UART_BUFF_LEN]; UART_Block_t uart_ctl_block; bool buffer_complet_flag = 0; /*------------------------------------------------------------------------------------ Func Prototype -------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------ Functions -------------------------------------------------------------------------------------*/ void xc_uart_init(uint8_t reg_idx, UART_InitCfg_t *uart_cfg) { uint32_t val; uint32_t uart_clk = 0x00; uint32_t div, mul, clk_ctl, adj_div, m0_fclk_div; m0_fclk_div = cpr_m0_fclk_ctl__m0_fclk_div__getf(); uart_clk = xc_clock_hfclk_in_get() * (m0_fclk_div + 1); mul = (uart_cfg->BaudRate >> 20) & 0xFFFF; div = (uart_cfg->BaudRate >> 4) & 0xFFFF; adj_div = uart_clk / 1000000; clk_ctl = (mul << 16) | (div * adj_div / 32); if (reg_idx == UART0_IDX) { cpr_rstctl_subrst_sw__uart0_rstn__setf(RSTCTL_ENABLE); cpr_rstctl_subrst_sw__uart0_rstn__setf(RSTCTL_DISABLE); val = cpr_lp_ctl_get(); val &= ~(UART0_CLK_OFF_PROTECT_EN_BIT); cpr_lp_ctl_set(val); cpr_ctlapbclken_grctl__uart0_pclk_en__setf(ENABLE); cpr_uart0_clk_grctl__uart0_clk_gr__setf(8); cpr_uart0_clk_grctl__uart0_clk_gr_upd__setf(ENABLE); cpr_uart0_clk_ctl_set(clk_ctl); } if (reg_idx == UART1_IDX) { cpr_rstctl_subrst_sw__uart1_rstn__setf(RSTCTL_ENABLE); cpr_rstctl_subrst_sw__uart1_rstn__setf(RSTCTL_DISABLE); val = cpr_lp_ctl_get(); val &= ~(UART1_CLK_OFF_PROTECT_EN_BIT); cpr_lp_ctl_set(val); cpr_ctlapbclken_grctl__uart1_pclk_en__setf(ENABLE); cpr_uart1_clk_grctl__uart1_clk_gr__setf(8); cpr_uart1_clk_grctl__uart1_clk_gr_upd__setf(ENABLE); cpr_uart1_clk_ctl_set(clk_ctl); } if (reg_idx == UART2_IDX) { cpr_rstctl_subrst_sw__uart2_rstn__setf(RSTCTL_ENABLE); cpr_rstctl_subrst_sw__uart2_rstn__setf(RSTCTL_DISABLE); cpr_uart2_clk_grctl__uart2_pclk_en__setf(ENABLE); cpr_uart2_clk_grctl__uart2_clk_gr__setf(8); cpr_uart2_clk_grctl__uart2_clk_gr_upd__setf(ENABLE); cpr_uart2_clk_ctl_set(clk_ctl); } uart_tcr__dlab__setf(reg_idx, UART_TCR_DLAB_DLLH_ENABLE); uart_dll__dll__setf(reg_idx, (uart_cfg->BaudRate & 0xF)); uart_ier_set(reg_idx, 0); uart_tcr__dlab__setf(reg_idx, UART_TCR_DLAB_DLLH_DISABLE); while (uart_usr_get(reg_idx) == 1) { }; uart_tcr__eps__setf(reg_idx, uart_cfg->Parity); uart_tcr__stop__setf(reg_idx, uart_cfg->StopBits); uart_tcr__cls__setf(reg_idx, uart_cfg->WordLength); uart_mcr__afce__setf(reg_idx, uart_cfg->HardwareFlowControl); uart_fcr_pack(reg_idx, UART_FCR_RCVR_TRIGGER_FIFO_2_1, UART_FCR_TX_EMPTY_TRIGGER_FIFO_2_1, UART_FCR_XMIT_FIFO_RESET_CLEAR, UART_FCR_RCVR_FIFO_RESET_CLEAR, UART_FCR_FIFO_ENABLE_ENABLE); } void xc_uart_enable_rx_it(uint8_t reg_idx) { uart_ier__erdai__setf(reg_idx, UART_IER_ERDAI_ENABLE); } void xc_uart_disable_rx_it(uint8_t reg_idx) { uart_ier__erdai__setf(reg_idx, UART_IER_ERDAI_DISABLE); } void xc_uart_send_byte(uint8_t reg_idx, uint8_t byte) { while (1) { if (uart_tsr__thre__getf(reg_idx) & UART_TSR_THRE_VALID) { break; } } uart_thr__thr__setf(reg_idx, byte); } void xc_uart_send_data(uint8_t reg_idx, uint8_t *data, uint16_t len) { for (int i = 0; i < len; i++) { xc_uart_send_byte(reg_idx, data[i]); } } void xc_uart_ctl_block_reset(void) { memset(&uart_ctl_block, 0, sizeof(uart_ctl_block)); uart_ctl_block.uart_receive_cb = NULL; } void xc_uart_register_receive_cb(uart_handler_callback uart_cb) { uart_ctl_block.uart_receive_cb = uart_cb; } __WEAK void uart_user_handler(uint8_t reg_idx) { uint8_t rx_val; uint32_t IIR, TSR; IIR = uart_iir__iid__getf(reg_idx); TSR = uart_tsr_get(reg_idx); if (((IIR & IID_MASK) == UART_IIR_IID_BUSY)) { uart_usr_get(reg_idx); } if (((IIR & IID_MASK) == UART_IIR_IID_ETSI)) { DEBUG("line=%d, error handle \n", __LINE__); } if (((IIR & IID_MASK) == UART_IIR_IID_ERDAI)) { TSR = uart_tsr_get(reg_idx); while ((TSR & UART_TSR_DR_VALID) == UART_TSR_DR_VALID) { rx_val = uart_rbr__rbr__getf(reg_idx); TSR = uart_tsr_get(reg_idx); if (uart_ctl_block.uart_receive_cb != NULL) { uart_ctl_block.uart_receive_cb(&rx_val, 1); } } } if ((IIR & IID_MASK) == UART_IIR_IID_TO) { TSR = uart_tsr_get(reg_idx); while ((TSR & UART_TSR_DR_VALID) == UART_TSR_DR_VALID) { rx_val = uart_rbr__rbr__getf(reg_idx); TSR = uart_tsr_get(reg_idx); if (uart_ctl_block.uart_receive_cb != NULL) { uart_ctl_block.uart_receive_cb(&rx_val, 1); } } } } void UART0_Handler(void) { uart_user_handler(UART0_IDX); } void UART1_Handler(void) { uart_user_handler(UART1_IDX); } void UART2_Handler(void) { uart_user_handler(UART2_IDX); }