ls1c_uart.c 6.4 KB
Newer Older
1
 /*
mysterywolf's avatar
mysterywolf 已提交
2
 * Copyright (c) 2006-2021, RT-Thread Development Team
3 4 5 6 7 8 9
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 *                             first version
 */
Z
zhuangwei123 已提交
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
// 串口相关源码

#include <stdio.h>
#include <stdarg.h>
#include "ls1c_public.h"
#include "ls1c_regs.h"
#include "ls1c_pin.h"
#include "ls1c_uart.h"
#include "ls1c_clock.h"
#include "ls1c.h"


// 串口线路状态寄存器的位域
#define LS1C_UART_LSR_TE                (1 << 6)
#define LS1C_UART_LSR_TFE               (1 << 5)


// 打印缓存的大小
#define LS1C_UART_PRINT_BUF_SIZE        (256)


// 调试串口信息
ls1c_uart_info_t debug_uart_info = {0};


/*
 * 获取指定串口模块的基地址
 * @UARTx 串口编号
 * @ret 基地址
 */
void *uart_get_base(ls1c_uart_t UARTx)
{
    void *base = NULL;

    switch (UARTx)
    {
        case LS1C_UART00:
            base = (void *)LS1C_UART00_BASE;
            break;
        case LS1C_UART01:
            base = (void *)LS1C_UART01_BASE;
            break;

        case LS1C_UART1:
            base = (void *)LS1C_UART1_BASE;
            break;
mysterywolf's avatar
mysterywolf 已提交
56

Z
zhuangwei123 已提交
57 58 59 60 61 62 63
        case LS1C_UART2:
            base = (void *)LS1C_UART2_BASE;
            break;

        case LS1C_UART3:
            base = (void *)LS1C_UART3_BASE;
            break;
mysterywolf's avatar
mysterywolf 已提交
64

Z
zhuangwei123 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
        case LS1C_UART4:
            base = (void *)LS1C_UART4_BASE;
            break;

        case LS1C_UART5:
            base = (void *)LS1C_UART5_BASE;
            break;

        case LS1C_UART6:
            base = (void *)LS1C_UART6_BASE;
            break;

        case LS1C_UART7:
            base = (void *)LS1C_UART7_BASE;
            break;

        case LS1C_UART8:
            base = (void *)LS1C_UART8_BASE;
            break;

        case LS1C_UART9:
            base = (void *)LS1C_UART9_BASE;
            break;

        case LS1C_UART10:
            base = (void *)LS1C_UART10_BASE;
            break;

        case LS1C_UART11:
            base = (void *)LS1C_UART11_BASE;
            break;

        default:
            break;
    }

    return base;
}


/*
 * 初始化指定的串口模块
 * @uart_info_p 串口模块信息
 */
void uart_init(ls1c_uart_info_t *uart_info_p)
{
    void *uart_base = uart_get_base(uart_info_p->UARTx);
    unsigned long baudrate_div = 0;

    // 禁止所有中断
    reg_write_8(0,      uart_base + LS1C_UART_IER_OFFSET);
mysterywolf's avatar
mysterywolf 已提交
116

Z
zhuangwei123 已提交
117 118
    // 接收FIFO的中断申请Trigger为14字节,清空发送和接收FIFO,并复位
    reg_write_8(0xc3,   uart_base + LS1C_UART_FCR_OFFSET);
mysterywolf's avatar
mysterywolf 已提交
119

Z
zhuangwei123 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
    // 设置波特率
    reg_write_8(0x80,   uart_base + LS1C_UART_LCR_OFFSET);
    baudrate_div = clk_get_cpu_rate() / 16 / uart_info_p->baudrate / 2;
    reg_write_8((baudrate_div >> 8) & 0xff, uart_base + LS1C_UART_MSB_OFFSET);
    reg_write_8(baudrate_div & 0xff,        uart_base + LS1C_UART_LSB_OFFSET);

    // 8个数据位,1个停止位,无校验
    reg_write_8(0x03,   uart_base + LS1C_UART_LCR_OFFSET);

    // 使能接收中断
    if (TRUE == uart_info_p->rx_enable)
    {
        reg_write_8(IER_IRxE|IER_ILE , uart_base + LS1C_UART_IER_OFFSET);
    }

    return ;
}


/*
 * 判断FIFO是否为空
 * @uartx 串口号
 * @ret TRUE or FALSE
 */
BOOL uart_is_transmit_empty(ls1c_uart_t uartx)
{
    void *uart_base = uart_get_base(uartx);
    unsigned char status = reg_read_8(uart_base + LS1C_UART_LSR_OFFSET);

    if (status & (LS1C_UART_LSR_TE | LS1C_UART_LSR_TFE))
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}


/*
 * 发送一个字节
 * @uartx 串口号
 * @ch 待发送的字符串
 */
