drv_uarte.c 9.0 KB
Newer Older
1 2
 /*
 * Copyright (c) 2006-2022, RT-Thread Development Team
csnd_nc's avatar
csnd_nc 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-04-28     xckhmf       Modify for <nrfx>
 * 2020-10-31     xckhmf       Support for UART1
 *
 */
#include <rtdevice.h>
#include <nrfx_uarte.h>
#include "drv_uart.h"

#ifdef BSP_USING_UART
17
#if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)|| defined(BSP_USING_UART2)|| defined(BSP_USING_UART3)
csnd_nc's avatar
csnd_nc 已提交
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
typedef struct
{
    struct rt_serial_device *serial;
    nrfx_uarte_t uarte_instance;
    uint8_t rx_length;
    uint8_t tx_buffer[1];
    uint8_t rx_buffer[1];
    bool isInit;
    uint32_t rx_pin;
    uint32_t tx_pin;
} drv_uart_cb_t;

#ifdef BSP_USING_UART0
static struct rt_serial_device m_serial_0;
drv_uart_cb_t m_uarte0_cb = {
    .uarte_instance = NRFX_UARTE_INSTANCE(0),
    .rx_length = 0,
    .rx_pin = BSP_UART0_RX_PIN,
    .tx_pin = BSP_UART0_TX_PIN,
    .isInit = false
};
#endif  /* BSP_USING_UART0 */

#ifdef BSP_USING_UART1
static struct rt_serial_device m_serial_1;
drv_uart_cb_t m_uarte1_cb = {
    .uarte_instance = NRFX_UARTE_INSTANCE(1),
    .rx_length = 0,
    .rx_pin = BSP_UART1_RX_PIN,
    .tx_pin = BSP_UART1_TX_PIN,
    .isInit = false
};
#endif  /* BSP_USING_UART1 */
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#ifdef BSP_USING_UART2
static struct rt_serial_device m_serial_2;
drv_uart_cb_t m_uarte2_cb = {
    .uarte_instance = NRFX_UARTE_INSTANCE(2),
    .rx_length = 0,
    .rx_pin = BSP_UART2_RX_PIN,
    .tx_pin = BSP_UART2_TX_PIN,
    .isInit = false
};
#endif  /* BSP_USING_UART2 */
#ifdef BSP_USING_UART3
static struct rt_serial_device m_serial_3;
drv_uart_cb_t m_uarte3_cb = {
    .uarte_instance = NRFX_UARTE_INSTANCE(3),
    .rx_length = 0,
    .rx_pin = BSP_UART3_RX_PIN,
    .tx_pin = BSP_UART3_TX_PIN,
    .isInit = false
};
#endif  /* BSP_USING_UART3 */

csnd_nc's avatar
csnd_nc 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91

static void uarte_evt_handler(nrfx_uarte_event_t const * p_event,
                              void *                     p_context)
{
    drv_uart_cb_t *p_cb = RT_NULL;
    p_cb = (drv_uart_cb_t*)p_context;
    switch (p_event->type)
    {
        case NRFX_UARTE_EVT_RX_DONE:
            p_cb->rx_length = p_event->data.rxtx.bytes;
            if(p_cb->serial->parent.open_flag&RT_DEVICE_FLAG_INT_RX)
            {
                rt_hw_serial_isr(p_cb->serial, RT_SERIAL_EVENT_RX_IND);
            }
            (void)nrfx_uarte_rx(&(p_cb->uarte_instance), p_cb->rx_buffer, 1);
            break;

        case NRFX_UARTE_EVT_ERROR:
            (void)nrfx_uarte_rx(&(p_cb->uarte_instance), p_cb->rx_buffer, 1);
            break;
mysterywolf's avatar
mysterywolf 已提交
92

csnd_nc's avatar
csnd_nc 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
        case NRFX_UARTE_EVT_TX_DONE:
            if(p_cb->serial->parent.open_flag&RT_DEVICE_FLAG_INT_TX)
            {
                rt_hw_serial_isr(p_cb->serial, RT_SERIAL_EVENT_TX_DONE);
            }
            break;

        default:
            break;
    }
}

