drv_uart.c 5.5 KB
Newer Older
Z
zhuangwei123 已提交
1
/*
2
 * Copyright (c) 2006-2018, RT-Thread Development Team
Z
zhuangwei123 已提交
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
Z
zhuangwei123 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-05-08     zhuangwei    the first version
 */
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#include "drv_uart.h"
#include "ls1c_pin.h"
#include "ls1c_uart.h"

/* STM32 uart driver */
struct rt_uart_ls1c
{
    ls1c_uart_t UARTx;
Z
zhuangwei123 已提交
21
    rt_uint32_t IRQ;
Z
zhuangwei123 已提交
22 23 24 25
};

static rt_err_t ls1c_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
Z
zhuangwei123 已提交
26 27
    struct rt_uart_ls1c *uart_dev = RT_NULL;
    ls1c_uart_info_t uart_info = {0};
Z
zhuangwei123 已提交
28

Z
zhuangwei123 已提交
29 30
    RT_ASSERT(serial != RT_NULL);
    RT_ASSERT(cfg != RT_NULL);
Z
zhuangwei123 已提交
31

Z
zhuangwei123 已提交
32
    uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data;
Z
zhuangwei123 已提交
33

Z
zhuangwei123 已提交
34 35 36 37
    // 初始化串口
    uart_info.UARTx    = uart_dev->UARTx;
    uart_info.baudrate = cfg->baud_rate;
    uart_info.rx_enable = TRUE;
Z
zhuangwei123 已提交
38 39
    uart_init(&uart_info);

Z
zhuangwei123 已提交
40
    return RT_EOK;
Z
zhuangwei123 已提交
41 42 43 44 45

}

static rt_err_t ls1c_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
Z
zhuangwei123 已提交
46 47 48 49 50 51 52 53
    struct rt_uart_ls1c *uart_dev = RT_NULL;

    RT_ASSERT(serial != RT_NULL);
    uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data;

    switch (cmd)
    {
    case RT_DEVICE_CTRL_CLR_INT: /* disable rx irq */
Z
zhuangwei123 已提交
54
        rt_hw_interrupt_mask(uart_dev->IRQ);
Z
zhuangwei123 已提交
55
        break;
Z
zhuangwei123 已提交
56

Z
zhuangwei123 已提交
57 58 59
    case RT_DEVICE_CTRL_SET_INT: /* enable rx irq */
        rt_hw_interrupt_umask(uart_dev->IRQ);
        break;
Z
zhuangwei123 已提交
60

Z
zhuangwei123 已提交
61 62 63
    default:
        break;
    }
Z
zhuangwei123 已提交
64

Z
zhuangwei123 已提交
65
    return RT_EOK;
Z
zhuangwei123 已提交
66 67 68 69 70

}

static int ls1c_uart_putc(struct rt_serial_device *serial, char c)
{
Z
zhuangwei123 已提交
71 72 73
    struct rt_uart_ls1c *uart_dev = RT_NULL;

    RT_ASSERT(serial != RT_NULL);
Z
zhuangwei123 已提交
74

Z
zhuangwei123 已提交
75 76
    uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data;
    uart_putc(uart_dev->UARTx, c);
Z
zhuangwei123 已提交
77

Z
zhuangwei123 已提交
78
    return 1;
Z
zhuangwei123 已提交
79 80 81 82
}

static int ls1c_uart_getc(struct rt_serial_device *serial)
{
Z
zhuangwei123 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95
    struct rt_uart_ls1c *uart_dev = RT_NULL;

    RT_ASSERT(serial != RT_NULL);

    uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data;
    void *uart_base = uart_get_base(uart_dev->UARTx);

    if (LSR_RXRDY & reg_read_8(uart_base + LS1C_UART_LSR_OFFSET))
    {
        return reg_read_8(uart_base + LS1C_UART_DAT_OFFSET);
    }

    return -1;
Z
zhuangwei123 已提交
96 97 98 99 100
}