void uart_putc(ls1c_uart_t uartx, unsigned char ch)
{
    void *uart_base = uart_get_base(uartx);
mysterywolf's avatar
mysterywolf 已提交
168

Z
zhuangwei123 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
    // 等待
    while (FALSE == uart_is_transmit_empty(uartx))
        ;

    // 发送
    reg_write_8(ch, uart_base + LS1C_UART_DAT_OFFSET);

    return ;
}


/*
 * 打印一个字符串到指定串口
 * @uartx 串口号
 * @str 待打印的字符串
 */
void uart_print(ls1c_uart_t uartx, const char *str)
{
    while ('\0' != *str)                // 判断是否为字符串结束符
    {
        uart_putc(uartx, *str);   // 发送一个字符
        str++;
    }

    return ;
}


/*
 * 初始化串口2
 */
void uart2_init(void)
{
    unsigned int tx_gpio = 37;
    unsigned int rx_gpio = 36;

    // 设置复用
    pin_set_remap(tx_gpio, PIN_REMAP_SECOND);
    pin_set_remap(rx_gpio, PIN_REMAP_SECOND);
mysterywolf's avatar
mysterywolf 已提交
208

Z
zhuangwei123 已提交
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
    // 初始化相关寄存器
    debug_uart_info.UARTx = LS1C_UART2;
    debug_uart_info.baudrate = 115200;
    debug_uart_info.rx_enable = FALSE;  // 调试串口只需要打印(发送)功能,不需要接收功能
    uart_init(&debug_uart_info);

    return ;
}


/*
 * 在串口2上打印字符串
 * @str 待打印的字符串
 */
void uart2_print(const char *str)
{
    uart_print(LS1C_UART2, str);
    return ;
}


/*
 * 在调试串口打印字符串
 * @str 待打印的字符串
 */
void uart_debug_print(const char *str)
{
    uart_print(debug_uart_info.UARTx, str);
    return ;
}


/*
 * 在调试串口打印一个字符
 * @ch 待打印的字符
 */
void uart_debug_putc(unsigned char ch)
{
    uart_putc(debug_uart_info.UARTx, ch);
    return ;
}


/*
 * 把中断号转换为串口号
 * @IRQn 中断号
 * @ret 串口号
 */
ls1c_uart_t uart_irqn_to_uartx(int IRQn)
{
    ls1c_uart_t uartx = LS1C_UART2;
mysterywolf's avatar
mysterywolf 已提交
260

Z
zhuangwei123 已提交
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
    switch (IRQn)
    {
        /* 串口UART00和UART01的中断号还待确定
        case LS1C_UART00_IRQ:
            uartx = LS1C_UART00;
            break;

        case LS1C_UART01_IRQ:
            uartx = LS1C_UART01;
            break;
       */

        case LS1C_UART1_IRQ:
            uartx = LS1C_UART1;
            break;
mysterywolf's avatar
mysterywolf 已提交
276

Z
zhuangwei123 已提交
277 278 279
        case LS1C_UART2_IRQ:
            uartx = LS1C_UART2;
            break;
mysterywolf's avatar
mysterywolf 已提交
280

Z
zhuangwei123 已提交
281 282 283
        case LS1C_UART3_IRQ:
            uartx = LS1C_UART3;
            break;
mysterywolf's avatar
mysterywolf 已提交
284

Z
zhuangwei123 已提交
285 286 287
        case LS1C_UART4_IRQ:
            uartx = LS1C_UART4;
            break;
mysterywolf's avatar
mysterywolf 已提交
288

Z
zhuangwei123 已提交
289 290 291
        case LS1C_UART5_IRQ:
            uartx = LS1C_UART5;
            break;
mysterywolf's avatar
mysterywolf 已提交
292

Z
zhuangwei123 已提交
293 294 295
        case LS1C_UART6_IRQ:
            uartx = LS1C_UART6;
            break;
mysterywolf's avatar
mysterywolf 已提交
296

Z
zhuangwei123 已提交
297 298 299
        case LS1C_UART7_IRQ:
            uartx = LS1C_UART7;
            break;
mysterywolf's avatar
mysterywolf 已提交
300

Z
zhuangwei123 已提交
301 302 303
        case LS1C_UART8_IRQ:
            uartx = LS1C_UART8;
            break;
mysterywolf's avatar
mysterywolf 已提交
304

Z
zhuangwei123 已提交
305 306 307
        case LS1C_UART9_IRQ:
            uartx = LS1C_UART9;
            break;
mysterywolf's avatar
mysterywolf 已提交
308

Z
zhuangwei123 已提交
309 310 311
        case LS1C_UART10_IRQ:
            uartx = LS1C_UART10;
            break;
mysterywolf's avatar
mysterywolf 已提交
312

Z
zhuangwei123 已提交
313 314 315
        case LS1C_UART11_IRQ:
            uartx = LS1C_UART11;
            break;
mysterywolf's avatar
mysterywolf 已提交
316

Z
zhuangwei123 已提交
317 318 319 320 321 322 323 324 325
        default:
            uartx = LS1C_UART2;
            break;
    }

    return uartx;
}