drv_usart.c 8.2 KB
Newer Older
1
/*
G
greedyhao 已提交
2
 * Copyright (c) 2020-2021, Bluetrum Development Team
mysterywolf's avatar
mysterywolf 已提交
3
 *
4 5 6 7 8 9 10 11 12
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2020-11-20     greedyhao         first version
 */

#include "board.h"
#include "drv_usart.h"
13
#include "api_huart.h"
14 15 16 17 18 19 20 21 22 23 24

#ifdef RT_USING_SERIAL

//#define DRV_DEBUG
#define LOG_TAG             "drv.usart"
#include <drv_log.h>

#undef  RT_SERIAL_USING_DMA

enum
{
25
#ifdef BSP_USING_UART0
26
    UART0_INDEX,
27 28
#endif
#ifdef BSP_USING_UART1
29
    UART1_INDEX,
30 31 32 33
#endif
#ifdef BSP_USING_UART2
    UART2_INDEX,
#endif
34 35 36 37
};

static struct ab32_uart_config uart_config[] =
{
38
#ifdef BSP_USING_UART0
39 40 41
    {
        .name = "uart0",
        .instance = UART0_BASE,
42
        .mode = UART_MODE_TX_RX | UART_MODE_1LINE,
43
        .fifo_size = BSP_UART0_FIFO_SIZE,
44
    },
45 46
#endif
#ifdef BSP_USING_UART1
47 48 49
    {
        .name = "uart1",
        .instance = UART1_BASE,
50
        .mode = UART_MODE_TX_RX,
51
        .fifo_size = BSP_UART1_FIFO_SIZE,
52 53 54 55 56 57 58
    },
#endif
#ifdef BSP_USING_UART2
    {
        .name = "uart2",
        .instance = UART2_BASE,
        .mode = UART_MODE_TX_RX,
59
        .fifo_size = BSP_UART2_FIFO_SIZE,
60
    }
61
#endif
62 63 64 65
};

static struct ab32_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};

66 67 68 69
#ifdef HUART_ENABLE
static uint8_t huart_dma[512];
#endif

70 71 72 73 74 75 76 77 78
static rt_err_t ab32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
    struct ab32_uart *uart;
    RT_ASSERT(serial != RT_NULL);
    RT_ASSERT(cfg != RT_NULL);

    uart = rt_container_of(serial, struct ab32_uart, serial);
    uart->handle.instance           = uart->config->instance;
    uart->handle.init.baud          = cfg->baud_rate;
79
    uart->handle.init.mode          = uart->config->mode;
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

    switch (cfg->data_bits)
    {
    case DATA_BITS_8:
        uart->handle.init.word_len  = UART_WORDLENGTH_8B;
        break;
    case DATA_BITS_9:
        uart->handle.init.word_len  = UART_WORDLENGTH_9B;
        break;
    default:
        uart->handle.init.word_len  = UART_WORDLENGTH_8B;
        break;
    }

    switch (cfg->stop_bits)
    {
    case STOP_BITS_1:
        uart->handle.init.stop_bits = UART_STOPBITS_1;
        break;
    case STOP_BITS_2:
        uart->handle.init.stop_bits = UART_STOPBITS_2;
        break;
    default:
        uart->handle.init.stop_bits = UART_STOPBITS_1;
        break;
    }

#ifdef RT_SERIAL_USING_DMA
    uart->dma_rx.last_index = 0;
#endif

111 112 113 114 115 116 117 118
    if (!uart->uart_dma_flag) {
        hal_uart_init(&uart->handle);
    }
#ifdef HUART_ENABLE
    else {
        huart_init_do(HUART_TR_PB3, HUART_TR_PB4, uart->handle.init.baud, huart_dma, 512);
    }
#endif
119 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

    return RT_EOK;
}

static rt_err_t ab32_control(struct rt_serial_device *serial, int cmd, void *arg)
{
    struct ab32_uart *uart;
#ifdef RT_SERIAL_USING_DMA
    rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
#endif

    RT_ASSERT(serial != RT_NULL);
    uart = rt_container_of(serial, struct ab32_uart, serial);

    switch (cmd)
    {
    /* disable interrupt */
    case RT_DEVICE_CTRL_CLR_INT:
        hal_uart_control(uart->handle.instance, UART_RXIT_ENABLE, HAL_DISABLE);
        break;
    /* enable interrupt */
    case RT_DEVICE_CTRL_SET_INT:
        hal_uart_clrflag(uart->handle.instance, UART_FLAG_RXPND);
        hal_uart_control(uart->handle.instance, UART_RXIT_ENABLE, HAL_ENABLE);
        break;
    case RT_DEVICE_CTRL_CLOSE:
        hal_uart_deinit(uart->handle.instance);
        break;
    }

    return RT_EOK;
}

static int ab32_putc(struct rt_serial_device *serial, char ch)
{
    struct ab32_uart *uart;
    RT_ASSERT(serial != RT_NULL);

    uart = rt_container_of(serial, struct ab32_uart, serial);
158 159 160 161 162 163 164 165 166 167 168

    if (!uart->uart_dma_flag) {
        hal_uart_clrflag(uart->handle.instance,  UART_FLAG_TXPND);
        hal_uart_write(uart->handle.instance, ch);
        while(hal_uart_getflag(uart->handle.instance, UART_FLAG_TXPND) == 0);
    }
#ifdef HUART_ENABLE
    else {
        huart_putchar(ch);
    }
#endif
169 170 171 172 173 174 175 176 177

    return 1;
}

