| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- /*
- * @File name : driver_uart.c
- * @Author : Bluetrum IOT Team
- * @Date : 2023-02-14
- * @Description : This file provides functions to manage the most functionalities
- * of the UART peripheral.
- *
- * Copyright (c) by Bluetrum, All Rights Reserved.
- */
- #include "driver_uart.h"
- /**
- * @brief Initializes the uart peripheral according to the specified
- * parameters in the uart_init_struct.
- * @param uartx: where x can be (0..2) to select the uartx peripheral.
- * @param uart_init_struct: pointer to a uart_init_typedef structure that
- * contains the configuration information for the specified UART peripheral.
- * @retval None
- */
- void uart_init(uart_typedef *uartx, uart_init_typedef* uart_init_struct)
- {
- uint32_t tmp_reg, sys_clk_val, baud_reg;
- //---------- UART Controller Register ----------//
- tmp_reg = uartx->con;
- tmp_reg &= (uint32_t)(~UARTxCON_RXEN);
- tmp_reg &= (uint32_t)(~UARTxCON_ONELINE);
- tmp_reg &= (uint32_t)(~UARTxCON_BIT9EN);
- tmp_reg &= (uint32_t)(~UARTxCON_SB2EN);
- tmp_reg |= (uint32_t)(uart_init_struct->mode |
- uart_init_struct->one_line_enable |
- uart_init_struct->stop_bits |
- uart_init_struct->word_len);
- if (uartx == UART) {
- tmp_reg &= (uint32_t)(~UARTxCON_CLKSRC);
- tmp_reg |= (uint32_t)(uart_init_struct->clock_source);
- } else if (uartx == UDET) {
- tmp_reg &= (uint32_t)(~UARTxCON_FIXBAUD);
- tmp_reg |= (uint32_t)(uart_init_struct->baud_fix);
- }
- uartx->con = tmp_reg;
- if (uartx == UART) {
- //---------- UART Baud Configuration ----------//
- sys_clk_val = sys_clk_nhz_get();
- if (uart_init_struct->clock_source == UART_SYSTEM_CLOCK) {
- baud_reg = (uint16_t)((sys_clk_val / uart_init_struct->baud) - 1);
- } else {
- // uart clk is double frequency of the clock source when select uart_inc
- sys_clk_val = 2 * clk_uart_inc_get(CLK_VALUE_MODE_FREQ);
- baud_reg = (uint16_t)((sys_clk_val / uart_init_struct->baud) - 1);
- }
- tmp_reg = (uint32_t)((baud_reg << 16) | baud_reg);
- uartx->baud = tmp_reg;
- } else if (uartx == UDET && uart_init_struct->baud_fix == UART_BAUD_FIX) {
- sys_clk_val = clk_udet_clk_get(CLK_VALUE_MODE_FREQ);
- baud_reg = (uint16_t)((sys_clk_val / uart_init_struct->baud) - 1);
- uartx->baud = baud_reg;
- }
- }
- /**
- * @brief De-initialize the specified uart peripheral.
- * @param uartx: which uart need to config. it should the one of [UART or UDET].
- * @retval None
- */
- void uart_deinit(uart_typedef *uartx)
- {
- uartx->con = 0;
- if (uartx == UART) {
- clk_gate0_cmd(CLK_GATE0_UART, CLK_DIS);
- } else if (uartx == UDET) {
- clk_gate0_cmd(CLK_GATE0_UDET, CLK_DIS);
- }
- }
- /**
- * @brief Enable or disable the specified UART peripheral.
- * @param uartx: where x can be (0..2) to select the uartx peripheral.
- * @param state: the state of the UARTx peripheral.
- * this parameter can be: ENABLE or DISABLE.
- * @retval None
- */
- void uart_cmd(uart_typedef *uartx, FUNCTIONAL_STATE state)
- {
- if (state != DISABLE) {
- uartx->con |= UARTxCON_UTEN;
- } else {
- uartx->con &= (uint32_t)(~UARTxCON_UTEN);
- }
- }
- /**
- * @brief Transmits data through the UARTx peripheral.
- * @param uartx: where x can be (0..2) to select the uartx peripheral.
- * @param data: the data to transmit.
- * @retval None
- */
- AT(.com_periph.uart.send)
- void uart_send_data(uart_typedef *uartx, uint16_t data)
- {
- uartx->data = (data & (uint16_t)0xff);
- }
- /**
- * @brief Return the received data lastly by the UARTx peripheral.
- * @param uartx: where x can be (0..2) to select the uartx peripheral.
- * @retval The received data.
- */
- AT(.com_periph.uart.recv)
- uint16_t uart_receive_data(uart_typedef *uartx)
- {
- if (uartx->con & UARTxCON_BIT9EN) {
- return (uartx->data & (uint16_t)0x1ff);
- } else {
- return (uartx->data & (uint16_t)0xff);
- }
- }
- /**
- * @brief Enable or disable the specified UARTx interrupt.
- * @param uartx: where x can be (0..2) to select the uartx peripheral.
- * @param isr: Function to be executed for service interruption.
- * @param pr: Priority of service interruption.
- * @param interrupt_type: specifies the UART interrupt sources to be enable or disable.
- * this parameter can be one of the following values:
- * @arg UART_IT_TX: Transmit single data finish interrupt enable bit.
- * @arg UART_IT_RX: Receive single data finish interrupt enable bit.
- * @arg UART_IT_ERR: Raise error interrupt enable bit.
- * @arg UART_IT_KEY: Match key interrupt enable bit.
- * @arg UART_IT_RSTKEY: Reset match key interrupt enable bit.
- * @param state: the state of the UARTx peripheral.
- * this parameter can be: ENABLE or DISABLE.
- * @retval None
- */
- void uart_pic_config(uart_typedef *uartx, isr_t isr, int pr, UART_IT_TYPEDEF interrupt_type, FUNCTIONAL_STATE state)
- {
- uint32_t interrupt_con_bit = 0;
- uint32_t all_interrupt_type_mask = UART_IT_TX | UART_IT_RX | UART_IT_ERR | UART_IT_KEY | UART_IT_RSTKEY;
- if (interrupt_type == 0) {
- return;
- }
- if (interrupt_type & UART_IT_TX) {
- interrupt_con_bit |= UARTxCON_TXIE;
- }
- if (interrupt_type & UART_IT_RX) {
- interrupt_con_bit |= UARTxCON_RXIE;
- }
- if (interrupt_type & UART_IT_ERR) {
- }
- if (interrupt_type & UART_IT_KEY) {
- }
- if (interrupt_type & UART_IT_RSTKEY) {
- }
- if (state != DISABLE) {
- sys_irq_init(IRQn_UART0_UDET, pr, isr);
- uartx->con |= interrupt_con_bit;
- } else {
- uartx->con &= ~interrupt_con_bit;
- if (interrupt_type == all_interrupt_type_mask) {
- PICEN &= ~BIT(IRQn_UART0_UDET);
- }
- }
- }
- /**
- * @brief Check the specified UART flag is set or not.
- * @param uartx: where x can be (0..2) to select the uartx peripheral.
- * @param interrupt_type: specifies the flag to check.
- * this parameter can be one of the following values:
- * @arg UART_IT_TX: Transmit single data finish interrupt enable bit.
- * @arg UART_IT_RX: Receive single data finish interrupt enable bit.
- * @arg UART_IT_ERR: Raise error interrupt enable bit.
- * @arg UART_IT_KEY: Match key interrupt enable bit.
- * @arg UART_IT_RSTKEY: Reset match key interrupt enable bit.
- * @retval The state of uart_flag (SET or RESET).
- */
- AT(.com_periph.uart.get_flag)
- FLAG_STATE uart_get_flag(uart_typedef *uartx, UART_IT_TYPEDEF interrupt_type)
- {
- uint32_t interrupt_con_bit = 0;
- if (interrupt_type & UART_IT_TX) {
- interrupt_con_bit |= UARTxCON_TXPND;
- }
- if (interrupt_type & UART_IT_RX) {
- interrupt_con_bit |= UARTxCON_RXPND;
- }
- if (interrupt_type & UART_IT_ERR) {
- }
- if (interrupt_type & UART_IT_KEY) {
- }
- if (interrupt_type & UART_IT_RSTKEY) {
- }
- if ((uartx->con & interrupt_con_bit) != RESET) {
- return SET;
- } else {
- return RESET;
- }
- }
- /**
- * @brief Clear the UART's pending flag.
- * @param uartx: where x can be (0..2) to select the uartx peripheral.
- * @param interrupt_type: specifies the flag to check.
- * this parameter can be one of the following values:
- * @arg UART_IT_TX: Transmit single data finish interrupt enable bit.
- * @arg UART_IT_RX: Receive single data finish interrupt enable bit.
- * @arg UART_IT_ERR: Raise error interrupt enable bit.
- * @arg UART_IT_KEY: Match key interrupt enable bit.
- * @arg UART_IT_RSTKEY: Reset match key interrupt enable bit.
- * @retval None
- */
- AT(.com_periph.uart.clear_flag)
- void uart_clear_flag(uart_typedef *uartx, UART_IT_TYPEDEF interrupt_type)
- {
- uint32_t interrupt_con_bit = 0;
- if (interrupt_type & UART_IT_TX) {
- interrupt_con_bit |= UARTxCPND_CTXPND;
- }
- if (interrupt_type & UART_IT_RX) {
- interrupt_con_bit |= UARTxCPND_CRXPND;
- }
- if (interrupt_type & UART_IT_ERR) {
- interrupt_con_bit |= UARTxCPND_RX4BUF_ERR_CLR;
- }
- if (interrupt_type & UART_IT_KEY) {
- interrupt_con_bit |= UARTxCPND_CKEYPND;
- }
- if (interrupt_type & UART_IT_RSTKEY) {
- interrupt_con_bit |= UARTxCPND_CRSTKEYPND;
- }
- uartx->cpnd |= interrupt_con_bit;
- }
- /**
- * @brief Config the baud rate of the serial port.
- * @param uartx: The uart that need to config.
- * @param baud: The baudrate value need to set.
- * @retval None
- */
- void uart_baud_config(uart_typedef *uartx, uint32_t baud)
- {
- uint32_t clk_val, baud_reg;
- if (uartx->con & UARTxCON_UTEN)
- while ((uartx->con & UARTxCON_TXPND) == 0);
- if (uartx == UART) {
- if ((uartx->con & UARTxCON_CLKSRC) == 0) { // if select is sys clk
- clk_val = sys_clk_nhz_get();
- } else { // if select is inc clk
- clk_val = 2 * clk_uart_inc_get(CLK_VALUE_MODE_FREQ); // uart clk is double frequency of the clock source when select uart_inc
- }
- baud_reg = (uint16_t)((clk_val / baud) - 1);
- uartx->baud = (uint32_t)((baud_reg << 16) | baud_reg);
- } else if (uartx == UDET && (uartx->con & UARTxCON_FIXBAUD)) {
- clk_val = clk_udet_clk_get(CLK_VALUE_MODE_FREQ);
- baud_reg = (uint16_t)((clk_val / baud) - 1);
- uartx->baud = baud_reg;
- }
- }
|