Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
人间散章
rt-thread
提交
d64a7e05
R
rt-thread
项目概览
人间散章
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
d64a7e05
编写于
4月 27, 2020
作者:
B
Bernard Xiong
提交者:
GitHub
4月 27, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3530 from tekkamanninja/k210_drv_uart_upstream
K210 drv uart upstream
上级
bc7d903c
609911be
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
314 addition
and
43 deletion
+314
-43
bsp/k210/driver/Kconfig
bsp/k210/driver/Kconfig
+33
-6
bsp/k210/driver/drv_io_config.c
bsp/k210/driver/drv_io_config.c
+21
-1
bsp/k210/driver/drv_uart.c
bsp/k210/driver/drv_uart.c
+260
-36
未找到文件。
bsp/k210/driver/Kconfig
浏览文件 @
d64a7e05
...
...
@@ -2,17 +2,44 @@ config BSP_USING_UART_HS
bool "Enable High Speed UART"
default y
config BSP_USING_UART1
bool "Enable UART1 (GPIO0/1)"
menu "General Purpose UARTs"
menuconfig BSP_USING_UART1
bool "Enable UART1"
default n
if BSP_USING_UART1
config BSP_UART1_TXD_PIN
int "uart1 TXD pin number"
default 20
config BSP_UART1_RXD_PIN
int "uart1 RXD pin number"
default 21
endif
config BSP_USING_UART2
bool "Enable UART2
(GPIO0/1)
"
menu
config BSP_USING_UART2
bool "Enable UART2"
default n
if BSP_USING_UART2
config BSP_UART2_TXD_PIN
int "uart2 TXD pin number"
default 28
config BSP_UART2_RXD_PIN
int "uart2 RXD pin number"
default 27
endif
config BSP_USING_UART3
bool "Enable UART3
(GPIO0/1)
"
menu
config BSP_USING_UART3
bool "Enable UART3"
default n
if BSP_USING_UART3
config BSP_UART3_TXD_PIN
int "uart3 TXD pin number"
default 22
config BSP_UART3_RXD_PIN
int "uart3 RXD pin number"
default 23
endif
endmenu
config BSP_USING_I2C1
bool "Enable I2C1 (GPIO0/1)"
...
...
bsp/k210/driver/drv_io_config.c
浏览文件 @
d64a7e05
...
...
@@ -63,6 +63,18 @@ static struct io_config
#endif
#endif
#ifdef BSP_USING_UART1
IOCONFIG
(
BSP_UART1_TXD_PIN
,
FUNC_UART1_TX
),
IOCONFIG
(
BSP_UART1_RXD_PIN
,
FUNC_UART1_RX
),
#endif
#ifdef BSP_USING_UART2
IOCONFIG
(
BSP_UART2_TXD_PIN
,
FUNC_UART2_TX
),
IOCONFIG
(
BSP_UART2_RXD_PIN
,
FUNC_UART2_RX
),
#endif
#ifdef BSP_USING_UART3
IOCONFIG
(
BSP_UART3_TXD_PIN
,
FUNC_UART3_TX
),
IOCONFIG
(
BSP_UART3_RXD_PIN
,
FUNC_UART3_RX
),
#endif
};
static
int
print_io_config
()
...
...
@@ -89,6 +101,14 @@ int io_config_init(void)
sysctl_set_power_mode
(
SYSCTL_POWER_BANK0
,
SYSCTL_POWER_V18
);
sysctl_set_power_mode
(
SYSCTL_POWER_BANK1
,
SYSCTL_POWER_V18
);
sysctl_set_power_mode
(
SYSCTL_POWER_BANK2
,
SYSCTL_POWER_V18
);
#ifdef BSP_USING_UART2
// for IO-27/28
sysctl_set_power_mode
(
SYSCTL_POWER_BANK4
,
SYSCTL_POWER_V33
);
#endif
#if defined(BSP_USING_UART1) || defined(BSP_USING_UART3)
// for IO-20~23
sysctl_set_power_mode
(
SYSCTL_POWER_BANK3
,
SYSCTL_POWER_V33
);
#endif
for
(
i
=
0
;
i
<
count
;
i
++
)
{
...
...
bsp/k210/driver/drv_uart.c
浏览文件 @
d64a7e05
...
...
@@ -17,10 +17,12 @@
#include <stdio.h>
#include <sysctl.h>
//
#include "uart.h"
#include "uart.h"
#include "uarths.h"
#include "plic.h"
#define UART_DEFAULT_BAUDRATE 115200
static
volatile
uarths_t
*
const
_uarths
=
(
volatile
uarths_t
*
)
UARTHS_BASE_ADDR
;
struct
device_uart
...
...
@@ -29,22 +31,71 @@ struct device_uart
rt_uint32_t
irqno
;
};
static
rt_err_t
uart_configure
(
struct
rt_serial_device
*
serial
,
struct
serial_configure
*
cfg
);
static
rt_err_t
rt_uarths_configure
(
struct
rt_serial_device
*
serial
,
struct
serial_configure
*
cfg
);
static
rt_err_t
uarths_control
(
struct
rt_serial_device
*
serial
,
int
cmd
,
void
*
arg
);
static
int
drv_uarths_putc
(
struct
rt_serial_device
*
serial
,
char
c
);
static
int
drv_uarths_getc
(
struct
rt_serial_device
*
serial
);
static
void
uarths_irq_handler
(
int
irqno
,
void
*
param
);
static
rt_err_t
rt_uart_configure
(
struct
rt_serial_device
*
serial
,
struct
serial_configure
*
cfg
);
static
rt_err_t
uart_control
(
struct
rt_serial_device
*
serial
,
int
cmd
,
void
*
arg
);
static
int
drv_uart_putc
(
struct
rt_serial_device
*
serial
,
char
c
);
static
int
drv_uart_getc
(
struct
rt_serial_device
*
serial
);
static
void
uart_irq_handler
(
int
irqno
,
void
*
param
);
const
struct
rt_uart_ops
_uart_hs_ops
=
{
rt_uarths_configure
,
uarths_control
,
drv_uarths_putc
,
drv_uarths_getc
,
RT_NULL
};
const
struct
rt_uart_ops
_uart_ops
=
{
uart_configure
,
rt_
uart_configure
,
uart_control
,
drv_uart_putc
,
drv_uart_getc
,
//TODO: add DMA support
RT_NULL
};
/* START ported from kendryte standalone sdk uart.c */
#define __UART_BRATE_CONST 16
volatile
uart_t
*
const
_uart
[
3
]
=
{
(
volatile
uart_t
*
)
UART1_BASE_ADDR
,
(
volatile
uart_t
*
)
UART2_BASE_ADDR
,
(
volatile
uart_t
*
)
UART3_BASE_ADDR
};
void
uart_init
(
uart_device_number_t
channel
)
{
sysctl_clock_enable
(
SYSCTL_CLOCK_UART1
+
channel
);
sysctl_reset
(
SYSCTL_RESET_UART1
+
channel
);
}
/* END ported from kendryte standalone sdk uart.c */
static
inline
uart_device_number_t
_get_uart_channel
(
rt_uint32_t
addr
)
{
switch
(
addr
)
{
case
UART1_BASE_ADDR
:
return
UART_DEVICE_1
;
case
UART2_BASE_ADDR
:
return
UART_DEVICE_2
;
case
UART3_BASE_ADDR
:
return
UART_DEVICE_3
;
default:
return
UART_DEVICE_MAX
;
}
}
/*
* UART Initiation
*/
...
...
@@ -62,7 +113,7 @@ int rt_hw_uart_init(void)
serial
=
&
serial_hs
;
uart
=
&
uart_hs
;
serial
->
ops
=
&
_uart_ops
;
serial
->
ops
=
&
_uart_
hs_
ops
;
serial
->
config
=
config
;
serial
->
config
.
baud_rate
=
115200
;
...
...
@@ -86,36 +137,79 @@ int rt_hw_uart_init(void)
serial
->
ops
=
&
_uart_ops
;
serial
->
config
=
config
;
serial
->
config
.
baud_rate
=
115200
;
serial
->
config
.
baud_rate
=
UART_DEFAULT_BAUDRATE
;
uart
->
hw_base
=
UART1_BASE_ADDR
;
uart
->
irqno
=
IRQN_UART1_INTERRUPT
;
uart_init
(
UART_DEVICE_1
);
rt_hw_serial_register
(
serial
,
"uart
hs
"
,
"uart
1
"
,
RT_DEVICE_FLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
,
uart
);
}
#endif
#ifdef BSP_USING_UART2
{
static
struct
rt_serial_device
serial2
;
static
struct
device_uart
uart2
;
serial
=
&
serial2
;
uart
=
&
uart2
;
serial
->
ops
=
&
_uart_ops
;
serial
->
config
=
config
;
serial
->
config
.
baud_rate
=
UART_DEFAULT_BAUDRATE
;
uart
->
hw_base
=
UART2_BASE_ADDR
;
uart
->
irqno
=
IRQN_UART2_INTERRUPT
;
uart_init
(
UART_DEVICE_2
);
rt_hw_serial_register
(
serial
,
"uart2"
,
RT_DEVICE_FLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
,
uart
);
}
#endif
#ifdef BSP_USING_UART3
{
static
struct
rt_serial_device
serial3
;
static
struct
device_uart
uart3
;
serial
=
&
serial3
;
uart
=
&
uart3
;
serial
->
ops
=
&
_uart_ops
;
serial
->
config
=
config
;
serial
->
config
.
baud_rate
=
UART_DEFAULT_BAUDRATE
;
uart
->
hw_base
=
UART3_BASE_ADDR
;
uart
->
irqno
=
IRQN_UART3_INTERRUPT
;
uart_init
(
UART_DEVICE_3
);
rt_hw_serial_register
(
serial
,
"uart3"
,
RT_DEVICE_FLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
,
uart
);
}
#endif
return
0
;
}
/*
* UART interface
* UART
HS
interface
*/
static
rt_err_t
uart
_configure
(
struct
rt_serial_device
*
serial
,
struct
serial_configure
*
cfg
)
static
rt_err_t
rt_uarths
_configure
(
struct
rt_serial_device
*
serial
,
struct
serial_configure
*
cfg
)
{
rt_uint32_t
baud_div
;
struct
device_uart
*
uart
;
uint32_t
freq
=
sysctl_clock_get_freq
(
SYSCTL_CLOCK_CPU
);
uint16_t
div
=
freq
/
cfg
->
baud_rate
-
1
;
uint32_t
freq
_hs
=
sysctl_clock_get_freq
(
SYSCTL_CLOCK_CPU
);
uint16_t
div
_hs
=
freq_hs
/
cfg
->
baud_rate
-
1
;
RT_ASSERT
(
serial
!=
RT_NULL
);
serial
->
config
=
*
cfg
;
...
...
@@ -125,7 +219,7 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
if
(
uart
->
hw_base
==
UARTHS_BASE_ADDR
)
{
_uarths
->
div
.
div
=
div
;
_uarths
->
div
.
div
=
div
_hs
;
_uarths
->
txctrl
.
txen
=
1
;
_uarths
->
rxctrl
.
rxen
=
1
;
_uarths
->
txctrl
.
txcnt
=
0
;
...
...
@@ -137,13 +231,14 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
}
else
{
return
(
-
1
);
/* other uart */
}
return
(
RT_EOK
);
}
static
rt_err_t
uart_control
(
struct
rt_serial_device
*
serial
,
int
cmd
,
void
*
arg
)
static
rt_err_t
uart
hs
_control
(
struct
rt_serial_device
*
serial
,
int
cmd
,
void
*
arg
)
{
struct
device_uart
*
uart
;
...
...
@@ -160,7 +255,7 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg
case
RT_DEVICE_CTRL_SET_INT
:
/* install interrupt */
rt_hw_interrupt_install
(
uart
->
irqno
,
uart_irq_handler
,
rt_hw_interrupt_install
(
uart
->
irqno
,
uart
hs
_irq_handler
,
serial
,
serial
->
parent
.
parent
.
name
);
rt_hw_interrupt_umask
(
uart
->
irqno
);
break
;
...
...
@@ -169,38 +264,168 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg
return
(
RT_EOK
);
}
static
int
drv_uart_putc
(
struct
rt_serial_device
*
serial
,
char
c
)
static
int
drv_uarths_putc
(
struct
rt_serial_device
*
serial
,
char
c
)
{
struct
device_uart
*
uart
;
struct
device_uart
*
uart
=
serial
->
parent
.
user_data
;
RT_ASSERT
(
uart
->
hw_base
==
UARTHS_BASE_ADDR
);
uart
=
serial
->
parent
.
user_data
;
if
(
uart
->
hw_base
==
UARTHS_BASE_ADDR
)
{
while
(
_uarths
->
txdata
.
full
);
_uarths
->
txdata
.
data
=
(
uint8_t
)
c
;
}
else
{
/* other uart */
}
return
(
1
);
}
static
int
drv_uart_getc
(
struct
rt_serial_device
*
serial
)
static
int
drv_uart
hs
_getc
(
struct
rt_serial_device
*
serial
)
{
int
ret
=
-
1
;
struct
device_uart
*
uart
=
serial
->
parent
.
user_data
;
RT_ASSERT
(
uart
->
hw_base
==
UARTHS_BASE_ADDR
);
if
(
uart
->
hw_base
==
UARTHS_BASE_ADDR
)
{
uarths_rxdata_t
recv
=
_uarths
->
rxdata
;
if
(
recv
.
empty
)
return
EOF
;
else
return
(
recv
.
data
&
0xff
);
/* Receive Data Available */
return
(
-
1
);
}
/* UARTHS ISR */
static
void
uarths_irq_handler
(
int
irqno
,
void
*
param
)
{
struct
rt_serial_device
*
serial
=
(
struct
rt_serial_device
*
)
param
;
struct
device_uart
*
uart
=
serial
->
parent
.
user_data
;
RT_ASSERT
(
uart
->
hw_base
==
UARTHS_BASE_ADDR
);
/* read interrupt status and clear it */
if
(
_uarths
->
ip
.
rxwm
)
rt_hw_serial_isr
(
serial
,
RT_SERIAL_EVENT_RX_IND
);
}
/*
* UART interface
*/
static
rt_err_t
rt_uart_configure
(
struct
rt_serial_device
*
serial
,
struct
serial_configure
*
cfg
)
{
struct
device_uart
*
uart
;
uart_bitwidth_t
data_width
=
(
uart_bitwidth_t
)
cfg
->
data_bits
;
uart_stopbit_t
stopbit
=
(
uart_stopbit_t
)
cfg
->
stop_bits
;
uart_parity_t
parity
=
(
uart_parity_t
)
cfg
->
parity
;
uint32_t
freq
=
sysctl_clock_get_freq
(
SYSCTL_CLOCK_APB0
);
uint32_t
divisor
=
freq
/
(
uint32_t
)
cfg
->
baud_rate
;
uint8_t
dlh
=
divisor
>>
12
;
uint8_t
dll
=
(
divisor
-
(
dlh
<<
12
))
/
__UART_BRATE_CONST
;
uint8_t
dlf
=
divisor
-
(
dlh
<<
12
)
-
dll
*
__UART_BRATE_CONST
;
RT_ASSERT
(
serial
!=
RT_NULL
);
serial
->
config
=
*
cfg
;
uart
=
serial
->
parent
.
user_data
;
RT_ASSERT
(
uart
!=
RT_NULL
);
uart_device_number_t
channel
=
_get_uart_channel
(
uart
->
hw_base
);
RT_ASSERT
(
channel
!=
UART_DEVICE_MAX
);
RT_ASSERT
(
data_width
>=
5
&&
data_width
<=
8
);
if
(
data_width
==
5
)
{
RT_ASSERT
(
stopbit
!=
UART_STOP_2
);
}
else
{
RT_ASSERT
(
stopbit
!=
UART_STOP_1_5
);
}
uint32_t
stopbit_val
=
stopbit
==
UART_STOP_1
?
0
:
1
;
uint32_t
parity_val
;
switch
(
parity
)
{
case
UART_PARITY_NONE
:
parity_val
=
0
;
break
;
case
UART_PARITY_ODD
:
parity_val
=
1
;
break
;
case
UART_PARITY_EVEN
:
parity_val
=
3
;
break
;
default:
RT_ASSERT
(
!
"Invalid parity"
);
break
;
}
_uart
[
channel
]
->
LCR
|=
1u
<<
7
;
_uart
[
channel
]
->
DLH
=
dlh
;
_uart
[
channel
]
->
DLL
=
dll
;
_uart
[
channel
]
->
DLF
=
dlf
;
_uart
[
channel
]
->
LCR
=
0
;
_uart
[
channel
]
->
LCR
=
(
data_width
-
5
)
|
(
stopbit_val
<<
2
)
|
(
parity_val
<<
3
);
_uart
[
channel
]
->
LCR
&=
~
(
1u
<<
7
);
_uart
[
channel
]
->
IER
|=
0x80
;
/* THRE */
_uart
[
channel
]
->
FCR
=
UART_RECEIVE_FIFO_1
<<
6
|
UART_SEND_FIFO_8
<<
4
|
0x1
<<
3
|
0x1
;
return
(
RT_EOK
);
}
static
rt_err_t
uart_control
(
struct
rt_serial_device
*
serial
,
int
cmd
,
void
*
arg
)
{
struct
device_uart
*
uart
;
uart
=
serial
->
parent
.
user_data
;
uart_device_number_t
channel
=
_get_uart_channel
(
uart
->
hw_base
);
RT_ASSERT
(
uart
!=
RT_NULL
);
RT_ASSERT
(
channel
!=
UART_DEVICE_MAX
);
switch
(
cmd
)
{
case
RT_DEVICE_CTRL_CLR_INT
:
/* Disable the UART Interrupt */
rt_hw_interrupt_mask
(
uart
->
irqno
);
_uart
[
channel
]
->
IER
&=
~
0x1
;
break
;
case
RT_DEVICE_CTRL_SET_INT
:
/* install interrupt */
rt_hw_interrupt_install
(
uart
->
irqno
,
uart_irq_handler
,
serial
,
serial
->
parent
.
parent
.
name
);
rt_hw_interrupt_umask
(
uart
->
irqno
);
_uart
[
channel
]
->
IER
|=
0x1
;
break
;
}
return
(
RT_EOK
);
}
static
int
drv_uart_putc
(
struct
rt_serial_device
*
serial
,
char
c
)
{
struct
device_uart
*
uart
=
serial
->
parent
.
user_data
;
uart_device_number_t
channel
=
_get_uart_channel
(
uart
->
hw_base
);
RT_ASSERT
(
channel
!=
UART_DEVICE_MAX
);
while
(
_uart
[
channel
]
->
LSR
&
(
1u
<<
5
));
_uart
[
channel
]
->
THR
=
c
;
return
(
1
);
}
static
int
drv_uart_getc
(
struct
rt_serial_device
*
serial
)
{
struct
device_uart
*
uart
=
serial
->
parent
.
user_data
;
uart_device_number_t
channel
=
_get_uart_channel
(
uart
->
hw_base
);
RT_ASSERT
(
channel
!=
UART_DEVICE_MAX
);
if
(
_uart
[
channel
]
->
LSR
&
1
)
return
(
char
)(
_uart
[
channel
]
->
RBR
&
0xff
);
else
return
EOF
;
/* Receive Data Available */
return
(
-
1
);
...
...
@@ -209,21 +434,20 @@ static int drv_uart_getc(struct rt_serial_device *serial)
/* UART ISR */
static
void
uart_irq_handler
(
int
irqno
,
void
*
param
)
{
rt_ubase_t
isr
;
struct
rt_serial_device
*
serial
=
(
struct
rt_serial_device
*
)
param
;
struct
device_uart
*
uart
=
serial
->
parent
.
user_data
;
uart_device_number_t
channel
=
_get_uart_channel
(
uart
->
hw_base
);
RT_ASSERT
(
channel
!=
UART_DEVICE_MAX
);
/* read interrupt status and clear it */
if
(
uart
->
hw_base
==
UARTHS_BASE_ADDR
)
{
if
(
_uarths
->
ip
.
rxwm
)
if
(
_uart
[
channel
]
->
LSR
)
rt_hw_serial_isr
(
serial
,
RT_SERIAL_EVENT_RX_IND
);
}
}
/* WEAK for SDK 0.5.6 */
RT_WEAK
void
uart_debug_init
(
in
t
uart_channel
)
RT_WEAK
void
uart_debug_init
(
uart_device_number_
t
uart_channel
)
{
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录