static int ab32_getc(struct rt_serial_device *serial)
{
    int ch;
    struct ab32_uart *uart;
    RT_ASSERT(serial != RT_NULL);
178

179 180 181
    uart = rt_container_of(serial, struct ab32_uart, serial);

    ch = -1;
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
    switch ((uint32_t)(uart->handle.instance)) {
        case (uint32_t)UART0_BASE:
            if (uart->rx_idx != uart->rx_idx_prev) {
                ch = (int)(uart->rx_buf[uart->rx_idx_prev++ % 10]);
            }
            break;
        case (uint32_t)UART1_BASE:
#ifdef HUART_ENABLE
            if ((uart->uart_dma_flag) && (huart_get_rxcnt())) {
                ch = huart_getchar();
            } else
#endif
            {
                if (uart->rx_idx != uart->rx_idx_prev) {
                    ch = (int)(uart->rx_buf[uart->rx_idx_prev++ % 10]);
                }
            }
            break;
        case (uint32_t)UART2_BASE:
            if (uart->rx_idx != uart->rx_idx_prev) {
                ch = (int)(uart->rx_buf[uart->rx_idx_prev++ % 10]);
            }
            break;
        default:
            break;
207 208 209 210 211 212 213 214 215 216
    }

    return ch;
}

static rt_size_t ab32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
{
    return -1;
}

217
void uart0_irq_process(void)
G
greedyhao 已提交
218
{
219
    rt_hw_serial_isr(&(uart_obj[UART0_INDEX].serial), RT_SERIAL_EVENT_RX_IND);
G
greedyhao 已提交
220 221
}

222 223
#ifdef BSP_USING_UART1
void uart1_irq_process(void)
G
greedyhao 已提交
224
{
225 226 227
    rt_hw_serial_isr(&(uart_obj[UART1_INDEX].serial), RT_SERIAL_EVENT_RX_IND);
}
#endif
228

229 230 231 232
#ifdef BSP_USING_UART2
void uart2_irq_process(void)
{
    rt_hw_serial_isr(&(uart_obj[UART2_INDEX].serial), RT_SERIAL_EVENT_RX_IND);
G
greedyhao 已提交
233
}
234
#endif
G
greedyhao 已提交
235 236

RT_SECTION(".irq.usart")
237 238 239 240
static void uart_isr(int vector, void *param)
{
    rt_interrupt_enter();

241
#ifdef BSP_USING_UART0
242 243
    if(hal_uart_getflag(UART0_BASE, UART_FLAG_RXPND))       //RX one byte finish
    {
244 245 246
        uart_obj[0].rx_buf[uart_obj[0].rx_idx++ % 10] = hal_uart_read(UART0_BASE);
        hal_uart_clrflag(UART0_BASE, UART_FLAG_RXPND);
        uart0_irq_post();
247
    }
248 249 250 251
#endif
#ifdef BSP_USING_UART1
    if(hal_uart_getflag(UART1_BASE, UART_FLAG_RXPND))       //RX one byte finish
    {
252 253 254
        uart_obj[1].rx_buf[uart_obj[1].rx_idx++ % 10] = hal_uart_read(UART1_BASE);
        hal_uart_clrflag(UART1_BASE, UART_FLAG_RXPND);
        uart1_irq_post();
255 256 257 258 259
    }
#endif
#ifdef BSP_USING_UART2
    if(hal_uart_getflag(UART2_BASE, UART_FLAG_RXPND))       //RX one byte finish
    {
260 261 262
        uart_obj[2].rx_buf[uart_obj[2].rx_idx++ % 10] = hal_uart_read(UART2_BASE);
        hal_uart_clrflag(UART2_BASE, UART_FLAG_RXPND);
        uart2_irq_post();
263 264
    }
#endif
265 266 267 268

    rt_interrupt_leave();
}

269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
#ifdef HUART_ENABLE
RT_SECTION(".irq.huart")
void huart_timer_isr(void)
{
    huart_if_rx_ovflow();

    if (0 == huart_get_rxcnt()) {
        return;
    }

    uart1_irq_post();
}
#else
RT_SECTION(".irq.huart")
void huart_timer_isr(void)
{
}
#endif

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
static const struct rt_uart_ops ab32_uart_ops =
{
    .configure = ab32_configure,
    .control = ab32_control,
    .putc = ab32_putc,
    .getc = ab32_getc,
    .dma_transmit = ab32_dma_transmit
};

int rt_hw_usart_init(void)
{
    rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct ab32_uart);
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
    rt_err_t result = 0;

    rt_hw_interrupt_install(IRQ_UART0_2_VECTOR, uart_isr, RT_NULL, "ut_isr");

    for (int i = 0; i < obj_num; i++)
    {
        /* init UART object */
        uart_obj[i].config          = &uart_config[i];
309 310
        uart_obj[i].rx_idx          = 0;
        uart_obj[i].rx_idx_prev     = 0;
311 312
        uart_obj[i].serial.ops      = &ab32_uart_ops;
        uart_obj[i].serial.config   = config;
G
greedyhao 已提交
313
        uart_obj[i].serial.config.baud_rate = 1500000;
314 315 316 317 318 319
        uart_obj[i].rx_buf          = rt_malloc(uart_config[i].fifo_size);

        if (uart_obj[i].rx_buf == RT_NULL) {
            LOG_E("uart%d malloc failed!", i);
            continue;
        }
320 321 322 323 324 325 326

        /* register UART device */
        result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
                                       RT_DEVICE_FLAG_RDWR
                                       | RT_DEVICE_FLAG_INT_RX
                                       | RT_DEVICE_FLAG_INT_TX
                                       | uart_obj[i].uart_dma_flag
mysterywolf's avatar
mysterywolf 已提交
327
                                       , RT_NULL);
328 329 330
        RT_ASSERT(result == RT_EOK);
    }

331
    return result;
332 333 334
}

#endif