📄 uart.c
字号:
/*******************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained herein
* is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of INFOMAX COMMUNICATION CO.,LTD.
* * MODULE NAME: * DESCRIPTION: * AUTHOR: * BEGIN DATE: * LAST MODIFICATION: *****************************************************************************//******************************************************************************* Include/header files *******************************************************************************/#include "uart.h"#include "magic_reg_defs.h"
#include "magic_env.h"/******************************************************************************* Constant/Marco*******************************************************************************//******************************************************************************* Structure/Union/Enum/Typedef *******************************************************************************//******************************************************************************* Local function prototype *******************************************************************************/void set_baud_rate( const uart_port_no_t port_no, uart_baud_rate_t baud_rate);/******************************************************************************* Global/Local variables *******************************************************************************/REG_ADDR UART_RBR_REG[3]={UART1_RBR_REG, UART2_RBR_REG, UART3_RBR_REG}; /* Receive Buffer Register */
REG_ADDR UART_THR_REG[3]={UART1_THR_REG, UART2_THR_REG, UART3_THR_REG}; /* Transmit Holding Register */
REG_ADDR UART_DLL_REG[3]={UART1_DLL_REG, UART2_DLL_REG, UART3_DLL_REG}; /* Divisor Latch(Low) Register */
REG_ADDR UART_IER_REG[3]={UART1_IER_REG, UART2_IER_REG, UART3_IER_REG}; /* Interrupt Enable Register */
REG_ADDR UART_DLH_REG[3]={UART1_DLH_REG, UART2_DLH_REG, UART3_DLH_REG}; /* Divisor Latch(High) Register */
REG_ADDR UART_IIR_REG[3]={UART1_IIR_REG, UART2_IIR_REG, UART3_IIR_REG}; /* Interrupt Identity Register */
REG_ADDR UART_FCR_REG[3]={UART1_FCR_REG, UART2_FCR_REG, UART3_FCR_REG}; /* FIFO Control Reigster */
REG_ADDR UART_LCR_REG[3]={UART1_LCR_REG, UART2_LCR_REG, UART3_LCR_REG}; /* Line Control Register */
REG_ADDR UART_MCR_REG[3]={UART1_MCR_REG, UART2_MCR_REG, UART3_MCR_REG}; /* Modem Control Register */
REG_ADDR UART_LSR_REG[3]={UART1_LSR_REG, UART2_LSR_REG, UART3_LSR_REG}; /* Line Status Register */
REG_ADDR UART_MSR_REG[3]={UART1_MSR_REG, UART2_MSR_REG, UART3_MSR_REG}; /* Modem Status Register */
REG_ADDR UART_ECR_REG[3]={UART1_ECR_REG, UART2_ECR_REG, UART3_ECR_REG}; /* Error Compensation Register */
static const UINT32 BaudRateTbl[] =
{
UART_DIV_110,
UART_DIV_300,
UART_DIV_1200,
UART_DIV_2400,
UART_DIV_4800,
UART_DIV_9600,
UART_DIV_19200,
UART_DIV_38400,
UART_DIV_57600,
UART_DIV_115200,
UART_DIV_230400,
UART_DIV_460800,
UART_DIV_921600
};
/******************************************************************************* Function implementation *******************************************************************************//**
@Desc
Description for function_name
@Param parameter 1
Put parameter 1 description here
@Param parameter 2
Put parameter 2 description here
@Return Return value 1 and it description
@Return Return value 1 and it description
*/
void uart_init(const uart_port_no_t port_no, uart_defs_t *uart_defs_param_p){ /* In 0015, settings for data bit/stop bit/parity bit are fixed */ //uart_data_bits_t data_bits;
//uart_stop_bits_t stop_bits;
//uart_parity_bit_t parity_bit;
//uart_baud_rate_t baud_rate; /* set baud rate */
set_baud_rate( port_no, uart_defs_param_p->baud_rate );
//uart_flow_control_t flow_control;
HW_WRITE(UART_MCR_REG[port_no], HW_READ(UART_MCR_REG[port_no]) | UART_MCR_RTS);
//uart_intr_mode_t intr_mode;
if(uart_defs_param_p->intr_mode == INTERRUPT_MODE_ENBALED)
{
HW_WRITE(UART_IER_REG[port_no], HW_READ(UART_IER_REG[port_no]) | UART_IER_ERFTI);
}
/* Initialzie UART FIFO */
HW_WRITE(UART_FCR_REG[port_no], 0xB6);
//uart_data_src_t data_src_t; if(uart_defs_param_p->data_src_t == DATA_SRC_TRACER) HW_WRITE(UART_MCR_REG[port_no], HW_READ(UART_MCR_REG[port_no]) | UART_MCR_DATA_SRC); else HW_WRITE(UART_MCR_REG[port_no], HW_READ(UART_MCR_REG[port_no]) & ~UART_MCR_DATA_SRC);
}
void uart_tx(const uart_port_no_t port_no, UINT8 *tx_data_ptr, UINT32 tx_data_length){ UINT32 transmitted_length;
/* Validate parameter */
// port_no: uart1~3
// tx_data_ptr: non null
// tx_data_length: shall have a maximum upper bound (e.g., ENTIRE SRAM SIZE)
for(transmitted_length = 0; transmitted_length < tx_data_length; transmitted_length++)
{
/* Use polling to send data to UART TX FIFO */
while( (HW_READ(UART_LSR_REG[port_no]) & UART_LSR_THRE) == 0); /* TX FIFO is over threshold, wait */
HW_WRITE(UART_THR_REG[port_no], tx_data_ptr[transmitted_length]);
}
/* Optional, Wait until FIFO is empty */
while( (HW_READ(UART_LSR_REG[port_no]) & UART_LSR_TEMT) != UART_LSR_TEMT);
}void set_baud_rate( const uart_port_no_t port_no, uart_baud_rate_t baud_rate)
{
uint32T baud_rate_bs = BaudRateTbl[baud_rate];
uint32T UART_ratio; uint32T UART_divisor;
uint32T bit_shift;
/* validate input parameters */
/* Formula: ratio = floor(HCLK/Baudrate) - 1, required to be smaller than 255 */
UART_ratio = (HCLK*1000*1000/baud_rate_bs);
bit_shift = 0;
while ( ( UART_ratio >> bit_shift) > 255 )
bit_shift++;
UART_ratio >>= bit_shift;
UART_divisor = (0x1 << bit_shift);
#if (HCLK==26)
//UART_ratio = 16;
UART_ratio = 224; //HCLK=26MHz, baudrate=115200 //UART_divisor = ( ( (float)UART_BAUD_RATE_INPUT_CLK / (UART_ratio * baud_rate_bs) ) + 0.5 );
UART_divisor = 1; //HCLK=26MHz, baudrate=115200
//#elif (HCLK==73)
// UART_ratio = 158; //HCLK=26MHz, baudrate=115200// // UART_divisor = 4; //HCLK=26MHz, baudrate=115200
#elif (HCLK==84)
UART_ratio = 181; //HCLK=26MHz, baudrate=115200 UART_divisor = (HCLK*1000000)/baud_rate_bs/UART_ratio;
//UART_divisor = 1; //HCLK=26MHz, baudrate=115200
#elif (HCLK==100)
UART_ratio = 108; //HCLK=26MHz, baudrate=115200 UART_divisor = 8; //HCLK=100MHz, baudrate=115200
#else
#error "ERROR: Unknown HCLK"
#endif
HW_WRITE(UART_ECR_REG[port_no], HW_READ(UART_ECR_REG[port_no]) | UART_ratio); /* set DLAB bit to 1, toggle to DLL/DLH registers */
HW_WRITE(UART_LCR_REG[port_no], HW_READ(UART_LCR_REG[port_no]) | UART_LCR_DLAB); HW_WRITE(UART_DLL_REG[port_no], (UART_divisor & 0xFF) ); /* DIV LO */
HW_WRITE(UART_DLH_REG[port_no], (UART_divisor >> 8) & 0xFF); /* DIV HI */
/* set DLAB bit to 0, toggle back to Tx/Rx/IE registers */
HW_WRITE(UART_LCR_REG[port_no], HW_READ(UART_LCR_REG[port_no]) & ~UART_LCR_DLAB);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -