|
@@ -1,26 +1,7 @@
|
|
|
/*
|
|
/*
|
|
|
- * serial.c UART driver
|
|
|
|
|
|
|
+ * Copyright (c) 2006-2021, RT-Thread Development Team
|
|
|
*
|
|
*
|
|
|
- * COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd
|
|
|
|
|
- *
|
|
|
|
|
- * This file is part of RT-Thread (http://www.rt-thread.org)
|
|
|
|
|
- * Maintainer: bernard.xiong <bernard.xiong at gmail.com>
|
|
|
|
|
- *
|
|
|
|
|
- * All rights reserved.
|
|
|
|
|
- *
|
|
|
|
|
- * This program is free software; you can redistribute it and/or modify
|
|
|
|
|
- * it under the terms of the GNU General Public License as published by
|
|
|
|
|
- * the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
- * (at your option) any later version.
|
|
|
|
|
- *
|
|
|
|
|
- * This program is distributed in the hope that it will be useful,
|
|
|
|
|
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
- * GNU General Public License for more details.
|
|
|
|
|
- *
|
|
|
|
|
- * You should have received a copy of the GNU General Public License along
|
|
|
|
|
- * with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
|
*
|
|
*
|
|
|
* Change Logs:
|
|
* Change Logs:
|
|
|
* Date Author Notes
|
|
* Date Author Notes
|
|
@@ -36,12 +17,12 @@
|
|
|
|
|
|
|
|
/*根据IMX6ULL芯片手册<<55.15 UART Memory Map/Register Definition>>的3608页,定义UART的结构体,*/
|
|
/*根据IMX6ULL芯片手册<<55.15 UART Memory Map/Register Definition>>的3608页,定义UART的结构体,*/
|
|
|
typedef struct {
|
|
typedef struct {
|
|
|
- volatile unsigned int URXD; /**< UART Receiver Register, offset: 0x0 串口接收寄存器,偏移地址0x0 */
|
|
|
|
|
- unsigned char RESERVED_0[60];
|
|
|
|
|
|
|
+ volatile unsigned int URXD; /**< UART Receiver Register, offset: 0x0 串口接收寄存器,偏移地址0x0 */
|
|
|
|
|
+ unsigned char RESERVED_0[60];
|
|
|
volatile unsigned int UTXD; /**< UART Transmitter Register, offset: 0x40 串口发送寄存器,偏移地址0x40*/
|
|
volatile unsigned int UTXD; /**< UART Transmitter Register, offset: 0x40 串口发送寄存器,偏移地址0x40*/
|
|
|
- unsigned char RESERVED_1[60];
|
|
|
|
|
- volatile unsigned int UCR1; /**< UART Control Register 1, offset: 0x80 串口控制寄存器1,偏移地址0x80*/
|
|
|
|
|
- volatile unsigned int UCR2; /**< UART Control Register 2, offset: 0x84 串口控制寄存器2,偏移地址0x84*/
|
|
|
|
|
|
|
+ unsigned char RESERVED_1[60];
|
|
|
|
|
+ volatile unsigned int UCR1; /**< UART Control Register 1, offset: 0x80 串口控制寄存器1,偏移地址0x80*/
|
|
|
|
|
+ volatile unsigned int UCR2; /**< UART Control Register 2, offset: 0x84 串口控制寄存器2,偏移地址0x84*/
|
|
|
volatile unsigned int UCR3; /**< UART Control Register 3, offset: 0x88 串口控制寄存器3,偏移地址0x88*/
|
|
volatile unsigned int UCR3; /**< UART Control Register 3, offset: 0x88 串口控制寄存器3,偏移地址0x88*/
|
|
|
volatile unsigned int UCR4; /**< UART Control Register 4, offset: 0x8C 串口控制寄存器4,偏移地址0x8C*/
|
|
volatile unsigned int UCR4; /**< UART Control Register 4, offset: 0x8C 串口控制寄存器4,偏移地址0x8C*/
|
|
|
volatile unsigned int UFCR; /**< UART FIFO Control Register, offset: 0x90 串口FIFO控制寄存器,偏移地址0x90*/
|
|
volatile unsigned int UFCR; /**< UART FIFO Control Register, offset: 0x90 串口FIFO控制寄存器,偏移地址0x90*/
|
|
@@ -50,10 +31,10 @@ volatile unsigned int USR2; /**< UART Status Register 2, offset:
|
|
|
volatile unsigned int UESC; /**< UART Escape Character Register, offset: 0x9C 串口转义字符寄存器,偏移地址0x9C*/
|
|
volatile unsigned int UESC; /**< UART Escape Character Register, offset: 0x9C 串口转义字符寄存器,偏移地址0x9C*/
|
|
|
volatile unsigned int UTIM; /**< UART Escape Timer Register, offset: 0xA0 串口转义定时器寄存器 偏移地址0xA0*/
|
|
volatile unsigned int UTIM; /**< UART Escape Timer Register, offset: 0xA0 串口转义定时器寄存器 偏移地址0xA0*/
|
|
|
volatile unsigned int UBIR; /**< UART BRM Incremental Register, offset: 0xA4 串口二进制倍率增加寄存器 偏移地址0xA4*/
|
|
volatile unsigned int UBIR; /**< UART BRM Incremental Register, offset: 0xA4 串口二进制倍率增加寄存器 偏移地址0xA4*/
|
|
|
- volatile unsigned int UBMR; /**< UART BRM Modulator Register, offset: 0xA8 串口二进制倍率调节寄存器 偏移地址0xA8*/
|
|
|
|
|
|
|
+ volatile unsigned int UBMR; /**< UART BRM Modulator Register, offset: 0xA8 串口二进制倍率调节寄存器 偏移地址0xA8*/
|
|
|
volatile unsigned int UBRC; /**< UART Baud Rate Count Register, offset: 0xAC 串口波特率计数寄存器 偏移地址0xAC*/
|
|
volatile unsigned int UBRC; /**< UART Baud Rate Count Register, offset: 0xAC 串口波特率计数寄存器 偏移地址0xAC*/
|
|
|
volatile unsigned int ONEMS; /**< UART One Millisecond Register, offset: 0xB0 串口一毫秒寄存器 偏移地址0xB0*/
|
|
volatile unsigned int ONEMS; /**< UART One Millisecond Register, offset: 0xB0 串口一毫秒寄存器 偏移地址0xB0*/
|
|
|
- volatile unsigned int UTS; /**< UART Test Register, offset: 0xB4 串口测试寄存器 偏移地址0xB4*/
|
|
|
|
|
|
|
+ volatile unsigned int UTS; /**< UART Test Register, offset: 0xB4 串口测试寄存器 偏移地址0xB4*/
|
|
|
volatile unsigned int UMCR; /**< UART RS-485 Mode Control Register, offset: 0xB8 串口485模式控制寄存器 偏移地址0xB8*/
|
|
volatile unsigned int UMCR; /**< UART RS-485 Mode Control Register, offset: 0xB8 串口485模式控制寄存器 偏移地址0xB8*/
|
|
|
} UART_Type;
|
|
} UART_Type;
|
|
|
|
|
|
|
@@ -87,61 +68,61 @@ static void rt_hw_uart_isr(int irqno, void *param)
|
|
|
|
|
|
|
|
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
|
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
|
|
{
|
|
{
|
|
|
- /* 115200,8n1 */
|
|
|
|
|
- volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA ;
|
|
|
|
|
- volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA ;
|
|
|
|
|
- volatile unsigned int *IOMUXC_UART1_RX_DATA_SELECT_INPUT ;
|
|
|
|
|
- volatile unsigned int *CCM_CSCDR1;
|
|
|
|
|
- volatile unsigned int *CCM_CCGR5;
|
|
|
|
|
-
|
|
|
|
|
- IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x20E0084, 4);
|
|
|
|
|
- IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x20E0088, 4);
|
|
|
|
|
- IOMUXC_UART1_RX_DATA_SELECT_INPUT = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x20E0624, 4);
|
|
|
|
|
- CCM_CSCDR1 = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x020C4024, 4);
|
|
|
|
|
- CCM_CCGR5 = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x020C407C, 4);
|
|
|
|
|
|
|
+ /* 115200,8n1 */
|
|
|
|
|
+ volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA ;
|
|
|
|
|
+ volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA ;
|
|
|
|
|
+ volatile unsigned int *IOMUXC_UART1_RX_DATA_SELECT_INPUT ;
|
|
|
|
|
+ volatile unsigned int *CCM_CSCDR1;
|
|
|
|
|
+ volatile unsigned int *CCM_CCGR5;
|
|
|
|
|
+
|
|
|
|
|
+ IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x20E0084, 4);
|
|
|
|
|
+ IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x20E0088, 4);
|
|
|
|
|
+ IOMUXC_UART1_RX_DATA_SELECT_INPUT = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x20E0624, 4);
|
|
|
|
|
+ CCM_CSCDR1 = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x020C4024, 4);
|
|
|
|
|
+ CCM_CCGR5 = (volatile unsigned int *)rt_hw_kernel_phys_to_virt((void *)0x020C407C, 4);
|
|
|
|
|
|
|
|
struct hw_uart_device * uart = (struct hw_uart_device *)serial->parent.user_data;
|
|
struct hw_uart_device * uart = (struct hw_uart_device *)serial->parent.user_data;
|
|
|
|
|
|
|
|
- UART_Type *uart_reg = (UART_Type *)uart->hw_base;
|
|
|
|
|
|
|
+ UART_Type *uart_reg = (UART_Type *)uart->hw_base;
|
|
|
|
|
|
|
|
- /* 设置UART的总时钟
|
|
|
|
|
- * UART_CLK_ROOT = 80Mhz
|
|
|
|
|
- */
|
|
|
|
|
- *CCM_CSCDR1 &= ~((1<<6) | (0x3f));
|
|
|
|
|
|
|
+ /* 设置UART的总时钟
|
|
|
|
|
+ * UART_CLK_ROOT = 80Mhz
|
|
|
|
|
+ */
|
|
|
|
|
+ *CCM_CSCDR1 &= ~((1<<6) | (0x3f));
|
|
|
|
|
|
|
|
- /* 给UART1模块提供时钟
|
|
|
|
|
- * uart1_clk_enable
|
|
|
|
|
- */
|
|
|
|
|
- *CCM_CCGR5 |= (3<<24);
|
|
|
|
|
|
|
+ /* 给UART1模块提供时钟
|
|
|
|
|
+ * uart1_clk_enable
|
|
|
|
|
+ */
|
|
|
|
|
+ *CCM_CCGR5 |= (3<<24);
|
|
|
|
|
|
|
|
- /* 配置引脚功能 */
|
|
|
|
|
- *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA &= ~0xf;
|
|
|
|
|
- *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA &= ~0xf;
|
|
|
|
|
|
|
+ /* 配置引脚功能 */
|
|
|
|
|
+ *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA &= ~0xf;
|
|
|
|
|
+ *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA &= ~0xf;
|
|
|
|
|
|
|
|
- /* IMX6ULL特殊的地方 */
|
|
|
|
|
- *IOMUXC_UART1_RX_DATA_SELECT_INPUT |= 3;
|
|
|
|
|
|
|
+ /* IMX6ULL特殊的地方 */
|
|
|
|
|
+ *IOMUXC_UART1_RX_DATA_SELECT_INPUT |= 3;
|
|
|
|
|
|
|
|
|
|
|
|
|
- /* 设置波特率
|
|
|
|
|
- * 115200 = 80M/(16*(UBMR+1)/(UBIR+1))
|
|
|
|
|
- * UBIR = 15
|
|
|
|
|
- * 115200 = 80M/(UBMR+1)
|
|
|
|
|
- * UBMR = 80,000,000/115200 = 694 - 1 = 693
|
|
|
|
|
- * 真正的baudrate = 80,000,000/694 = 115274
|
|
|
|
|
- * 先设置UBIR, 后设置UBMR
|
|
|
|
|
- */
|
|
|
|
|
- uart_reg->UFCR |= (5<<7);
|
|
|
|
|
- uart_reg->UBIR = 15;
|
|
|
|
|
- uart_reg->UBMR = 693;
|
|
|
|
|
|
|
+ /* 设置波特率
|
|
|
|
|
+ * 115200 = 80M/(16*(UBMR+1)/(UBIR+1))
|
|
|
|
|
+ * UBIR = 15
|
|
|
|
|
+ * 115200 = 80M/(UBMR+1)
|
|
|
|
|
+ * UBMR = 80,000,000/115200 = 694 - 1 = 693
|
|
|
|
|
+ * 真正的baudrate = 80,000,000/694 = 115274
|
|
|
|
|
+ * 先设置UBIR, 后设置UBMR
|
|
|
|
|
+ */
|
|
|
|
|
+ uart_reg->UFCR |= (5<<7);
|
|
|
|
|
+ uart_reg->UBIR = 15;
|
|
|
|
|
+ uart_reg->UBMR = 693;
|
|
|
|
|
|
|
|
- /* 设置数据格式 */
|
|
|
|
|
- uart_reg->UCR2 |= (1<<14) | (0<<8) | (0<<6) | (1<<5) | (1<<2) | (1<<1);
|
|
|
|
|
|
|
+ /* 设置数据格式 */
|
|
|
|
|
+ uart_reg->UCR2 |= (1<<14) | (0<<8) | (0<<6) | (1<<5) | (1<<2) | (1<<1);
|
|
|
|
|
|
|
|
- /* IMX6ULL芯片要求必须设置 */
|
|
|
|
|
- uart_reg->UCR3 |= (1<<2);
|
|
|
|
|
|
|
+ /* IMX6ULL芯片要求必须设置 */
|
|
|
|
|
+ uart_reg->UCR3 |= (1<<2);
|
|
|
|
|
|
|
|
- /* 使能UART */
|
|
|
|
|
- uart_reg->UCR1 |= (1<<0);
|
|
|
|
|
|
|
+ /* 使能UART */
|
|
|
|
|
+ uart_reg->UCR1 |= (1<<0);
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
return RT_EOK;
|
|
|
}
|
|
}
|
|
@@ -149,11 +130,11 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
|
|
|
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
|
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
|
|
{
|
|
{
|
|
|
struct hw_uart_device *uart;
|
|
struct hw_uart_device *uart;
|
|
|
- UART_Type *uart_reg;
|
|
|
|
|
|
|
+ UART_Type *uart_reg;
|
|
|
|
|
|
|
|
RT_ASSERT(serial != RT_NULL);
|
|
RT_ASSERT(serial != RT_NULL);
|
|
|
uart = (struct hw_uart_device *)serial->parent.user_data;
|
|
uart = (struct hw_uart_device *)serial->parent.user_data;
|
|
|
- uart_reg = (UART_Type *)uart->hw_base;
|
|
|
|
|
|
|
+ uart_reg = (UART_Type *)uart->hw_base;
|
|
|
|
|
|
|
|
switch (cmd)
|
|
switch (cmd)
|
|
|
{
|
|
{
|
|
@@ -164,7 +145,7 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg
|
|
|
|
|
|
|
|
case RT_DEVICE_CTRL_SET_INT:
|
|
case RT_DEVICE_CTRL_SET_INT:
|
|
|
/* enable rx irq */
|
|
/* enable rx irq */
|
|
|
- uart_reg->UCR4 |= (1<<0);
|
|
|
|
|
|
|
+ uart_reg->UCR4 |= (1<<0);
|
|
|
rt_hw_interrupt_umask(uart->irqno);
|
|
rt_hw_interrupt_umask(uart->irqno);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -175,14 +156,14 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg
|
|
|
static int uart_putc(struct rt_serial_device *serial, char c)
|
|
static int uart_putc(struct rt_serial_device *serial, char c)
|
|
|
{
|
|
{
|
|
|
struct hw_uart_device *uart;
|
|
struct hw_uart_device *uart;
|
|
|
- UART_Type *uart_reg;
|
|
|
|
|
|
|
+ UART_Type *uart_reg;
|
|
|
|
|
|
|
|
RT_ASSERT(serial != RT_NULL);
|
|
RT_ASSERT(serial != RT_NULL);
|
|
|
uart = (struct hw_uart_device *)serial->parent.user_data;
|
|
uart = (struct hw_uart_device *)serial->parent.user_data;
|
|
|
- uart_reg = (UART_Type *)uart->hw_base;
|
|
|
|
|
|
|
+ uart_reg = (UART_Type *)uart->hw_base;
|
|
|
|
|
|
|
|
- while ((uart_reg->USR2 & (1<<3)) == 0);
|
|
|
|
|
- uart_reg->UTXD = c;
|
|
|
|
|
|
|
+ while ((uart_reg->USR2 & (1<<3)) == 0);
|
|
|
|
|
+ uart_reg->UTXD = c;
|
|
|
|
|
|
|
|
return 1;
|
|
return 1;
|
|
|
}
|
|
}
|
|
@@ -191,16 +172,16 @@ static int uart_getc(struct rt_serial_device *serial)
|
|
|
{
|
|
{
|
|
|
int ch;
|
|
int ch;
|
|
|
struct hw_uart_device *uart;
|
|
struct hw_uart_device *uart;
|
|
|
- UART_Type *uart_reg;
|
|
|
|
|
|
|
+ UART_Type *uart_reg;
|
|
|
|
|
|
|
|
RT_ASSERT(serial != RT_NULL);
|
|
RT_ASSERT(serial != RT_NULL);
|
|
|
uart = (struct hw_uart_device *)serial->parent.user_data;
|
|
uart = (struct hw_uart_device *)serial->parent.user_data;
|
|
|
- uart_reg = (UART_Type *)uart->hw_base;
|
|
|
|
|
|
|
+ uart_reg = (UART_Type *)uart->hw_base;
|
|
|
|
|
|
|
|
- if ((uart_reg->USR2 & (1<<0)) == 0)
|
|
|
|
|
- ch = -1;
|
|
|
|
|
- else
|
|
|
|
|
- ch = uart_reg->URXD;
|
|
|
|
|
|
|
+ if ((uart_reg->USR2 & (1<<0)) == 0)
|
|
|
|
|
+ ch = -1;
|
|
|
|
|
+ else
|
|
|
|
|
+ ch = uart_reg->URXD;
|
|
|
|
|
|
|
|
return ch;
|
|
return ch;
|
|
|
}
|
|
}
|