⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 realview下的一个arm9的bootloader烧录器.支持norflash读写
💻 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 + -