static rt_err_t _uart_cfg(struct rt_serial_device *serial, struct serial_configure *cfg)
{
    nrfx_uarte_config_t config = NRFX_UARTE_DEFAULT_CONFIG(NRF_UARTE_PSEL_DISCONNECTED,\
                                                            NRF_UARTE_PSEL_DISCONNECTED);

    drv_uart_cb_t *p_cb = RT_NULL;

    RT_ASSERT(serial != RT_NULL);
    RT_ASSERT(cfg != RT_NULL);
mysterywolf's avatar
mysterywolf 已提交
114

csnd_nc's avatar
csnd_nc 已提交
115 116 117 118 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
    if (serial->parent.user_data == RT_NULL)
    {
        return -RT_ERROR;
    }
    p_cb = (drv_uart_cb_t*)serial->parent.user_data;
    if(p_cb->isInit)
    {
        nrfx_uarte_uninit(&(p_cb->uarte_instance));
        p_cb->isInit = false;
    }

    switch (cfg->baud_rate)
    {
    case BAUD_RATE_2400:
        config.baudrate = NRF_UARTE_BAUDRATE_2400;
        break;
    case BAUD_RATE_4800:
        config.baudrate = NRF_UARTE_BAUDRATE_4800;
        break;
    case BAUD_RATE_9600:
        config.baudrate = NRF_UARTE_BAUDRATE_9600;
        break;
    case BAUD_RATE_19200:
        config.baudrate = NRF_UARTE_BAUDRATE_19200;
        break;
    case BAUD_RATE_38400:
        config.baudrate = NRF_UARTE_BAUDRATE_38400;
        break;
    case BAUD_RATE_57600:
        config.baudrate = NRF_UARTE_BAUDRATE_57600;
        break;
    case BAUD_RATE_115200:
        config.baudrate = NRF_UARTE_BAUDRATE_115200;
        break;
    case BAUD_RATE_230400:
        config.baudrate = NRF_UARTE_BAUDRATE_230400;
        break;
    case BAUD_RATE_460800:
        config.baudrate = NRF_UARTE_BAUDRATE_460800;
        break;
    case BAUD_RATE_921600:
        config.baudrate = NRF_UARTE_BAUDRATE_921600;
        break;
158 159
#if defined(SOC_NRF5340)
    case 1000000:
160
        config.baudrate = NRF_UARTE_BAUDRATE_1000000;
161 162
        break;
#endif /* SOC_NRF5340*/
csnd_nc's avatar
csnd_nc 已提交
163 164 165 166 167 168 169 170 171 172 173
    case BAUD_RATE_2000000:
    case BAUD_RATE_3000000:
        return -RT_EINVAL;
    default:
        config.baudrate = NRF_UARTE_BAUDRATE_115200;
        break;
    }
    config.hal_cfg.parity = (cfg->parity == PARITY_NONE)?\
                            NRF_UARTE_PARITY_EXCLUDED:NRF_UARTE_PARITY_INCLUDED;
    config.hal_cfg.hwfc = NRF_UARTE_HWFC_DISABLED;
    config.pselrxd = p_cb->rx_pin;
mysterywolf's avatar
mysterywolf 已提交
174
    config.pseltxd = p_cb->tx_pin;
csnd_nc's avatar
csnd_nc 已提交
175 176 177
    config.p_context = (void *)p_cb;

    nrfx_uarte_init(&(p_cb->uarte_instance),(nrfx_uarte_config_t const *)&config,uarte_evt_handler);
mysterywolf's avatar
mysterywolf 已提交
178
    nrfx_uarte_rx(&(p_cb->uarte_instance),p_cb->rx_buffer,1);
csnd_nc's avatar
csnd_nc 已提交
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 208 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
    p_cb->isInit = true;
    return RT_EOK;
}

static rt_err_t _uart_ctrl(struct rt_serial_device *serial, int cmd, void *arg)
{
    drv_uart_cb_t *p_cb = RT_NULL;
    RT_ASSERT(serial != RT_NULL);

    if (serial->parent.user_data == RT_NULL)
    {
        return -RT_ERROR;
    }
    p_cb = (drv_uart_cb_t*)serial->parent.user_data;

    switch (cmd)
    {
        /* disable interrupt */
    case RT_DEVICE_CTRL_CLR_INT:
        break;

        /* enable interrupt */
    case RT_DEVICE_CTRL_SET_INT:
        break;

    case RT_DEVICE_CTRL_CUSTOM:
        if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_9600)
        {
            p_cb->serial->config.baud_rate = 9600;
        }
        else if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_115200)
        {
            p_cb->serial->config.baud_rate = 115200;
        }
        _uart_cfg(serial, &(serial->config));
        break;

    case RT_DEVICE_CTRL_PIN:
        _uart_cfg(serial, &(serial->config));
        break;

    case RT_DEVICE_POWERSAVE:
        if(p_cb->isInit)
        {
            nrfx_uarte_uninit(&(p_cb->uarte_instance));
            p_cb->isInit = false;
        }
        break;

    case RT_DEVICE_WAKEUP:
        _uart_cfg(serial, &(serial->config));
        break;

    default:
        return -RT_ERROR;
    }

    return RT_EOK;
}