/* UART interrupt handler */
static void uart_irq_handler(int vector, void *param)
{
Z
zhuangwei123 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    struct rt_serial_device *serial = (struct rt_serial_device *)param;
    struct rt_uart_ls1c *uart_dev = RT_NULL;

    RT_ASSERT(serial != RT_NULL);

    uart_dev = (struct rt_uart_ls1c *)serial->parent.user_data;
    void *uart_base = uart_get_base(uart_dev->UARTx);
    unsigned char iir = reg_read_8(uart_base + LS1C_UART_IIR_OFFSET);

    // 判断是否为接收超时或接收到有效数据
    if ((IIR_RXTOUT & iir) || (IIR_RXRDY & iir))
    {
        rt_interrupt_enter();
        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
        rt_interrupt_leave();
    }
Z
zhuangwei123 已提交
117 118 119

}

120
static const struct rt_uart_ops ls1c_uart_ops =
Z
zhuangwei123 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133 134
{
    ls1c_uart_configure,
    ls1c_uart_control,
    ls1c_uart_putc,
    ls1c_uart_getc,
};

#if defined(RT_USING_UART2)
struct rt_uart_ls1c uart2 =
{
    LS1C_UART2,
    LS1C_UART2_IRQ,
};
struct rt_serial_device serial2;
135 136 137 138 139 140 141 142 143
#endif /* RT_USING_UART2 */

#if defined(RT_USING_UART1)
struct rt_uart_ls1c uart1 =
{
    LS1C_UART1,
    LS1C_UART1_IRQ,
};
struct rt_serial_device serial1;
Z
zhuangwei123 已提交
144 145
#endif /* RT_USING_UART1 */

146 147 148 149 150 151 152 153 154
#if defined(RT_USING_UART3)
struct rt_uart_ls1c uart3 =
{
    LS1C_UART3,
    LS1C_UART3_IRQ,
};
struct rt_serial_device serial3;
#endif /* RT_USING_UART3 */

Z
zhuangwei123 已提交
155 156 157 158 159 160 161 162
void rt_hw_uart_init(void)
{
    struct rt_uart_ls1c *uart;
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

#ifdef RT_USING_UART2
    uart = &uart2;

163
    serial2.ops    = &ls1c_uart_ops;
Z
zhuangwei123 已提交
164 165
    serial2.config = config;

Z
zhuangwei123 已提交
166 167 168 169
    pin_set_purpose(36, PIN_PURPOSE_OTHER);
    pin_set_purpose(37, PIN_PURPOSE_OTHER);
    pin_set_remap(36, PIN_REMAP_SECOND);
    pin_set_remap(37, PIN_REMAP_SECOND);
Z
zhuangwei123 已提交
170

Z
zhuangwei123 已提交
171
    rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial2, "UART2");
Z
zhuangwei123 已提交
172

173
    /* register UART2 device */
Z
zhuangwei123 已提交
174 175 176 177 178
    rt_hw_serial_register(&serial2,
                          "uart2",
                          //RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX,
                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
                          uart);
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
#endif /* RT_USING_UART2 */

#ifdef RT_USING_UART1
    uart = &uart1;

    serial1.ops    = &ls1c_uart_ops;
    serial1.config = config;

    pin_set_purpose(2, PIN_PURPOSE_OTHER);
    pin_set_purpose(3, PIN_PURPOSE_OTHER);
    pin_set_remap(2, PIN_REMAP_FOURTH);
    pin_set_remap(3, PIN_REMAP_FOURTH);

    rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial1, "UART1");

    /* register UART1 device */
    rt_hw_serial_register(&serial1,
                          "uart1",
                          //RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX,
                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
                          uart);
Z
zhuangwei123 已提交
200
#endif /* RT_USING_UART1 */
201

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
#ifdef RT_USING_UART3
    uart = &uart3;

    serial3.ops    = &ls1c_uart_ops;
    serial3.config = config;

    pin_set_purpose(0, PIN_PURPOSE_OTHER);
    pin_set_purpose(1, PIN_PURPOSE_OTHER);
    pin_set_remap(0, PIN_REMAP_FOURTH);
    pin_set_remap(1, PIN_REMAP_FOURTH);

    rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial3, "UART3");

    /* register UART1 device */
    rt_hw_serial_register(&serial3,
                          "uart3",
                          //RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX,
                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
                          uart);
#endif /* RT_USING_UART3 */

Z
zhuangwei123 已提交
223 224
}