static int _uart_putc(struct rt_serial_device *serial, char c)
{
    drv_uart_cb_t *p_cb = RT_NULL;
    int rtn = -1;
    RT_ASSERT(serial != RT_NULL);

    if (serial->parent.user_data != RT_NULL)
    {
        p_cb = (drv_uart_cb_t*)serial->parent.user_data;
    }
    p_cb->tx_buffer[0] = c;
    nrfx_uarte_tx(&(p_cb->uarte_instance),p_cb->tx_buffer,1);
    if(!(serial->parent.open_flag&RT_DEVICE_FLAG_INT_TX))
    {
        while(nrfx_uarte_tx_in_progress(&(p_cb->uarte_instance)))
        {
        }
mysterywolf's avatar
mysterywolf 已提交
256
    }
csnd_nc's avatar
csnd_nc 已提交
257 258 259 260 261 262 263 264 265 266 267 268
    return rtn;
}

static int _uart_getc(struct rt_serial_device *serial)
{
    int ch = -1;
    drv_uart_cb_t *p_cb = RT_NULL;
    RT_ASSERT(serial != RT_NULL);

    if (serial->parent.user_data != RT_NULL)
    {
        p_cb = (drv_uart_cb_t*)serial->parent.user_data;
mysterywolf's avatar
mysterywolf 已提交
269
    }
csnd_nc's avatar
csnd_nc 已提交
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
    if(p_cb->rx_length)
    {
        ch = p_cb->rx_buffer[0];
        p_cb->rx_length--;
    }
    return ch;
}

static struct rt_uart_ops _uart_ops = {
    _uart_cfg,
    _uart_ctrl,
    _uart_putc,
    _uart_getc
};

285
int rt_hw_uart_init(void)
csnd_nc's avatar
csnd_nc 已提交
286 287 288
{
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

mysterywolf's avatar
mysterywolf 已提交
289
#ifdef BSP_USING_UART0
csnd_nc's avatar
csnd_nc 已提交
290
    m_serial_0.config = config;
291 292 293
#if defined(SOC_NRF5340)
    m_serial_0.config.baud_rate =  1000000;
#endif /* SOC_NRF5340*/
csnd_nc's avatar
csnd_nc 已提交
294 295 296
    m_serial_0.ops = &_uart_ops;
    m_uarte0_cb.serial = &m_serial_0;
    rt_hw_serial_register(&m_serial_0, "uart0", \
297
                            RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX ,  &m_uarte0_cb);
csnd_nc's avatar
csnd_nc 已提交
298
#endif  /* BSP_USING_UART0 */
mysterywolf's avatar
mysterywolf 已提交
299 300

#ifdef BSP_USING_UART1
csnd_nc's avatar
csnd_nc 已提交
301 302 303 304
    m_serial_1.config = config;
    m_serial_1.ops = &_uart_ops;
    m_uarte1_cb.serial = &m_serial_1;
    rt_hw_serial_register(&m_serial_1, "uart1", \
305
                            RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX,  &m_uarte1_cb);
csnd_nc's avatar
csnd_nc 已提交
306 307
#endif  /* BSP_USING_UART1 */

308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
#ifdef BSP_USING_UART2
    m_serial_2.config = config;
    m_serial_2.ops = &_uart_ops;
    m_uarte2_cb.serial = &m_serial_2;
    rt_hw_serial_register(&m_serial_2, "uart2", \
                            RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX,  &m_uarte2_cb);
#endif  /* BSP_USING_UART2 */

#ifdef BSP_USING_UART3
    m_serial_3.config = config;
    m_serial_3.ops = &_uart_ops;
    m_uarte3_cb.serial = &m_serial_3;
    rt_hw_serial_register(&m_serial_3, "uart3", \
                            RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX,  &m_uarte3_cb);
#endif  /* BSP_USING_UART3 */

        return RT_EOK;
csnd_nc's avatar
csnd_nc 已提交
325 326 327
}
#endif /* defined(BSP_USING_UART0) || defined(BSP_USING_UART1) */
#endif /* BSP_USING_UART */