Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
红岛
rt-thread
提交
d94be14d
R
rt-thread
项目概览
红岛
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d94be14d
编写于
6月 05, 2021
作者:
C
chenjh
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[serial] 增加serial_v2版本的框架和基于stm32的串口驱动
上级
5c8625c8
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
2973 addition
and
44 deletion
+2973
-44
bsp/stm32/libraries/HAL_Drivers/SConscript
bsp/stm32/libraries/HAL_Drivers/SConscript
+4
-1
bsp/stm32/libraries/HAL_Drivers/config/l4/dma_config.h
bsp/stm32/libraries/HAL_Drivers/config/l4/dma_config.h
+11
-0
bsp/stm32/libraries/HAL_Drivers/drv_common.c
bsp/stm32/libraries/HAL_Drivers/drv_common.c
+4
-0
bsp/stm32/libraries/HAL_Drivers/drv_usart_v2.c
bsp/stm32/libraries/HAL_Drivers/drv_usart_v2.c
+1137
-0
bsp/stm32/libraries/HAL_Drivers/drv_usart_v2.h
bsp/stm32/libraries/HAL_Drivers/drv_usart_v2.h
+83
-0
bsp/stm32/stm32l475-atk-pandora/.config
bsp/stm32/stm32l475-atk-pandora/.config
+250
-13
bsp/stm32/stm32l475-atk-pandora/board/Kconfig
bsp/stm32/stm32l475-atk-pandora/board/Kconfig
+49
-13
bsp/stm32/stm32l475-atk-pandora/rtconfig.h
bsp/stm32/stm32l475-atk-pandora/rtconfig.h
+40
-3
components/drivers/Kconfig
components/drivers/Kconfig
+19
-11
components/drivers/include/drivers/serial_v2.h
components/drivers/include/drivers/serial_v2.h
+193
-0
components/drivers/include/rtdevice.h
components/drivers/include/rtdevice.h
+4
-0
components/drivers/serial/SConscript
components/drivers/serial/SConscript
+8
-3
components/drivers/serial/serial_v2.c
components/drivers/serial/serial_v2.c
+1171
-0
未找到文件。
bsp/stm32/libraries/HAL_Drivers/SConscript
浏览文件 @
d94be14d
...
...
@@ -12,7 +12,10 @@ if GetDepend(['RT_USING_PIN']):
src
+=
[
'drv_gpio.c'
]
if
GetDepend
([
'RT_USING_SERIAL'
]):
src
+=
[
'drv_usart.c'
]
if
GetDepend
([
'RT_USING_SERIAL_V2'
]):
src
+=
[
'drv_usart_v2.c'
]
else
:
src
+=
[
'drv_usart.c'
]
if
GetDepend
([
'RT_USING_HWTIMER'
]):
src
+=
[
'drv_hwtimer.c'
]
...
...
bsp/stm32/libraries/HAL_Drivers/config/l4/dma_config.h
浏览文件 @
d94be14d
...
...
@@ -127,6 +127,17 @@ extern "C" {
#endif
/* DMA1 channel7 */
#if defined(BSP_UART2_TX_USING_DMA) && !defined(UART2_TX_DMA_INSTANCE)
#define UART2_DMA_TX_IRQHandler DMA1_Channel7_IRQHandler
#define UART2_TX_DMA_RCC RCC_AHB1ENR_DMA1EN
#define UART2_TX_DMA_INSTANCE DMA1_Channel7
#if defined(DMAMUX1)
/* for L4+ */
#define UART2_TX_DMA_REQUEST DMA_REQUEST_USART2_TX
#else
/* for L4 */
#define UART2_TX_DMA_REQUEST DMA_REQUEST_2
#endif
/* DMAMUX1 */
#define UART2_TX_DMA_IRQ DMA1_Channel7_IRQn
#endif
/* DMA2 channel1 */
#if defined(BSP_UART5_TX_USING_DMA) && !defined(UART5_TX_DMA_INSTANCE)
...
...
bsp/stm32/libraries/HAL_Drivers/drv_common.c
浏览文件 @
d94be14d
...
...
@@ -12,8 +12,12 @@
#include "board.h"
#ifdef RT_USING_SERIAL
#ifdef RT_USING_SERIAL_V2
#include "drv_usart_v2.h"
#else
#include "drv_usart.h"
#endif
#endif
#ifdef RT_USING_FINSH
#include <finsh.h>
...
...
bsp/stm32/libraries/HAL_Drivers/drv_usart_v2.c
0 → 100644
浏览文件 @
d94be14d
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-01 KyleChan first version
*/
#include "board.h"
#include "drv_usart_v2.h"
#ifdef RT_USING_SERIAL_V2
//#define DRV_DEBUG
#define DBG_TAG "drv.usart"
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif
/* DRV_DEBUG */
#include <rtdbg.h>
#if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) && \
!defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6) && \
!defined(BSP_USING_UART7) && !defined(BSP_USING_UART8) && !defined(BSP_USING_LPUART1)
#error "Please define at least one BSP_USING_UARTx"
/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
#endif
#ifdef RT_SERIAL_USING_DMA
static
void
stm32_dma_config
(
struct
rt_serial_device
*
serial
,
rt_ubase_t
flag
);
#endif
enum
{
#ifdef BSP_USING_UART1
UART1_INDEX
,
#endif
#ifdef BSP_USING_UART2
UART2_INDEX
,
#endif
#ifdef BSP_USING_UART3
UART3_INDEX
,
#endif
#ifdef BSP_USING_UART4
UART4_INDEX
,
#endif
#ifdef BSP_USING_UART5
UART5_INDEX
,
#endif
#ifdef BSP_USING_UART6
UART6_INDEX
,
#endif
#ifdef BSP_USING_UART7
UART7_INDEX
,
#endif
#ifdef BSP_USING_UART8
UART8_INDEX
,
#endif
#ifdef BSP_USING_LPUART1
LPUART1_INDEX
,
#endif
};
static
struct
stm32_uart_config
uart_config
[]
=
{
#ifdef BSP_USING_UART1
UART1_CONFIG
,
#endif
#ifdef BSP_USING_UART2
UART2_CONFIG
,
#endif
#ifdef BSP_USING_UART3
UART3_CONFIG
,
#endif
#ifdef BSP_USING_UART4
UART4_CONFIG
,
#endif
#ifdef BSP_USING_UART5
UART5_CONFIG
,
#endif
#ifdef BSP_USING_UART6
UART6_CONFIG
,
#endif
#ifdef BSP_USING_UART7
UART7_CONFIG
,
#endif
#ifdef BSP_USING_UART8
UART8_CONFIG
,
#endif
#ifdef BSP_USING_LPUART1
LPUART1_CONFIG
,
#endif
};
static
struct
stm32_uart
uart_obj
[
sizeof
(
uart_config
)
/
sizeof
(
uart_config
[
0
])]
=
{
0
};
static
rt_err_t
stm32_configure
(
struct
rt_serial_device
*
serial
,
struct
serial_configure
*
cfg
)
{
struct
stm32_uart
*
uart
;
RT_ASSERT
(
serial
!=
RT_NULL
);
RT_ASSERT
(
cfg
!=
RT_NULL
);
uart
=
rt_container_of
(
serial
,
struct
stm32_uart
,
serial
);
uart
->
handle
.
Instance
=
uart
->
config
->
Instance
;
uart
->
handle
.
Init
.
BaudRate
=
cfg
->
baud_rate
;
uart
->
handle
.
Init
.
HwFlowCtl
=
UART_HWCONTROL_NONE
;
uart
->
handle
.
Init
.
Mode
=
UART_MODE_TX_RX
;
uart
->
handle
.
Init
.
OverSampling
=
UART_OVERSAMPLING_16
;
if
(
uart
->
handle
.
Instance
==
USART3
)
{
uart
->
handle
.
Init
.
HwFlowCtl
=
UART_HWCONTROL_RTS_CTS
;
}
switch
(
cfg
->
data_bits
)
{
case
DATA_BITS_8
:
if
(
cfg
->
parity
==
PARITY_ODD
||
cfg
->
parity
==
PARITY_EVEN
)
uart
->
handle
.
Init
.
WordLength
=
UART_WORDLENGTH_9B
;
else
uart
->
handle
.
Init
.
WordLength
=
UART_WORDLENGTH_8B
;
break
;
case
DATA_BITS_9
:
uart
->
handle
.
Init
.
WordLength
=
UART_WORDLENGTH_9B
;
break
;
default:
uart
->
handle
.
Init
.
WordLength
=
UART_WORDLENGTH_8B
;
break
;
}
switch
(
cfg
->
stop_bits
)
{
case
STOP_BITS_1
:
uart
->
handle
.
Init
.
StopBits
=
UART_STOPBITS_1
;
break
;
case
STOP_BITS_2
:
uart
->
handle
.
Init
.
StopBits
=
UART_STOPBITS_2
;
break
;
default:
uart
->
handle
.
Init
.
StopBits
=
UART_STOPBITS_1
;
break
;
}
switch
(
cfg
->
parity
)
{
case
PARITY_NONE
:
uart
->
handle
.
Init
.
Parity
=
UART_PARITY_NONE
;
break
;
case
PARITY_ODD
:
uart
->
handle
.
Init
.
Parity
=
UART_PARITY_ODD
;
break
;
case
PARITY_EVEN
:
uart
->
handle
.
Init
.
Parity
=
UART_PARITY_EVEN
;
break
;
default:
uart
->
handle
.
Init
.
Parity
=
UART_PARITY_NONE
;
break
;
}
#ifdef RT_SERIAL_USING_DMA
uart
->
dma_rx
.
remaining_cnt
=
serial
->
config
.
rx_bufsz
;
#endif
if
(
HAL_UART_Init
(
&
uart
->
handle
)
!=
HAL_OK
)
{
return
-
RT_ERROR
;
}
return
RT_EOK
;
}
static
rt_err_t
stm32_control
(
struct
rt_serial_device
*
serial
,
int
cmd
,
void
*
arg
)
{
struct
stm32_uart
*
uart
;
rt_ubase_t
ctrl_arg
=
(
rt_ubase_t
)
arg
;
RT_ASSERT
(
serial
!=
RT_NULL
);
uart
=
rt_container_of
(
serial
,
struct
stm32_uart
,
serial
);
if
(
ctrl_arg
&
(
RT_DEVICE_FLAG_RX_BLOCKING
|
RT_DEVICE_FLAG_RX_NON_BLOCKING
))
{
if
(
uart
->
uart_dma_flag
&
RT_DEVICE_FLAG_DMA_RX
)
ctrl_arg
=
RT_DEVICE_FLAG_DMA_RX
;
else
ctrl_arg
=
RT_DEVICE_FLAG_INT_RX
;
}
else
if
(
ctrl_arg
&
(
RT_DEVICE_FLAG_TX_BLOCKING
|
RT_DEVICE_FLAG_TX_NON_BLOCKING
))
{
if
(
uart
->
uart_dma_flag
&
RT_DEVICE_FLAG_DMA_TX
)
ctrl_arg
=
RT_DEVICE_FLAG_DMA_TX
;
else
ctrl_arg
=
RT_DEVICE_FLAG_INT_TX
;
}
switch
(
cmd
)
{
/* disable interrupt */
case
RT_DEVICE_CTRL_CLR_INT
:
NVIC_DisableIRQ
(
uart
->
config
->
irq_type
);
if
(
ctrl_arg
==
RT_DEVICE_FLAG_INT_RX
)
__HAL_UART_DISABLE_IT
(
&
(
uart
->
handle
),
UART_IT_RXNE
);
else
if
(
ctrl_arg
==
RT_DEVICE_FLAG_INT_TX
)
__HAL_UART_DISABLE_IT
(
&
(
uart
->
handle
),
UART_IT_TXE
);
#ifdef RT_SERIAL_USING_DMA
else
if
(
ctrl_arg
==
RT_DEVICE_FLAG_DMA_RX
)
{
__HAL_UART_DISABLE_IT
(
&
(
uart
->
handle
),
UART_IT_RXNE
);
HAL_NVIC_DisableIRQ
(
uart
->
config
->
dma_rx
->
dma_irq
);
if
(
HAL_DMA_Abort
(
&
(
uart
->
dma_rx
.
handle
))
!=
HAL_OK
)
{
RT_ASSERT
(
0
);
}
if
(
HAL_DMA_DeInit
(
&
(
uart
->
dma_rx
.
handle
))
!=
HAL_OK
)
{
RT_ASSERT
(
0
);
}
}
else
if
(
ctrl_arg
==
RT_DEVICE_FLAG_DMA_TX
)
{
__HAL_UART_DISABLE_IT
(
&
(
uart
->
handle
),
UART_IT_TC
);
HAL_NVIC_DisableIRQ
(
uart
->
config
->
dma_tx
->
dma_irq
);
if
(
HAL_DMA_DeInit
(
&
(
uart
->
dma_tx
.
handle
))
!=
HAL_OK
)
{
RT_ASSERT
(
0
);
}
}
#endif
break
;
case
RT_DEVICE_CTRL_SET_INT
:
HAL_NVIC_SetPriority
(
uart
->
config
->
irq_type
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
uart
->
config
->
irq_type
);
if
(
ctrl_arg
==
RT_DEVICE_FLAG_INT_RX
)
__HAL_UART_ENABLE_IT
(
&
(
uart
->
handle
),
UART_IT_RXNE
);
else
if
(
ctrl_arg
==
RT_DEVICE_FLAG_INT_TX
)
__HAL_UART_ENABLE_IT
(
&
(
uart
->
handle
),
UART_IT_TXE
);
break
;
case
RT_DEVICE_CTRL_CONFIG
:
if
(
ctrl_arg
&
(
RT_DEVICE_FLAG_DMA_RX
|
RT_DEVICE_FLAG_DMA_TX
))
{
#ifdef RT_SERIAL_USING_DMA
stm32_dma_config
(
serial
,
ctrl_arg
);
#endif
}
else
stm32_control
(
serial
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
ctrl_arg
);
break
;
case
RT_DEVICE_CHECK_OPTMODE
:
{
if
(
ctrl_arg
&
RT_DEVICE_FLAG_DMA_TX
)
return
RT_SERIAL_TX_BLOCKING_NO_BUFFER
;
else
return
RT_SERIAL_TX_BLOCKING_BUFFER
;
}
case
RT_DEVICE_CTRL_CLOSE
:
if
(
HAL_UART_DeInit
(
&
(
uart
->
handle
))
!=
HAL_OK
)
{
RT_ASSERT
(
0
)
}
break
;
}
return
RT_EOK
;
}
static
int
stm32_putc
(
struct
rt_serial_device
*
serial
,
char
c
)
{
struct
stm32_uart
*
uart
;
RT_ASSERT
(
serial
!=
RT_NULL
);
uart
=
rt_container_of
(
serial
,
struct
stm32_uart
,
serial
);
while
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_TC
)
==
RESET
);
UART_INSTANCE_CLEAR_FUNCTION
(
&
(
uart
->
handle
),
UART_FLAG_TC
);
UART_SET_TDR
(
&
uart
->
handle
,
c
);
return
1
;
}
static
int
stm32_getc
(
struct
rt_serial_device
*
serial
)
{
int
ch
;
struct
stm32_uart
*
uart
;
RT_ASSERT
(
serial
!=
RT_NULL
);
uart
=
rt_container_of
(
serial
,
struct
stm32_uart
,
serial
);
ch
=
-
1
;
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_RXNE
)
!=
RESET
)
ch
=
UART_GET_RDR
(
&
uart
->
handle
);
return
ch
;
}
static
rt_size_t
stm32_transmit
(
struct
rt_serial_device
*
serial
,
rt_uint8_t
*
buf
,
rt_size_t
size
,
rt_uint32_t
tx_flag
)
{
struct
stm32_uart
*
uart
;
RT_ASSERT
(
serial
!=
RT_NULL
);
RT_ASSERT
(
buf
!=
RT_NULL
);
uart
=
rt_container_of
(
serial
,
struct
stm32_uart
,
serial
);
if
(
uart
->
uart_dma_flag
&
RT_DEVICE_FLAG_DMA_TX
)
{
HAL_UART_Transmit_DMA
(
&
uart
->
handle
,
buf
,
size
);
return
size
;
}
stm32_control
(
serial
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
tx_flag
);
return
size
;
}
#ifdef RT_SERIAL_USING_DMA
static
void
dma_recv_isr
(
struct
rt_serial_device
*
serial
,
rt_uint8_t
isr_flag
)
{
struct
stm32_uart
*
uart
;
rt_base_t
level
;
rt_uint16_t
recv_len
=
0
;
RT_ASSERT
(
serial
!=
RT_NULL
);
uart
=
rt_container_of
(
serial
,
struct
stm32_uart
,
serial
);
struct
rt_serial_rx_fifo
*
rx_fifo
;
rx_fifo
=
(
struct
rt_serial_rx_fifo
*
)
serial
->
serial_rx
;
RT_ASSERT
(
rx_fifo
!=
RT_NULL
);
level
=
rt_hw_interrupt_disable
();
rt_uint16_t
index
=
__HAL_DMA_GET_COUNTER
(
&
(
uart
->
dma_rx
.
handle
));
switch
(
isr_flag
)
{
case
UART_RX_DMA_IT_TC_FLAG
:
if
(
index
>=
uart
->
dma_rx
.
remaining_cnt
)
recv_len
=
serial
->
config
.
rx_bufsz
+
uart
->
dma_rx
.
remaining_cnt
-
index
;
break
;
case
UART_RX_DMA_IT_HT_FLAG
:
case
UART_RX_DMA_IT_IDLE_FLAG
:
if
(
index
<
uart
->
dma_rx
.
remaining_cnt
)
recv_len
=
uart
->
dma_rx
.
remaining_cnt
-
index
;
break
;
default:
break
;
}
uart
->
dma_rx
.
remaining_cnt
=
index
;
rt_serial_update_write_index
(
&
(
rx_fifo
->
rb
),
recv_len
);
rt_hw_interrupt_enable
(
level
);
}
#endif
/* RT_SERIAL_USING_DMA */
/**
* Uart common interrupt process. This need add to uart ISR.
*
* @param serial serial device
*/
static
void
uart_isr
(
struct
rt_serial_device
*
serial
)
{
struct
stm32_uart
*
uart
;
RT_ASSERT
(
serial
!=
RT_NULL
);
uart
=
rt_container_of
(
serial
,
struct
stm32_uart
,
serial
);
/* If the Read data register is not empty and the RXNE interrupt is enabled (RDR) */
if
((
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_RXNE
)
!=
RESET
)
&&
(
__HAL_UART_GET_IT_SOURCE
(
&
(
uart
->
handle
),
UART_IT_RXNE
)
!=
RESET
))
{
struct
rt_serial_rx_fifo
*
rx_fifo
;
rx_fifo
=
(
struct
rt_serial_rx_fifo
*
)
serial
->
serial_rx
;
RT_ASSERT
(
rx_fifo
!=
RT_NULL
);
rt_ringbuffer_putchar
(
&
(
rx_fifo
->
rb
),
UART_GET_RDR
(
&
uart
->
handle
));
rt_hw_serial_isr
(
serial
,
RT_SERIAL_EVENT_RX_IND
);
}
/* If the Transmit data register is empty and the TXE interrupt enable is enabled (TDR)*/
else
if
((
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_TXE
)
!=
RESET
)
&&
(
__HAL_UART_GET_IT_SOURCE
(
&
(
uart
->
handle
),
UART_IT_TXE
))
!=
RESET
)
{
struct
rt_serial_tx_fifo
*
tx_fifo
;
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
serial
->
serial_tx
;
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
rt_uint8_t
put_char
=
0
;
if
(
rt_ringbuffer_getchar
(
&
(
tx_fifo
->
rb
),
&
put_char
))
{
UART_SET_TDR
(
&
uart
->
handle
,
put_char
);
}
else
{
__HAL_UART_DISABLE_IT
(
&
(
uart
->
handle
),
UART_IT_TXE
);
__HAL_UART_ENABLE_IT
(
&
(
uart
->
handle
),
UART_IT_TC
);
}
}
else
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_TC
)
&&
(
__HAL_UART_GET_IT_SOURCE
(
&
(
uart
->
handle
),
UART_IT_TC
)
!=
RESET
))
{
if
(
uart
->
uart_dma_flag
&
RT_DEVICE_FLAG_DMA_TX
)
{
/* The HAL_UART_TxCpltCallback will be triggered */
HAL_UART_IRQHandler
(
&
(
uart
->
handle
));
}
else
{
/* Transmission complete interrupt disable ( CR1 Register) */
__HAL_UART_DISABLE_IT
(
&
(
uart
->
handle
),
UART_IT_TC
);
rt_hw_serial_isr
(
serial
,
RT_SERIAL_EVENT_TX_DONE
);
}
/* Clear Transmission complete interrupt flag ( ISR Register ) */
UART_INSTANCE_CLEAR_FUNCTION
(
&
(
uart
->
handle
),
UART_FLAG_TC
);
}
#ifdef RT_SERIAL_USING_DMA
else
if
((
uart
->
uart_dma_flag
)
&&
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_IDLE
)
!=
RESET
)
&&
(
__HAL_UART_GET_IT_SOURCE
(
&
(
uart
->
handle
),
UART_IT_IDLE
)
!=
RESET
))
{
dma_recv_isr
(
serial
,
UART_RX_DMA_IT_IDLE_FLAG
);
rt_hw_serial_isr
(
serial
,
RT_SERIAL_EVENT_RX_IND
);
__HAL_UART_CLEAR_IDLEFLAG
(
&
uart
->
handle
);
}
#endif
else
{
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_ORE
)
!=
RESET
)
{
__HAL_UART_CLEAR_OREFLAG
(
&
uart
->
handle
);
}
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_NE
)
!=
RESET
)
{
__HAL_UART_CLEAR_NEFLAG
(
&
uart
->
handle
);
}
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_FE
)
!=
RESET
)
{
__HAL_UART_CLEAR_FEFLAG
(
&
uart
->
handle
);
}
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_PE
)
!=
RESET
)
{
__HAL_UART_CLEAR_PEFLAG
(
&
uart
->
handle
);
}
#if !defined(SOC_SERIES_STM32L4) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32F7) && !defined(SOC_SERIES_STM32F0) \
&& !defined(SOC_SERIES_STM32L0) && !defined(SOC_SERIES_STM32G0) && !defined(SOC_SERIES_STM32H7) \
&& !defined(SOC_SERIES_STM32G4) && !defined(SOC_SERIES_STM32MP1) && !defined(SOC_SERIES_STM32WB)
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_LBD
)
!=
RESET
)
{
UART_INSTANCE_CLEAR_FUNCTION
(
&
(
uart
->
handle
),
UART_FLAG_LBD
);
}
#endif
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_CTS
)
!=
RESET
)
{
UART_INSTANCE_CLEAR_FUNCTION
(
&
(
uart
->
handle
),
UART_FLAG_CTS
);
}
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_TXE
)
!=
RESET
)
{
UART_INSTANCE_CLEAR_FUNCTION
(
&
(
uart
->
handle
),
UART_FLAG_TXE
);
}
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_TC
)
!=
RESET
)
{
UART_INSTANCE_CLEAR_FUNCTION
(
&
(
uart
->
handle
),
UART_FLAG_TC
);
}
if
(
__HAL_UART_GET_FLAG
(
&
(
uart
->
handle
),
UART_FLAG_RXNE
)
!=
RESET
)
{
UART_INSTANCE_CLEAR_FUNCTION
(
&
(
uart
->
handle
),
UART_FLAG_RXNE
);
}
}
}
#if defined(BSP_USING_UART1)
void
USART1_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
UART1_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_RX_USING_DMA)
void
UART1_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART1_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_RX_USING_DMA) */
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_TX_USING_DMA)
void
UART1_DMA_TX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART1_INDEX
].
dma_tx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART1_TX_USING_DMA) */
#endif
/* BSP_USING_UART1 */
#if defined(BSP_USING_UART2)
void
USART2_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
UART2_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_RX_USING_DMA)
void
UART2_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART2_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_RX_USING_DMA) */
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_TX_USING_DMA)
void
UART2_DMA_TX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART2_INDEX
].
dma_tx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART2_TX_USING_DMA) */
#endif
/* BSP_USING_UART2 */
#if defined(BSP_USING_UART3)
void
USART3_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
UART3_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART3_RX_USING_DMA)
void
UART3_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART3_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(BSP_UART_USING_DMA_RX) && defined(BSP_UART3_RX_USING_DMA) */
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART3_TX_USING_DMA)
void
UART3_DMA_TX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART3_INDEX
].
dma_tx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(BSP_UART_USING_DMA_TX) && defined(BSP_UART3_TX_USING_DMA) */
#endif
/* BSP_USING_UART3*/
#if defined(BSP_USING_UART4)
void
UART4_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
UART4_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART4_RX_USING_DMA)
void
UART4_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART4_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(BSP_UART_USING_DMA_RX) && defined(BSP_UART4_RX_USING_DMA) */
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART4_TX_USING_DMA)
void
UART4_DMA_TX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART4_INDEX
].
dma_tx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(BSP_UART_USING_DMA_TX) && defined(BSP_UART4_TX_USING_DMA) */
#endif
/* BSP_USING_UART4*/
#if defined(BSP_USING_UART5)
void
UART5_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
UART5_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART5_RX_USING_DMA)
void
UART5_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART5_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART5_RX_USING_DMA) */
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART5_TX_USING_DMA)
void
UART5_DMA_TX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART5_INDEX
].
dma_tx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART5_TX_USING_DMA) */
#endif
/* BSP_USING_UART5*/
#if defined(BSP_USING_UART6)
void
USART6_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
UART6_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART6_RX_USING_DMA)
void
UART6_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART6_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART6_RX_USING_DMA) */
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART6_TX_USING_DMA)
void
UART6_DMA_TX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART6_INDEX
].
dma_tx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART6_TX_USING_DMA) */
#endif
/* BSP_USING_UART6*/
#if defined(BSP_USING_UART7)
void
UART7_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
UART7_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART7_RX_USING_DMA)
void
UART7_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART7_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART7_RX_USING_DMA) */
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART7_TX_USING_DMA)
void
UART7_DMA_TX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART7_INDEX
].
dma_tx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART7_TX_USING_DMA) */
#endif
/* BSP_USING_UART7*/
#if defined(BSP_USING_UART8)
void
UART8_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
UART8_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART8_RX_USING_DMA)
void
UART8_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART8_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART8_RX_USING_DMA) */
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART8_TX_USING_DMA)
void
UART8_DMA_TX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
UART8_INDEX
].
dma_tx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART8_TX_USING_DMA) */
#endif
/* BSP_USING_UART8*/
#if defined(BSP_USING_LPUART1)
void
LPUART1_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
uart_isr
(
&
(
uart_obj
[
LPUART1_INDEX
].
serial
));
/* leave interrupt */
rt_interrupt_leave
();
}
#if defined(RT_SERIAL_USING_DMA) && defined(BSP_LPUART1_RX_USING_DMA)
void
LPUART1_DMA_RX_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
HAL_DMA_IRQHandler
(
&
uart_obj
[
LPUART1_INDEX
].
dma_rx
.
handle
);
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
/* defined(RT_SERIAL_USING_DMA) && defined(BSP_LPUART1_RX_USING_DMA) */
#endif
/* BSP_USING_LPUART1*/
static
void
stm32_uart_get_config
(
void
)
{
struct
serial_configure
config
=
RT_SERIAL_CONFIG_DEFAULT
;
#ifdef BSP_USING_UART1
uart_obj
[
UART1_INDEX
].
serial
.
config
=
config
;
uart_obj
[
UART1_INDEX
].
uart_dma_flag
=
0
;
uart_obj
[
UART1_INDEX
].
serial
.
config
.
rx_bufsz
=
BSP_UART1_RX_BUFSIZE
;
uart_obj
[
UART1_INDEX
].
serial
.
config
.
tx_bufsz
=
BSP_UART1_TX_BUFSIZE
;
#ifdef BSP_UART1_RX_USING_DMA
uart_obj
[
UART1_INDEX
].
uart_dma_flag
|=
RT_DEVICE_FLAG_DMA_RX
;
static
struct
dma_config
uart1_dma_rx
=
UART1_DMA_RX_CONFIG
;
uart_config
[
UART1_INDEX
].
dma_rx
=
&
uart1_dma_rx
;
#endif
#ifdef BSP_UART1_TX_USING_DMA
uart_obj
[
UART1_INDEX
].
uart_dma_flag
|=
RT_DEVICE_FLAG_DMA_TX
;
static
struct
dma_config
uart1_dma_tx
=
UART1_DMA_TX_CONFIG
;
uart_config
[
UART1_INDEX
].
dma_tx
=
&
uart1_dma_tx
;
#endif
#endif
#ifdef BSP_USING_UART2
uart_obj
[
UART2_INDEX
].
serial
.
config
=
config
;
uart_obj
[
UART2_INDEX
].
uart_dma_flag
=
0
;
uart_obj
[
UART2_INDEX
].
serial
.
config
.
rx_bufsz
=
BSP_UART2_RX_BUFSIZE
;
uart_obj
[
UART2_INDEX
].
serial
.
config
.
tx_bufsz
=
BSP_UART2_TX_BUFSIZE
;
#ifdef BSP_UART2_RX_USING_DMA
uart_obj
[
UART2_INDEX
].
uart_dma_flag
|=
RT_DEVICE_FLAG_DMA_RX
;
static
struct
dma_config
uart2_dma_rx
=
UART2_DMA_RX_CONFIG
;
uart_config
[
UART2_INDEX
].
dma_rx
=
&
uart2_dma_rx
;
#endif
#ifdef BSP_UART2_TX_USING_DMA
uart_obj
[
UART2_INDEX
].
uart_dma_flag
|=
RT_DEVICE_FLAG_DMA_TX
;
static
struct
dma_config
uart2_dma_tx
=
UART2_DMA_TX_CONFIG
;
uart_config
[
UART2_INDEX
].
dma_tx
=
&
uart2_dma_tx
;
#endif
#endif
#ifdef BSP_USING_UART3
uart_obj
[
UART3_INDEX
].
serial
.
config
=
config
;
uart_obj
[
UART3_INDEX
].
uart_dma_flag
=
0
;
uart_obj
[
UART3_INDEX
].
serial
.
config
.
rx_bufsz
=
BSP_UART3_RX_BUFSIZE
;
uart_obj
[
UART3_INDEX
].
serial
.
config
.
tx_bufsz
=
BSP_UART3_TX_BUFSIZE
;
#ifdef BSP_UART3_RX_USING_DMA
uart_obj
[
UART3_INDEX
].
uart_dma_flag
|=
RT_DEVICE_FLAG_DMA_RX
;
static
struct
dma_config
uart3_dma_rx
=
UART3_DMA_RX_CONFIG
;
uart_config
[
UART3_INDEX
].
dma_rx
=
&
uart3_dma_rx
;
#endif
#ifdef BSP_UART3_TX_USING_DMA
uart_obj
[
UART3_INDEX
].
uart_dma_flag
|=
RT_DEVICE_FLAG_DMA_TX
;
static
struct
dma_config
uart3_dma_tx
=
UART3_DMA_TX_CONFIG
;
uart_config
[
UART3_INDEX
].
dma_tx
=
&
uart3_dma_tx
;
#endif
#endif
#ifdef BSP_USING_UART4
uart_obj
[
UART4_INDEX
].
serial
.
config
=
config
;
uart_obj
[
UART4_INDEX
].
uart_dma_flag
=
0
;
uart_obj
[
UART4_INDEX
].
serial
.
config
.
rx_bufsz
=
BSP_UART4_RX_BUFSIZE
;
uart_obj
[
UART4_INDEX
].
serial
.
config
.
tx_bufsz
=
BSP_UART4_TX_BUFSIZE
;
#ifdef BSP_UART4_RX_USING_DMA
uart_obj
[
UART4_INDEX
].
uart_dma_flag
|=
RT_DEVICE_FLAG_DMA_RX
;
static
struct
dma_config
uart4_dma_rx
=
UART4_DMA_RX_CONFIG
;
uart_config
[
UART4_INDEX
].
dma_rx
=
&
uart4_dma_rx
;
#endif
#ifdef BSP_UART4_TX_USING_DMA
uart_obj
[
UART4_INDEX
].
uart_dma_flag
|=
RT_DEVICE_FLAG_DMA_TX
;
static
struct
dma_config
uart4_dma_tx
=
UART4_DMA_TX_CONFIG
;
uart_config
[
UART4_INDEX
].
dma_tx
=
&
uart4_dma_tx
;
#endif
#endif
}
#ifdef RT_SERIAL_USING_DMA
static
void
stm32_dma_config
(
struct
rt_serial_device
*
serial
,
rt_ubase_t
flag
)
{
struct
rt_serial_rx_fifo
*
rx_fifo
;
DMA_HandleTypeDef
*
DMA_Handle
;
struct
dma_config
*
dma_config
;
struct
stm32_uart
*
uart
;
RT_ASSERT
(
serial
!=
RT_NULL
);
uart
=
rt_container_of
(
serial
,
struct
stm32_uart
,
serial
);
if
(
RT_DEVICE_FLAG_DMA_RX
==
flag
)
{
DMA_Handle
=
&
uart
->
dma_rx
.
handle
;
dma_config
=
uart
->
config
->
dma_rx
;
}
else
if
(
RT_DEVICE_FLAG_DMA_TX
==
flag
)
{
DMA_Handle
=
&
uart
->
dma_tx
.
handle
;
dma_config
=
uart
->
config
->
dma_tx
;
}
LOG_D
(
"%s dma config start"
,
uart
->
config
->
name
);
{
rt_uint32_t
tmpreg
=
0x00U
;
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) \
|| defined(SOC_SERIES_STM32L0)
/* enable DMA clock && Delay after an RCC peripheral clock enabling*/
SET_BIT
(
RCC
->
AHBENR
,
dma_config
->
dma_rcc
);
tmpreg
=
READ_BIT
(
RCC
->
AHBENR
,
dma_config
->
dma_rcc
);
#elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) \
|| defined(SOC_SERIES_STM32G4)|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32WB)
/* enable DMA clock && Delay after an RCC peripheral clock enabling*/
SET_BIT
(
RCC
->
AHB1ENR
,
dma_config
->
dma_rcc
);
tmpreg
=
READ_BIT
(
RCC
->
AHB1ENR
,
dma_config
->
dma_rcc
);
#elif defined(SOC_SERIES_STM32MP1)
/* enable DMA clock && Delay after an RCC peripheral clock enabling*/
SET_BIT
(
RCC
->
MP_AHB2ENSETR
,
dma_config
->
dma_rcc
);
tmpreg
=
READ_BIT
(
RCC
->
MP_AHB2ENSETR
,
dma_config
->
dma_rcc
);
#endif
#if defined(DMAMUX1) && (defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB))
/* enable DMAMUX clock for L4+ and G4 */
__HAL_RCC_DMAMUX1_CLK_ENABLE
();
#elif defined(SOC_SERIES_STM32MP1)
__HAL_RCC_DMAMUX_CLK_ENABLE
();
#endif
UNUSED
(
tmpreg
);
/* To avoid compiler warnings */
}
if
(
RT_DEVICE_FLAG_DMA_RX
==
flag
)
{
__HAL_LINKDMA
(
&
(
uart
->
handle
),
hdmarx
,
uart
->
dma_rx
.
handle
);
}
else
if
(
RT_DEVICE_FLAG_DMA_TX
==
flag
)
{
__HAL_LINKDMA
(
&
(
uart
->
handle
),
hdmatx
,
uart
->
dma_tx
.
handle
);
}
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0)
DMA_Handle
->
Instance
=
dma_config
->
Instance
;
#elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
DMA_Handle
->
Instance
=
dma_config
->
Instance
;
DMA_Handle
->
Init
.
Channel
=
dma_config
->
channel
;
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)\
|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
DMA_Handle
->
Instance
=
dma_config
->
Instance
;
DMA_Handle
->
Init
.
Request
=
dma_config
->
request
;
#endif
DMA_Handle
->
Init
.
PeriphInc
=
DMA_PINC_DISABLE
;
DMA_Handle
->
Init
.
MemInc
=
DMA_MINC_ENABLE
;
DMA_Handle
->
Init
.
PeriphDataAlignment
=
DMA_PDATAALIGN_BYTE
;
DMA_Handle
->
Init
.
MemDataAlignment
=
DMA_MDATAALIGN_BYTE
;
if
(
RT_DEVICE_FLAG_DMA_RX
==
flag
)
{
DMA_Handle
->
Init
.
Direction
=
DMA_PERIPH_TO_MEMORY
;
DMA_Handle
->
Init
.
Mode
=
DMA_CIRCULAR
;
}
else
if
(
RT_DEVICE_FLAG_DMA_TX
==
flag
)
{
DMA_Handle
->
Init
.
Direction
=
DMA_MEMORY_TO_PERIPH
;
DMA_Handle
->
Init
.
Mode
=
DMA_NORMAL
;
}
DMA_Handle
->
Init
.
Priority
=
DMA_PRIORITY_MEDIUM
;
#if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
DMA_Handle
->
Init
.
FIFOMode
=
DMA_FIFOMODE_DISABLE
;
#endif
if
(
HAL_DMA_DeInit
(
DMA_Handle
)
!=
HAL_OK
)
{
RT_ASSERT
(
0
);
}
if
(
HAL_DMA_Init
(
DMA_Handle
)
!=
HAL_OK
)
{
RT_ASSERT
(
0
);
}
/* enable interrupt */
if
(
flag
==
RT_DEVICE_FLAG_DMA_RX
)
{
rx_fifo
=
(
struct
rt_serial_rx_fifo
*
)
serial
->
serial_rx
;
RT_ASSERT
(
rx_fifo
!=
RT_NULL
);
/* Start DMA transfer */
if
(
HAL_UART_Receive_DMA
(
&
(
uart
->
handle
),
rx_fifo
->
buffer
,
serial
->
config
.
rx_bufsz
)
!=
HAL_OK
)
{
/* Transfer error in reception process */
RT_ASSERT
(
0
);
}
CLEAR_BIT
(
uart
->
handle
.
Instance
->
CR3
,
USART_CR3_EIE
);
__HAL_UART_ENABLE_IT
(
&
(
uart
->
handle
),
UART_IT_IDLE
);
}
/* DMA irq should set in DMA TX mode, or HAL_UART_TxCpltCallback function will not be called */
HAL_NVIC_SetPriority
(
dma_config
->
dma_irq
,
0
,
0
);
HAL_NVIC_EnableIRQ
(
dma_config
->
dma_irq
);
HAL_NVIC_SetPriority
(
uart
->
config
->
irq_type
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
uart
->
config
->
irq_type
);
LOG_D
(
"%s dma %s instance: %x"
,
uart
->
config
->
name
,
flag
==
RT_DEVICE_FLAG_DMA_RX
?
"RX"
:
"TX"
,
DMA_Handle
->
Instance
);
LOG_D
(
"%s dma config done"
,
uart
->
config
->
name
);
}
/**
* @brief UART error callbacks
* @param huart: UART handle
* @note This example shows a simple way to report transfer error, and you can
* add your own implementation.
* @retval None
*/
void
HAL_UART_ErrorCallback
(
UART_HandleTypeDef
*
huart
)
{
RT_ASSERT
(
huart
!=
NULL
);
struct
stm32_uart
*
uart
=
(
struct
stm32_uart
*
)
huart
;
LOG_D
(
"%s: %s %d
\n
"
,
__FUNCTION__
,
uart
->
config
->
name
,
huart
->
ErrorCode
);
UNUSED
(
uart
);
}
/**
* @brief Rx Transfer completed callback
* @param huart: UART handle
* @note This example shows a simple way to report end of DMA Rx transfer, and
* you can add your own implementation.
* @retval None
*/
void
HAL_UART_RxCpltCallback
(
UART_HandleTypeDef
*
huart
)
{
struct
stm32_uart
*
uart
;
RT_ASSERT
(
huart
!=
NULL
);
uart
=
(
struct
stm32_uart
*
)
huart
;
dma_recv_isr
(
&
uart
->
serial
,
UART_RX_DMA_IT_TC_FLAG
);
rt_hw_serial_isr
(
&
uart
->
serial
,
RT_SERIAL_EVENT_RX_DMADONE
);
}
/**
* @brief Rx Half transfer completed callback
* @param huart: UART handle
* @note This example shows a simple way to report end of DMA Rx Half transfer,
* and you can add your own implementation.
* @retval None
*/
void
HAL_UART_RxHalfCpltCallback
(
UART_HandleTypeDef
*
huart
)
{
struct
stm32_uart
*
uart
;
RT_ASSERT
(
huart
!=
NULL
);
uart
=
(
struct
stm32_uart
*
)
huart
;
dma_recv_isr
(
&
uart
->
serial
,
UART_RX_DMA_IT_HT_FLAG
);
rt_hw_serial_isr
(
&
uart
->
serial
,
RT_SERIAL_EVENT_RX_DMADONE
);
}
/**
* @brief HAL_UART_TxCpltCallback
* @param huart: UART handle
* @note This callback can be called by two functions, first in UART_EndTransmit_IT when
* UART Tx complete and second in UART_DMATransmitCplt function in DMA Circular mode.
* @retval None
*/
void
HAL_UART_TxCpltCallback
(
UART_HandleTypeDef
*
huart
)
{
struct
stm32_uart
*
uart
;
struct
rt_serial_device
*
serial
;
rt_size_t
trans_total_index
;
rt_base_t
level
;
RT_ASSERT
(
huart
!=
NULL
);
uart
=
(
struct
stm32_uart
*
)
huart
;
serial
=
&
uart
->
serial
;
RT_ASSERT
(
serial
!=
RT_NULL
);
level
=
rt_hw_interrupt_disable
();
trans_total_index
=
__HAL_DMA_GET_COUNTER
(
&
(
uart
->
dma_tx
.
handle
));
rt_hw_interrupt_enable
(
level
);
if
(
trans_total_index
)
return
;
rt_hw_serial_isr
(
serial
,
RT_SERIAL_EVENT_TX_DMADONE
);
}
#endif
/* RT_SERIAL_USING_DMA */
static
const
struct
rt_uart_ops
stm32_uart_ops
=
{
.
configure
=
stm32_configure
,
.
control
=
stm32_control
,
.
putc
=
stm32_putc
,
.
getc
=
stm32_getc
,
.
transmit
=
stm32_transmit
};
int
rt_hw_usart_init
(
void
)
{
rt_err_t
result
=
0
;
rt_size_t
obj_num
=
sizeof
(
uart_obj
)
/
sizeof
(
struct
stm32_uart
);
stm32_uart_get_config
();
for
(
int
i
=
0
;
i
<
obj_num
;
i
++
)
{
/* init UART object */
uart_obj
[
i
].
config
=
&
uart_config
[
i
];
uart_obj
[
i
].
serial
.
ops
=
&
stm32_uart_ops
;
/* register UART device */
result
=
rt_hw_serial_register
(
&
uart_obj
[
i
].
serial
,
uart_obj
[
i
].
config
->
name
,
RT_DEVICE_FLAG_RDWR
,
NULL
);
RT_ASSERT
(
result
==
RT_EOK
);
}
return
result
;
}
#endif
/* RT_USING_SERIAL_V2 */
bsp/stm32/libraries/HAL_Drivers/drv_usart_v2.h
0 → 100644
浏览文件 @
d94be14d
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-01 KyleChan first version
*/
#ifndef __DRV_USART_V2_H__
#define __DRV_USART_V2_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#include <drv_common.h>
#include <drv_dma.h>
#include <drv_config.h>
int
rt_hw_usart_init
(
void
);
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) \
|| defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) \
|| defined(SOC_SERIES_STM32G4)
#define UART_SET_TDR(__HANDLE__, __DATA__) ((__HANDLE__)->Instance->TDR = (__DATA__))
#define UART_GET_RDR(__HANDLE__) ((__HANDLE__)->Instance->RDR & 0xFF)
#else
#define UART_SET_TDR(__HANDLE__, __DATA__) ((__HANDLE__)->Instance->DR = (__DATA__))
#define UART_GET_RDR(__HANDLE__) (return (__HANDLE__)->Instance->DR & 0xFF))
#endif
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F2) \
|| defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) \
|| defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)
#define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_FLAG
#elif defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) \
|| defined(SOC_SERIES_STM32MP1)
#define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_IT
#endif
#define UART_RX_DMA_IT_IDLE_FLAG 0x00
#define UART_RX_DMA_IT_HT_FLAG 0x01
#define UART_RX_DMA_IT_TC_FLAG 0x02
/* stm32 config class */
struct
stm32_uart_config
{
const
char
*
name
;
USART_TypeDef
*
Instance
;
IRQn_Type
irq_type
;
#ifdef RT_SERIAL_USING_DMA
struct
dma_config
*
dma_rx
;
struct
dma_config
*
dma_tx
;
#endif
};
/* stm32 uart dirver class */
struct
stm32_uart
{
UART_HandleTypeDef
handle
;
struct
stm32_uart_config
*
config
;
#ifdef RT_SERIAL_USING_DMA
struct
{
DMA_HandleTypeDef
handle
;
rt_size_t
remaining_cnt
;
}
dma_rx
;
struct
{
DMA_HandleTypeDef
handle
;
}
dma_tx
;
#endif
rt_uint16_t
uart_dma_flag
;
struct
rt_serial_device
serial
;
};
#endif
/* __DRV_USART_H__ */
bsp/stm32/stm32l475-atk-pandora/.config
浏览文件 @
d94be14d
...
...
@@ -21,6 +21,12 @@ CONFIG_RT_USING_IDLE_HOOK=y
CONFIG_RT_IDLE_HOOK_LIST_SIZE
=
4
CONFIG_IDLE_THREAD_STACK_SIZE
=
256
# CONFIG_RT_USING_TIMER_SOFT is not set
#
# kservice optimization
#
# CONFIG_RT_KSERVICE_USING_STDLIB is not set
# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
CONFIG_RT_DEBUG
=
y
CONFIG_RT_DEBUG_COLOR
=
y
# CONFIG_RT_DEBUG_INIT_CONFIG is not set
...
...
@@ -52,6 +58,7 @@ CONFIG_RT_USING_MEMPOOL=y
# CONFIG_RT_USING_NOHEAP is not set
CONFIG_RT_USING_SMALL_MEM
=
y
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_USERHEAP is not set
# CONFIG_RT_USING_MEMTRACE is not set
CONFIG_RT_USING_HEAP
=
y
...
...
@@ -64,7 +71,7 @@ CONFIG_RT_USING_DEVICE=y
CONFIG_RT_USING_CONSOLE
=
y
CONFIG_RT_CONSOLEBUF_SIZE
=
256
CONFIG_RT_CONSOLE_DEVICE_NAME
=
"uart1"
CONFIG_RT_VER_NUM
=
0
x4000
2
CONFIG_RT_VER_NUM
=
0
x4000
4
CONFIG_ARCH_ARM
=
y
CONFIG_RT_USING_CPU_FFS
=
y
CONFIG_ARCH_ARM_CORTEX_M
=
y
...
...
@@ -115,14 +122,17 @@ CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_PIPE_BUFSZ
=
512
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
CONFIG_RT_USING_SERIAL
=
y
# CONFIG_RT_USING_SERIAL_V1 is not set
CONFIG_RT_USING_SERIAL_V2
=
y
CONFIG_RT_SERIAL_USING_DMA
=
y
CONFIG_RT_SERIAL_RB_BUFSZ
=
64
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
# CONFIG_RT_USING_PHY is not set
CONFIG_RT_USING_PIN
=
y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_DAC is not set
# CONFIG_RT_USING_PWM is not set
# CONFIG_RT_USING_MTD_NOR is not set
# CONFIG_RT_USING_MTD_NAND is not set
...
...
@@ -135,7 +145,7 @@ CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_SENSOR is not set
# CONFIG_RT_USING_TOUCH is not set
# CONFIG_RT_USING_HWCRYPTO is not set
# CONFIG_RT_USING_ENCODER is not set
# CONFIG_RT_USING_
PULSE_
ENCODER is not set
# CONFIG_RT_USING_INPUT_CAPTURE is not set
# CONFIG_RT_USING_WIFI is not set
...
...
@@ -150,7 +160,7 @@ CONFIG_RT_USING_PIN=y
#
# CONFIG_RT_USING_LIBC is not set
# CONFIG_RT_USING_PTHREADS is not set
CONFIG_RT_LIBC_USING_TIME
=
y
# CONFIG_RT_LIBC_USING_TIME is not set
#
# Network
...
...
@@ -187,8 +197,28 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_RT_USING_RYM is not set
# CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set
CONFIG_RT_USING_RT_LINK
=
y
CONFIG_RT_LINK_USING_SF_CRC
=
y
# CONFIG_RT_LINK_USING_HW_CRC is not set
#
# rt-link hardware device configuration
#
CONFIG_RT_LINK_HW_DEVICE_NAME
=
"uart2"
CONFIG_RT_LINK_USING_UART
=
y
#
# rt link debug option
#
# CONFIG_USING_RT_LINK_DEBUG is not set
# CONFIG_USING_RT_LINK_HW_DEBUG is not set
# CONFIG_RT_USING_LWP is not set
#
# RT-Thread Utestcases
#
# CONFIG_RT_USING_UTESTCASES is not set
#
# RT-Thread online packages
#
...
...
@@ -196,10 +226,15 @@ CONFIG_RT_LIBC_USING_TIME=y
#
# IoT - internet of things
#
# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
# CONFIG_PKG_USING_PAHOMQTT is not set
# CONFIG_PKG_USING_UMQTT is not set
# CONFIG_PKG_USING_WEBCLIENT is not set
# CONFIG_PKG_USING_WEBNET is not set
# CONFIG_PKG_USING_MONGOOSE is not set
# CONFIG_PKG_USING_MYMQTT is not set
# CONFIG_PKG_USING_KAWAII_MQTT is not set
# CONFIG_PKG_USING_BC28_MQTT is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_JSMN is not set
...
...
@@ -226,6 +261,8 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
# CONFIG_PKG_USING_CMUX is not set
# CONFIG_PKG_USING_PPP_DEVICE is not set
# CONFIG_PKG_USING_AT_DEVICE is not set
# CONFIG_PKG_USING_ATSRV_SOCKET is not set
# CONFIG_PKG_USING_WIZNET is not set
...
...
@@ -237,7 +274,10 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
# CONFIG_PKG_USING_JIOT-C-SDK is not set
# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
# CONFIG_PKG_USING_JOYLINK is not set
# CONFIG_PKG_USING_NIMBLE is not set
# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
# CONFIG_PKG_USING_IPMSG is not set
...
...
@@ -246,8 +286,23 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_LIBRWS is not set
# CONFIG_PKG_USING_TCPSERVER is not set
# CONFIG_PKG_USING_PROTOBUF_C is not set
# CONFIG_PKG_USING_ONNX_PARSER is not set
# CONFIG_PKG_USING_ONNX_BACKEND is not set
# CONFIG_PKG_USING_DLT645 is not set
# CONFIG_PKG_USING_QXWZ is not set
# CONFIG_PKG_USING_SMTP_CLIENT is not set
# CONFIG_PKG_USING_ABUP_FOTA is not set
# CONFIG_PKG_USING_LIBCURL2RTT is not set
# CONFIG_PKG_USING_CAPNP is not set
# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
# CONFIG_PKG_USING_AGILE_TELNET is not set
# CONFIG_PKG_USING_NMEALIB is not set
# CONFIG_PKG_USING_AGILE_JSMN is not set
# CONFIG_PKG_USING_PDULIB is not set
# CONFIG_PKG_USING_BTSTACK is not set
# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
# CONFIG_PKG_USING_MAVLINK is not set
# CONFIG_PKG_USING_RAPIDJSON is not set
# CONFIG_PKG_USING_BSAL is not set
#
# security packages
...
...
@@ -255,6 +310,8 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_libsodium is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
# CONFIG_PKG_USING_TFM is not set
# CONFIG_PKG_USING_YD_CRYPTO is not set
#
# language packages
...
...
@@ -270,6 +327,10 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_MUPDF is not set
# CONFIG_PKG_USING_STEMWIN is not set
# CONFIG_PKG_USING_WAVPLAYER is not set
# CONFIG_PKG_USING_TJPGD is not set
# CONFIG_PKG_USING_HELIX is not set
# CONFIG_PKG_USING_AZUREGUIX is not set
# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
#
# tools packages
...
...
@@ -281,7 +342,31 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_QRCODE is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
# CONFIG_PKG_USING_ULOG_FILE is not set
# CONFIG_PKG_USING_LOGMGR is not set
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
# CONFIG_PKG_USING_DHRYSTONE is not set
# CONFIG_PKG_USING_MEMORYPERF is not set
# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
# CONFIG_PKG_USING_BS8116A is not set
# CONFIG_PKG_USING_GPS_RMC is not set
# CONFIG_PKG_USING_URLENCODE is not set
# CONFIG_PKG_USING_UMCN is not set
# CONFIG_PKG_USING_LWRB2RTT is not set
# CONFIG_PKG_USING_CPU_USAGE is not set
# CONFIG_PKG_USING_GBK2UTF8 is not set
# CONFIG_PKG_USING_VCONSOLE is not set
# CONFIG_PKG_USING_KDB is not set
# CONFIG_PKG_USING_WAMR is not set
# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
# CONFIG_PKG_USING_LWLOG is not set
# CONFIG_PKG_USING_ANV_TRACE is not set
# CONFIG_PKG_USING_ANV_MEMLEAK is not set
# CONFIG_PKG_USING_ANV_TESTSUIT is not set
# CONFIG_PKG_USING_ANV_BENCH is not set
#
# system packages
...
...
@@ -293,14 +378,43 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_LWEXT4 is not set
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_FAL is not set
# CONFIG_PKG_USING_FLASHDB is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_CMSIS is not set
# CONFIG_PKG_USING_DFS_YAFFS is not set
# CONFIG_PKG_USING_LITTLEFS is not set
# CONFIG_PKG_USING_DFS_JFFS2 is not set
# CONFIG_PKG_USING_DFS_UFFS is not set
# CONFIG_PKG_USING_THREAD_POOL is not set
# CONFIG_PKG_USING_ROBOTS is not set
# CONFIG_PKG_USING_EV is not set
# CONFIG_PKG_USING_SYSWATCH is not set
# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
# CONFIG_PKG_USING_PLCCORE is not set
# CONFIG_PKG_USING_RAMDISK is not set
# CONFIG_PKG_USING_MININI is not set
# CONFIG_PKG_USING_QBOOT is not set
#
# Micrium: Micrium software products porting for RT-Thread
#
# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
# CONFIG_PKG_USING_UC_CRC is not set
# CONFIG_PKG_USING_UC_CLK is not set
# CONFIG_PKG_USING_UC_COMMON is not set
# CONFIG_PKG_USING_UC_MODBUS is not set
# CONFIG_PKG_USING_PPOOL is not set
# CONFIG_PKG_USING_OPENAMP is not set
# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
# CONFIG_PKG_USING_QFPLIB_M3 is not set
# CONFIG_PKG_USING_LPM is not set
# CONFIG_PKG_USING_TLSF is not set
#
# peripheral libraries and drivers
...
...
@@ -308,6 +422,8 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_U8G2 is not set
...
...
@@ -316,10 +432,16 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_SX12XX is not set
# CONFIG_PKG_USING_SIGNAL_LED is not set
# CONFIG_PKG_USING_LEDBLINK is not set
# CONFIG_PKG_USING_LITTLED is not set
# CONFIG_PKG_USING_LKDGUI is not set
# CONFIG_PKG_USING_NRF5X_SDK is not set
# CONFIG_PKG_USING_NRFX is not set
# CONFIG_PKG_USING_WM_LIBRARIES is not set
# CONFIG_PKG_USING_KENDRYTE_SDK is not set
# CONFIG_PKG_USING_INFRARED is not set
# CONFIG_PKG_USING_ROSSERIAL is not set
# CONFIG_PKG_USING_AGILE_BUTTON is not set
# CONFIG_PKG_USING_AGILE_LED is not set
# CONFIG_PKG_USING_AT24CXX is not set
# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
# CONFIG_PKG_USING_AD7746 is not set
...
...
@@ -327,7 +449,47 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_I2C_TOOLS is not set
# CONFIG_PKG_USING_NRF24L01 is not set
# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
# CONFIG_PKG_USING_LCD_DRIVERS is not set
# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
# CONFIG_PKG_USING_WS2812B is not set
# CONFIG_PKG_USING_EMBARC_BSP is not set
# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
# CONFIG_PKG_USING_MULTI_RTIMER is not set
# CONFIG_PKG_USING_MAX7219 is not set
# CONFIG_PKG_USING_BEEP is not set
# CONFIG_PKG_USING_EASYBLINK is not set
# CONFIG_PKG_USING_PMS_SERIES is not set
# CONFIG_PKG_USING_CAN_YMODEM is not set
# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
# CONFIG_PKG_USING_QLED is not set
# CONFIG_PKG_USING_PAJ7620 is not set
# CONFIG_PKG_USING_AGILE_CONSOLE is not set
# CONFIG_PKG_USING_LD3320 is not set
# CONFIG_PKG_USING_WK2124 is not set
# CONFIG_PKG_USING_LY68L6400 is not set
# CONFIG_PKG_USING_DM9051 is not set
# CONFIG_PKG_USING_SSD1306 is not set
# CONFIG_PKG_USING_QKEY is not set
# CONFIG_PKG_USING_RS485 is not set
# CONFIG_PKG_USING_NES is not set
# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
# CONFIG_PKG_USING_VDEVICE is not set
# CONFIG_PKG_USING_SGM706 is not set
# CONFIG_PKG_USING_RDA58XX is not set
#
# AI packages
#
# CONFIG_PKG_USING_LIBANN is not set
# CONFIG_PKG_USING_NNOM is not set
# CONFIG_PKG_USING_ONNX_BACKEND is not set
# CONFIG_PKG_USING_ONNX_PARSER is not set
# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
# CONFIG_PKG_USING_ELAPACK is not set
# CONFIG_PKG_USING_ULAPACK is not set
# CONFIG_PKG_USING_QUEST is not set
#
# miscellaneous packages
...
...
@@ -337,6 +499,7 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
# CONFIG_PKG_USING_QUICKLZ is not set
# CONFIG_PKG_USING_LZMA is not set
# CONFIG_PKG_USING_MULTIBUTTON is not set
# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
# CONFIG_PKG_USING_CANFESTIVAL is not set
...
...
@@ -345,6 +508,8 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_TINYFRAME is not set
# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
# CONFIG_PKG_USING_DIGITALCTRL is not set
# CONFIG_PKG_USING_UPACKER is not set
# CONFIG_PKG_USING_UPARAM is not set
#
# samples: kernel and components samples
...
...
@@ -355,9 +520,69 @@ CONFIG_RT_LIBC_USING_TIME=y
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
# CONFIG_PKG_USING_HELLO is not set
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_NNOM is not set
# CONFIG_PKG_USING_LIBANN is not set
# CONFIG_PKG_USING_ELAPACK is not set
# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
# CONFIG_PKG_USING_VT100 is not set
# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_CRCLIB is not set
#
# games: games run on RT-Thread console
#
# CONFIG_PKG_USING_THREES is not set
# CONFIG_PKG_USING_2048 is not set
# CONFIG_PKG_USING_SNAKE is not set
# CONFIG_PKG_USING_TETRIS is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set
# CONFIG_PKG_USING_MCURSES is not set
# CONFIG_PKG_USING_COWSAY is not set
#
# Privated Packages of RealThread
#
# CONFIG_PKG_USING_CODEC is not set
# CONFIG_PKG_USING_PLAYER is not set
# CONFIG_PKG_USING_MPLAYER is not set
# CONFIG_PKG_USING_PERSIMMON_SRC is not set
# CONFIG_PKG_USING_JS_PERSIMMON is not set
# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
#
# Network Utilities
#
# CONFIG_PKG_USING_WICED is not set
# CONFIG_PKG_USING_CLOUDSDK is not set
# CONFIG_PKG_USING_POWER_MANAGER is not set
# CONFIG_PKG_USING_RT_OTA is not set
# CONFIG_PKG_USING_RTINSIGHT is not set
# CONFIG_PKG_USING_SMARTCONFIG is not set
# CONFIG_PKG_USING_RTX is not set
# CONFIG_RT_USING_TESTCASE is not set
# CONFIG_PKG_USING_NGHTTP2 is not set
# CONFIG_PKG_USING_AVS is not set
# CONFIG_PKG_USING_ALI_LINKKIT is not set
# CONFIG_PKG_USING_STS is not set
# CONFIG_PKG_USING_DLMS is not set
# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
# CONFIG_PKG_USING_ZBAR is not set
# CONFIG_PKG_USING_MCF is not set
# CONFIG_PKG_USING_URPC is not set
# CONFIG_PKG_USING_DCM is not set
# CONFIG_PKG_USING_EMQ is not set
# CONFIG_PKG_USING_CFGM is not set
# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
# CONFIG_PKG_USING_SMODULE is not set
# CONFIG_PKG_USING_SNFD is not set
# CONFIG_PKG_USING_UDBD is not set
# CONFIG_PKG_USING_BENCHMARK is not set
# CONFIG_PKG_USING_UBJSON is not set
# CONFIG_PKG_USING_DATATYPE is not set
# CONFIG_PKG_USING_FASTFS is not set
# CONFIG_PKG_USING_RIL is not set
# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
# CONFIG_PKG_USING_GUI_TEST is not set
# CONFIG_PKG_USING_PMEM is not set
CONFIG_SOC_FAMILY_STM32
=
y
CONFIG_SOC_SERIES_STM32L4
=
y
...
...
@@ -370,12 +595,15 @@ CONFIG_SOC_STM32L475VE=y
# Onboard Peripheral Drivers
#
CONFIG_BSP_USING_STLINK_TO_USART
=
y
# CONFIG_BSP_USING_KEY is not set
# CONFIG_BSP_USING_QSPI_FLASH is not set
# CONFIG_BSP_USING_SPI_LCD is not set
# CONFIG_BSP_USING_SDCARD is not set
# CONFIG_BSP_USING_ICM20608 is not set
# CONFIG_BSP_USING_AHT10 is not set
# CONFIG_BSP_USING_AUDIO is not set
# CONFIG_BSP_USING_USB_AUDIO is not set
# CONFIG_BSP_USING_WIFI is not set
#
# On-chip Peripheral Drivers
...
...
@@ -384,7 +612,14 @@ CONFIG_BSP_USING_GPIO=y
CONFIG_BSP_USING_UART
=
y
CONFIG_BSP_USING_UART1
=
y
# CONFIG_BSP_UART1_RX_USING_DMA is not set
# CONFIG_BSP_USING_UART2 is not set
# CONFIG_BSP_UART1_TX_USING_DMA is not set
CONFIG_BSP_UART1_RX_BUFSIZE
=
256
CONFIG_BSP_UART1_TX_BUFSIZE
=
0
CONFIG_BSP_USING_UART2
=
y
CONFIG_BSP_UART2_RX_USING_DMA
=
y
CONFIG_BSP_UART2_TX_USING_DMA
=
y
CONFIG_BSP_UART2_RX_BUFSIZE
=
256
CONFIG_BSP_UART2_TX_BUFSIZE
=
256
# CONFIG_BSP_USING_ON_CHIP_FLASH is not set
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_QSPI is not set
...
...
@@ -393,9 +628,11 @@ CONFIG_BSP_USING_UART1=y
# CONFIG_BSP_USING_TIM is not set
# CONFIG_BSP_USING_PWM is not set
# CONFIG_BSP_USING_ADC is not set
# CONFIG_BSP_USING_DAC is not set
# CONFIG_BSP_USING_ONCHIP_RTC is not set
# CONFIG_BSP_USING_WDT is not set
# CONFIG_BSP_USING_USBD_FS is not set
# CONFIG_BSP_USING_USBD is not set
# CONFIG_BSP_USING_STM32_SDIO is not set
# CONFIG_BSP_USING_CRC is not set
# CONFIG_BSP_USING_RNG is not set
# CONFIG_BSP_USING_UDID is not set
...
...
bsp/stm32/stm32l475-atk-pandora/board/Kconfig
浏览文件 @
d94be14d
...
...
@@ -152,23 +152,59 @@ menu "On-chip Peripheral Drivers"
default y
select RT_USING_SERIAL
if BSP_USING_UART
config BSP_USING_UART1
bool "Enable UART1"
menu
config BSP_USING_UART1
bool "Enable UART1
(Debugger)
"
default y
if BSP_USING_UART1
config BSP_UART1_RX_USING_DMA
bool "Enable UART1 RX DMA"
depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA
default n
config BSP_UART1_TX_USING_DMA
bool "Enable UART1 TX DMA"
depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA
default n
config BSP_UART1_RX_BUFSIZE
int "Set UART1 RX buffer size"
range 64 65535
depends on RT_USING_SERIAL_V2
default 256
config BSP_UART1_TX_BUFSIZE
int "Set UART1 TX buffer size"
range 0 65535
depends on RT_USING_SERIAL_V2
default 0
endif
config BSP_UART1_RX_USING_DMA
bool "Enable UART1 RX DMA"
depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA
default n
config BSP_USING_UART2
menuconfig BSP_USING_UART2
bool "Enable UART2"
default n
config BSP_UART2_RX_USING_DMA
bool "Enable UART2 RX DMA"
depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA
default n
if BSP_USING_UART2
config BSP_UART2_RX_USING_DMA
bool "Enable UART2 RX DMA"
depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA
default n
config BSP_UART2_TX_USING_DMA
bool "Enable UART2 TX DMA"
depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA
default n
config BSP_UART2_RX_BUFSIZE
int "Set UART2 RX buffer size"
range 64 65535
depends on RT_USING_SERIAL_V2
default 256
config BSP_UART2_TX_BUFSIZE
int "Set UART2 TX buffer size"
range 0 65535
depends on RT_USING_SERIAL_V2
default 256
endif
endif
config BSP_USING_ON_CHIP_FLASH
...
...
bsp/stm32/stm32l475-atk-pandora/rtconfig.h
浏览文件 @
d94be14d
...
...
@@ -16,6 +16,9 @@
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 256
/* kservice optimization */
#define RT_DEBUG
#define RT_DEBUG_COLOR
...
...
@@ -39,7 +42,7 @@
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 256
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x4000
2
#define RT_VER_NUM 0x4000
4
#define ARCH_ARM
#define RT_USING_CPU_FFS
#define ARCH_ARM_CORTEX_M
...
...
@@ -79,8 +82,8 @@
#define RT_USING_DEVICE_IPC
#define RT_PIPE_BUFSZ 512
#define RT_USING_SERIAL
#define RT_USING_SERIAL_V2
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_PIN
/* Using USB */
...
...
@@ -88,7 +91,6 @@
/* POSIX layer and C standard library */
#define RT_LIBC_USING_TIME
/* Network */
...
...
@@ -109,6 +111,19 @@
/* Utilities */
#define RT_USING_RT_LINK
#define RT_LINK_USING_SF_CRC
/* rt-link hardware device configuration */
#define RT_LINK_HW_DEVICE_NAME "uart2"
#define RT_LINK_USING_UART
/* rt link debug option */
/* RT-Thread Utestcases */
/* RT-Thread online packages */
...
...
@@ -141,14 +156,29 @@
/* system packages */
/* Micrium: Micrium software products porting for RT-Thread */
/* peripheral libraries and drivers */
/* AI packages */
/* miscellaneous packages */
/* samples: kernel and components samples */
/* games: games run on RT-Thread console */
/* Privated Packages of RealThread */
/* Network Utilities */
#define SOC_FAMILY_STM32
#define SOC_SERIES_STM32L4
...
...
@@ -165,6 +195,13 @@
#define BSP_USING_GPIO
#define BSP_USING_UART
#define BSP_USING_UART1
#define BSP_UART1_RX_BUFSIZE 256
#define BSP_UART1_TX_BUFSIZE 0
#define BSP_USING_UART2
#define BSP_UART2_RX_USING_DMA
#define BSP_UART2_TX_USING_DMA
#define BSP_UART2_RX_BUFSIZE 256
#define BSP_UART2_TX_BUFSIZE 256
/* Board extended module Drivers */
...
...
components/drivers/Kconfig
浏览文件 @
d94be14d
...
...
@@ -24,22 +24,30 @@ if RT_USING_DEVICE_IPC
endif
endif
config RT_USING_SERIAL
bool "U
sing s
erial device drivers"
menu
config RT_USING_SERIAL
bool "U
SING S
erial device drivers"
select RT_USING_DEVICE_IPC
select RT_USING_DEVICE
default y
if RT_USING_SERIAL
config RT_SERIAL_USING_DMA
bool "Enable serial DMA mode"
default y
config RT_SERIAL_RB_BUFSZ
int "Set RX buffer size"
default 64
if RT_USING_SERIAL
choice
prompt "Choice Serial version"
default RT_USING_SERIAL_V1
config RT_USING_SERIAL_V1
bool "RT_USING_SERIAL_V1"
config RT_USING_SERIAL_V2
bool "RT_USING_SERIAL_V2"
endchoice
config RT_SERIAL_USING_DMA
bool "Enable serial DMA mode"
default y
endif
config RT_SERIAL_RB_BUFSZ
int "Set RX buffer size"
depends on !RT_USING_SERIAL_V2
default 64
endif
config RT_USING_CAN
bool "Using CAN device drivers"
...
...
components/drivers/include/drivers/serial_v2.h
0 → 100644
浏览文件 @
d94be14d
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-01 KyleChan first version
*/
#ifndef __SERIAL_V2_H__
#define __SERIAL_V2_H__
#include <rtthread.h>
#define BAUD_RATE_2400 2400
#define BAUD_RATE_4800 4800
#define BAUD_RATE_9600 9600
#define BAUD_RATE_19200 19200
#define BAUD_RATE_38400 38400
#define BAUD_RATE_57600 57600
#define BAUD_RATE_115200 115200
#define BAUD_RATE_230400 230400
#define BAUD_RATE_460800 460800
#define BAUD_RATE_921600 921600
#define BAUD_RATE_2000000 2000000
#define BAUD_RATE_3000000 3000000
#define DATA_BITS_5 5
#define DATA_BITS_6 6
#define DATA_BITS_7 7
#define DATA_BITS_8 8
#define DATA_BITS_9 9
#define STOP_BITS_1 0
#define STOP_BITS_2 1
#define STOP_BITS_3 2
#define STOP_BITS_4 3
#ifdef _WIN32
#include <windows.h>
#else
#define PARITY_NONE 0
#define PARITY_ODD 1
#define PARITY_EVEN 2
#endif
#define BIT_ORDER_LSB 0
#define BIT_ORDER_MSB 1
#define NRZ_NORMAL 0
/* Non Return to Zero : normal mode */
#define NRZ_INVERTED 1
/* Non Return to Zero : inverted mode */
#define RT_DEVICE_FLAG_RX_BLOCKING 0x1000
#define RT_DEVICE_FLAG_RX_NON_BLOCKING 0x2000
#define RT_DEVICE_FLAG_TX_BLOCKING 0x4000
#define RT_DEVICE_FLAG_TX_NON_BLOCKING 0x8000
#define RT_SERIAL_RX_BLOCKING RT_DEVICE_FLAG_RX_BLOCKING
#define RT_SERIAL_RX_NON_BLOCKING RT_DEVICE_FLAG_RX_NON_BLOCKING
#define RT_SERIAL_TX_BLOCKING RT_DEVICE_FLAG_TX_BLOCKING
#define RT_SERIAL_TX_NON_BLOCKING RT_DEVICE_FLAG_TX_NON_BLOCKING
#define RT_DEVICE_CHECK_OPTMODE 0x20
#define RT_SERIAL_EVENT_RX_IND 0x01
/* Rx indication */
#define RT_SERIAL_EVENT_TX_DONE 0x02
/* Tx complete */
#define RT_SERIAL_EVENT_RX_DMADONE 0x03
/* Rx DMA transfer done */
#define RT_SERIAL_EVENT_TX_DMADONE 0x04
/* Tx DMA transfer done */
#define RT_SERIAL_EVENT_RX_TIMEOUT 0x05
/* Rx timeout */
#define RT_SERIAL_ERR_OVERRUN 0x01
#define RT_SERIAL_ERR_FRAMING 0x02
#define RT_SERIAL_ERR_PARITY 0x03
#define RT_SERIAL_TX_DATAQUEUE_SIZE 2048
#define RT_SERIAL_TX_DATAQUEUE_LWM 30
#define RT_SERIAL_RX_MINBUFSZ 64
#define RT_SERIAL_TX_MINBUFSZ 64
#define RT_SERIAL_TX_BLOCKING_BUFFER 1
#define RT_SERIAL_TX_BLOCKING_NO_BUFFER 0
/* Default config for serial_configure structure */
#define RT_SERIAL_CONFIG_DEFAULT \
{ \
BAUD_RATE_115200,
/* 115200 bits/s */
\
DATA_BITS_8,
/* 8 databits */
\
STOP_BITS_1,
/* 1 stopbit */
\
PARITY_NONE,
/* No parity */
\
BIT_ORDER_LSB,
/* LSB first sent */
\
NRZ_NORMAL,
/* Normal mode */
\
RT_SERIAL_RX_MINBUFSZ,
/* rxBuf size */
\
RT_SERIAL_TX_MINBUFSZ,
/* txBuf size */
\
0 \
}
struct
serial_configure
{
rt_uint32_t
baud_rate
;
rt_uint32_t
data_bits
:
4
;
rt_uint32_t
stop_bits
:
2
;
rt_uint32_t
parity
:
2
;
rt_uint32_t
bit_order
:
1
;
rt_uint32_t
invert
:
1
;
rt_uint32_t
rx_bufsz
:
16
;
rt_uint32_t
tx_bufsz
:
16
;
rt_uint32_t
reserved
:
6
;
};
/*
* Serial FIFO mode
*/
struct
rt_serial_rx_fifo
{
struct
rt_ringbuffer
rb
;
rt_uint16_t
rx_index
;
struct
rt_completion
rx_cpt
;
rt_uint16_t
rx_cpt_index
;
/* software fifo */
rt_uint8_t
buffer
[];
};
struct
rt_serial_tx_fifo
{
struct
rt_ringbuffer
rb
;
rt_size_t
put_size
;
rt_bool_t
activated
;
struct
rt_completion
tx_cpt
;
/* software fifo */
rt_uint8_t
buffer
[];
};
struct
rt_serial_device
{
struct
rt_device
parent
;
const
struct
rt_uart_ops
*
ops
;
struct
serial_configure
config
;
void
*
serial_rx
;
void
*
serial_tx
;
};
/**
* uart operators
*/
struct
rt_uart_ops
{
rt_err_t
(
*
configure
)(
struct
rt_serial_device
*
serial
,
struct
serial_configure
*
cfg
);
rt_err_t
(
*
control
)(
struct
rt_serial_device
*
serial
,
int
cmd
,
void
*
arg
);
int
(
*
putc
)(
struct
rt_serial_device
*
serial
,
char
c
);
int
(
*
getc
)(
struct
rt_serial_device
*
serial
);
rt_size_t
(
*
transmit
)(
struct
rt_serial_device
*
serial
,
rt_uint8_t
*
buf
,
rt_size_t
size
,
rt_uint32_t
tx_flag
);
};
rt_size_t
rt_serial_get_linear_buffer
(
struct
rt_ringbuffer
*
rb
,
rt_uint8_t
**
ptr
);
rt_size_t
rt_serial_update_read_index
(
struct
rt_ringbuffer
*
rb
,
rt_uint16_t
read_index
);
rt_size_t
rt_serial_update_write_index
(
struct
rt_ringbuffer
*
rb
,
rt_uint16_t
write_index
);
void
rt_hw_serial_isr
(
struct
rt_serial_device
*
serial
,
int
event
);
rt_err_t
rt_hw_serial_register
(
struct
rt_serial_device
*
serial
,
const
char
*
name
,
rt_uint32_t
flag
,
void
*
data
);
#endif
components/drivers/include/rtdevice.h
浏览文件 @
d94be14d
...
...
@@ -57,7 +57,11 @@ extern "C" {
#endif
/* RT_USING_USB_HOST */
#ifdef RT_USING_SERIAL
#ifdef RT_USING_SERIAL_V2
#include "drivers/serial_v2.h"
#else
#include "drivers/serial.h"
#endif
#endif
/* RT_USING_SERIAL */
#ifdef RT_USING_I2C
...
...
components/drivers/serial/SConscript
浏览文件 @
d94be14d
from
building
import
*
cwd
=
GetCurrentDir
()
src
=
Glob
(
'*.c'
)
cwd
=
GetCurrentDir
()
CPPPATH
=
[
cwd
+
'/../include'
]
group
=
DefineGroup
(
'DeviceDrivers'
,
src
,
depend
=
[
'RT_USING_SERIAL'
],
CPPPATH
=
CPPPATH
)
if
GetDepend
([
'RT_USING_SERIAL'
]):
if
GetDepend
([
'RT_USING_SERIAL_V2'
]):
src
=
Glob
(
'serial_v2.c'
)
group
=
DefineGroup
(
'DeviceDrivers'
,
src
,
depend
=
[
'RT_USING_SERIAL_V2'
],
CPPPATH
=
CPPPATH
)
else
:
src
=
Glob
(
'serial.c'
)
group
=
DefineGroup
(
'DeviceDrivers'
,
src
,
depend
=
[
'RT_USING_SERIAL'
],
CPPPATH
=
CPPPATH
)
Return
(
'group'
)
components/drivers/serial/serial_v2.c
0 → 100644
浏览文件 @
d94be14d
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-01 KyleChan first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "UART"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef RT_USING_POSIX
#include <dfs_posix.h>
#include <dfs_poll.h>
#ifdef getc
#undef getc
#endif
#ifdef putc
#undef putc
#endif
static
rt_err_t
serial_fops_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
)
{
rt_wqueue_wakeup
(
&
(
dev
->
wait_queue
),
(
void
*
)
POLLIN
);
return
RT_EOK
;
}
/* fops for serial */
static
int
serial_fops_open
(
struct
dfs_fd
*
fd
)
{
rt_err_t
ret
=
0
;
rt_uint16_t
flags
=
0
;
rt_device_t
device
;
device
=
(
rt_device_t
)
fd
->
data
;
RT_ASSERT
(
device
!=
RT_NULL
);
switch
(
fd
->
flags
&
O_ACCMODE
)
{
case
O_RDONLY
:
LOG_D
(
"fops open: O_RDONLY!"
);
flags
=
RT_DEVICE_FLAG_RDONLY
;
break
;
case
O_WRONLY
:
LOG_D
(
"fops open: O_WRONLY!"
);
flags
=
RT_DEVICE_FLAG_WRONLY
;
break
;
case
O_RDWR
:
LOG_D
(
"fops open: O_RDWR!"
);
flags
=
RT_DEVICE_FLAG_RDWR
;
break
;
default:
LOG_E
(
"fops open: unknown mode - %d!"
,
fd
->
flags
&
O_ACCMODE
);
break
;
}
if
((
fd
->
flags
&
O_ACCMODE
)
!=
O_WRONLY
)
rt_device_set_rx_indicate
(
device
,
serial_fops_rx_ind
);
ret
=
rt_device_open
(
device
,
flags
);
if
(
ret
==
RT_EOK
)
return
0
;
return
ret
;
}
static
int
serial_fops_close
(
struct
dfs_fd
*
fd
)
{
rt_device_t
device
;
device
=
(
rt_device_t
)
fd
->
data
;
rt_device_set_rx_indicate
(
device
,
RT_NULL
);
rt_device_close
(
device
);
return
0
;
}
static
int
serial_fops_ioctl
(
struct
dfs_fd
*
fd
,
int
cmd
,
void
*
args
)
{
rt_device_t
device
;
device
=
(
rt_device_t
)
fd
->
data
;
switch
(
cmd
)
{
case
FIONREAD
:
break
;
case
FIONWRITE
:
break
;
}
return
rt_device_control
(
device
,
cmd
,
args
);
}
static
int
serial_fops_read
(
struct
dfs_fd
*
fd
,
void
*
buf
,
size_t
count
)
{
int
size
=
0
;
rt_device_t
device
;
device
=
(
rt_device_t
)
fd
->
data
;
do
{
size
=
rt_device_read
(
device
,
-
1
,
buf
,
count
);
if
(
size
<=
0
)
{
if
(
fd
->
flags
&
O_NONBLOCK
)
{
size
=
-
EAGAIN
;
break
;
}
rt_wqueue_wait
(
&
(
device
->
wait_queue
),
0
,
RT_WAITING_FOREVER
);
}
}
while
(
size
<=
0
);
return
size
;
}
static
int
serial_fops_write
(
struct
dfs_fd
*
fd
,
const
void
*
buf
,
size_t
count
)
{
rt_device_t
device
;
device
=
(
rt_device_t
)
fd
->
data
;
return
rt_device_write
(
device
,
-
1
,
buf
,
count
);
}
static
int
serial_fops_poll
(
struct
dfs_fd
*
fd
,
struct
rt_pollreq
*
req
)
{
int
mask
=
0
;
int
flags
=
0
;
rt_device_t
device
;
struct
rt_serial_device
*
serial
;
device
=
(
rt_device_t
)
fd
->
data
;
RT_ASSERT
(
device
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
device
;
/* only support POLLIN */
flags
=
fd
->
flags
&
O_ACCMODE
;
if
(
flags
==
O_RDONLY
||
flags
==
O_RDWR
)
{
rt_base_t
level
;
struct
rt_serial_rx_fifo
*
rx_fifo
;
rt_poll_add
(
&
(
device
->
wait_queue
),
req
);
rx_fifo
=
(
struct
rt_serial_rx_fifo
*
)
serial
->
serial_rx
;
level
=
rt_hw_interrupt_disable
();
if
(
rt_ringbuffer_data_len
(
&
rx_fifo
->
rb
))
mask
|=
POLLIN
;
rt_hw_interrupt_enable
(
level
);
}
// mask|=POLLOUT;
return
mask
;
}
const
static
struct
dfs_file_ops
_serial_fops
=
{
serial_fops_open
,
serial_fops_close
,
serial_fops_ioctl
,
serial_fops_read
,
serial_fops_write
,
RT_NULL
,
/* flush */
RT_NULL
,
/* lseek */
RT_NULL
,
/* getdents */
serial_fops_poll
,
};
#endif
rt_size_t
rt_serial_get_linear_buffer
(
struct
rt_ringbuffer
*
rb
,
rt_uint8_t
**
ptr
)
{
rt_size_t
size
;
RT_ASSERT
(
rb
!=
RT_NULL
);
*
ptr
=
RT_NULL
;
/* whether has enough data */
size
=
rt_ringbuffer_data_len
(
rb
);
/* no data */
if
(
size
==
0
)
return
0
;
*
ptr
=
&
rb
->
buffer_ptr
[
rb
->
read_index
];
if
(
rb
->
buffer_size
-
rb
->
read_index
>
size
)
{
return
size
;
}
return
rb
->
buffer_size
-
rb
->
read_index
;
}
rt_size_t
rt_serial_update_read_index
(
struct
rt_ringbuffer
*
rb
,
rt_uint16_t
read_index
)
{
rt_size_t
size
;
RT_ASSERT
(
rb
!=
RT_NULL
);
/* whether has enough data */
size
=
rt_ringbuffer_data_len
(
rb
);
/* no data */
if
(
size
==
0
)
return
0
;
/* less data */
if
(
size
<
read_index
)
read_index
=
size
;
if
(
rb
->
buffer_size
-
rb
->
read_index
>
read_index
)
{
rb
->
read_index
+=
read_index
;
return
read_index
;
}
read_index
=
rb
->
buffer_size
-
rb
->
read_index
;
/* we are going into the other side of the mirror */
rb
->
read_mirror
=
~
rb
->
read_mirror
;
rb
->
read_index
=
0
;
return
read_index
;
}
rt_size_t
rt_serial_update_write_index
(
struct
rt_ringbuffer
*
rb
,
rt_uint16_t
write_index
)
{
rt_uint16_t
size
;
RT_ASSERT
(
rb
!=
RT_NULL
);
/* whether has enough space */
size
=
rt_ringbuffer_space_len
(
rb
);
/* no space */
if
(
size
==
0
)
return
0
;
/* drop some data */
if
(
size
<
write_index
)
write_index
=
size
;
if
(
rb
->
buffer_size
-
rb
->
write_index
>
write_index
)
{
/* this should not cause overflow because there is enough space for
* length of data in current mirror */
rb
->
write_index
+=
write_index
;
return
write_index
;
}
/* we are going into the other side of the mirror */
rb
->
write_mirror
=
~
rb
->
write_mirror
;
rb
->
write_index
=
write_index
-
(
rb
->
buffer_size
-
rb
->
write_index
);
return
write_index
;
}
/**
* @brief Serial polling receive data routine, This function will receive data
* in a continuous loop by one by one byte.
* @param dev The pointer of device driver structure
* @param pos Empty parameter.
* @param buffer Receive data buffer.
* @param size Receive data buffer length.
* @return Return the final length of data received.
*/
rt_size_t
_serial_poll_rx
(
struct
rt_device
*
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
struct
rt_serial_device
*
serial
;
rt_size_t
getc_size
;
int
getc_element
;
/* Gets one byte of data received */
rt_uint8_t
*
getc_buffer
;
/* Pointer to the receive data buffer */
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
RT_ASSERT
(
serial
!=
RT_NULL
);
getc_buffer
=
(
rt_uint8_t
*
)
buffer
;
getc_size
=
size
;
while
(
size
)
{
getc_element
=
serial
->
ops
->
getc
(
serial
);
if
(
getc_element
==
-
1
)
break
;
*
getc_buffer
=
getc_element
;
++
getc_buffer
;
--
size
;
if
(
serial
->
parent
.
open_flag
&
RT_DEVICE_FLAG_STREAM
)
{
/* If open_flag satisfies RT_DEVICE_FLAG_STREAM
* and the received character is '\n', exit the loop directly */
if
(
getc_element
==
'\n'
)
break
;
}
}
return
getc_size
-
size
;
}
/**
* @brief Serial polling transmit data routines, This function will transmit
* data in a continuous loop by one by one byte.
* @param dev The pointer of device driver structure
* @param pos Empty parameter.
* @param buffer Transmit data buffer.
* @param size Transmit data buffer length.
* @return Return the final length of data received.
*/
rt_size_t
_serial_poll_tx
(
struct
rt_device
*
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
struct
rt_serial_device
*
serial
;
rt_size_t
putc_size
;
rt_uint8_t
*
putc_buffer
;
/* Pointer to the transmit data buffer */
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
RT_ASSERT
(
serial
!=
RT_NULL
);
putc_buffer
=
(
rt_uint8_t
*
)
buffer
;
putc_size
=
size
;
while
(
size
)
{
if
(
serial
->
parent
.
open_flag
&
RT_DEVICE_FLAG_STREAM
)
{
/* If open_flag satisfies RT_DEVICE_FLAG_STREAM and the received character is '\n',
* inserts '\r' character before '\n' character for the effect of carriage return newline */
if
(
*
putc_buffer
==
'\n'
)
serial
->
ops
->
putc
(
serial
,
'\r'
);
}
serial
->
ops
->
putc
(
serial
,
*
putc_buffer
);
++
putc_buffer
;
--
size
;
}
return
putc_size
-
size
;
}
/**
* @brief Serial receive data routines, This function will receive
* data by using fifo
* @param dev The pointer of device driver structure
* @param pos Empty parameter.
* @param buffer Receive data buffer.
* @param size Receive data buffer length.
* @return Return the final length of data received.
*/
static
rt_size_t
_serial_fifo_rx
(
struct
rt_device
*
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
struct
rt_serial_device
*
serial
;
struct
rt_serial_rx_fifo
*
rx_fifo
;
rt_base_t
level
;
rt_size_t
recv_len
;
/* The length of data from the ringbuffer */
RT_ASSERT
(
dev
!=
RT_NULL
);
if
(
size
==
0
)
return
0
;
serial
=
(
struct
rt_serial_device
*
)
dev
;
RT_ASSERT
((
serial
!=
RT_NULL
)
&&
(
buffer
!=
RT_NULL
));
rx_fifo
=
(
struct
rt_serial_rx_fifo
*
)
serial
->
serial_rx
;
if
(
dev
->
open_flag
&
RT_SERIAL_RX_BLOCKING
)
{
if
(
size
>
serial
->
config
.
rx_bufsz
)
{
LOG_W
(
"(%s) serial device received data:[%d] larger than "
"rx_bufsz:[%d], please increase the BSP_UARTx_RX_BUFSIZE option"
,
dev
->
parent
.
name
,
size
,
serial
->
config
.
rx_bufsz
);
return
0
;
}
/* Get the length of the data from the ringbuffer */
recv_len
=
rt_ringbuffer_data_len
(
&
(
rx_fifo
->
rb
));
if
(
recv_len
<
size
)
{
/* When recv_len is less than size, rx_cpt_index is updated to the size
* and rt_current_thread is suspend until rx_cpt_index is equal to 0 */
rx_fifo
->
rx_cpt_index
=
size
;
rt_completion_wait
(
&
(
rx_fifo
->
rx_cpt
),
RT_WAITING_FOREVER
);
}
}
/* This part of the code is open_flag as RT_SERIAL_RX_NON_BLOCKING */
level
=
rt_hw_interrupt_disable
();
/* When open_flag is RT_SERIAL_RX_NON_BLOCKING,
* the data is retrieved directly from the ringbuffer and returned */
recv_len
=
rt_ringbuffer_get
(
&
(
rx_fifo
->
rb
),
buffer
,
size
);
rt_hw_interrupt_enable
(
level
);
return
recv_len
;
}
/**
* @brief Serial transmit data routines, This function will transmit
* data by using blocking_nbuf.
* @param dev The pointer of device driver structure
* @param pos Empty parameter.
* @param buffer Transmit data buffer.
* @param size Transmit data buffer length.
* @return Return the final length of data transmit.
*/
static
rt_size_t
_serial_fifo_tx_blocking_nbuf
(
struct
rt_device
*
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
struct
rt_serial_device
*
serial
;
struct
rt_serial_tx_fifo
*
tx_fifo
=
RT_NULL
;
RT_ASSERT
(
dev
!=
RT_NULL
);
if
(
size
==
0
)
return
0
;
serial
=
(
struct
rt_serial_device
*
)
dev
;
RT_ASSERT
((
serial
!=
RT_NULL
)
&&
(
buffer
!=
RT_NULL
));
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
serial
->
serial_tx
;
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
/* When serial transmit in tx_blocking mode,
* if the activated mode is RT_TRUE, it will return directly */
if
(
tx_fifo
->
activated
==
RT_TRUE
)
return
0
;
tx_fifo
->
activated
=
RT_TRUE
;
/* Call the transmit interface for transmission */
serial
->
ops
->
transmit
(
serial
,
(
rt_uint8_t
*
)
buffer
,
size
,
RT_SERIAL_TX_BLOCKING
);
/* Waiting for the transmission to complete */
rt_completion_wait
(
&
(
tx_fifo
->
tx_cpt
),
RT_WAITING_FOREVER
);
return
size
;
}
/**
* @brief Serial transmit data routines, This function will transmit
* data by using blocking_buf.
* @param dev The pointer of device driver structure
* @param pos Empty parameter.
* @param buffer Transmit data buffer.
* @param size Transmit data buffer length.
* @return Return the final length of data transmit.
*/
static
rt_size_t
_serial_fifo_tx_blocking_buf
(
struct
rt_device
*
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
struct
rt_serial_device
*
serial
;
struct
rt_serial_tx_fifo
*
tx_fifo
=
RT_NULL
;
RT_ASSERT
(
dev
!=
RT_NULL
);
if
(
size
==
0
)
return
0
;
serial
=
(
struct
rt_serial_device
*
)
dev
;
RT_ASSERT
((
serial
!=
RT_NULL
)
&&
(
buffer
!=
RT_NULL
));
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
serial
->
serial_tx
;
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
/* When serial transmit in tx_blocking mode,
* if the activated mode is RT_TRUE, it will return directly */
if
(
tx_fifo
->
activated
==
RT_TRUE
)
return
0
;
tx_fifo
->
activated
=
RT_TRUE
;
rt_size_t
length
=
size
;
rt_size_t
offset
=
0
;
while
(
size
)
{
/* Copy one piece of data into the ringbuffer at a time
* until the length of the data is equal to size */
tx_fifo
->
put_size
=
rt_ringbuffer_put
(
&
(
tx_fifo
->
rb
),
(
rt_uint8_t
*
)
buffer
+
offset
,
size
);
offset
+=
tx_fifo
->
put_size
;
size
-=
tx_fifo
->
put_size
;
/* Call the transmit interface for transmission */
serial
->
ops
->
transmit
(
serial
,
(
rt_uint8_t
*
)
buffer
+
offset
,
tx_fifo
->
put_size
,
RT_SERIAL_TX_BLOCKING
);
/* Waiting for the transmission to complete */
rt_completion_wait
(
&
(
tx_fifo
->
tx_cpt
),
RT_WAITING_FOREVER
);
}
return
length
;
}
/**
* @brief Serial transmit data routines, This function will transmit
* data by using nonblocking.
* @param dev The pointer of device driver structure
* @param pos Empty parameter.
* @param buffer Transmit data buffer.
* @param size Transmit data buffer length.
* @return Return the final length of data transmit.
*/
static
rt_size_t
_serial_fifo_tx_nonblocking
(
struct
rt_device
*
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
struct
rt_serial_device
*
serial
;
struct
rt_serial_tx_fifo
*
tx_fifo
;
rt_base_t
level
;
rt_size_t
length
;
RT_ASSERT
(
dev
!=
RT_NULL
);
if
(
size
==
0
)
return
0
;
serial
=
(
struct
rt_serial_device
*
)
dev
;
RT_ASSERT
((
serial
!=
RT_NULL
)
&&
(
buffer
!=
RT_NULL
));
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
serial
->
serial_tx
;
level
=
rt_hw_interrupt_disable
();
if
(
tx_fifo
->
activated
==
RT_FALSE
)
{
/* When serial transmit in tx_non_blocking mode, if the activated mode is RT_FALSE,
* start copying data into the ringbuffer */
tx_fifo
->
activated
=
RT_TRUE
;
/* Copying data into the ringbuffer */
length
=
rt_ringbuffer_put
(
&
(
tx_fifo
->
rb
),
buffer
,
size
);
rt_hw_interrupt_enable
(
level
);
rt_uint8_t
*
put_ptr
=
RT_NULL
;
/* Get the linear length buffer from rinbuffer */
tx_fifo
->
put_size
=
rt_serial_get_linear_buffer
(
&
(
tx_fifo
->
rb
),
&
put_ptr
);
/* Call the transmit interface for transmission */
serial
->
ops
->
transmit
(
serial
,
put_ptr
,
tx_fifo
->
put_size
,
RT_SERIAL_TX_NON_BLOCKING
);
/* In tx_nonblocking mode, there is no need to call rt_completion_wait() APIs to wait
* for the rt_current_thread to resume */
return
length
;
}
/* If the activated mode is RT_FALSE, it means that serial device is transmitting,
* where only the data in the ringbuffer and there is no need to call the transmit() API.
* Note that this part of the code requires disable interrupts
* to prevent multi thread reentrant */
/* Copying data into the ringbuffer */
length
=
rt_ringbuffer_put
(
&
(
tx_fifo
->
rb
),
buffer
,
size
);
rt_hw_interrupt_enable
(
level
);
return
length
;
}
/**
* @brief Enable serial transmit mode.
* @param dev The pointer of device driver structure
* @param rx_oflag The flag of that the serial port opens.
* @return Return the status of the operation.
*/
static
rt_err_t
rt_serial_tx_enable
(
struct
rt_device
*
dev
,
rt_uint16_t
tx_oflag
)
{
struct
rt_serial_device
*
serial
;
struct
rt_serial_tx_fifo
*
tx_fifo
=
RT_NULL
;
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
if
(
serial
->
config
.
tx_bufsz
==
0
)
{
/* Cannot use RT_SERIAL_TX_NON_BLOCKING when tx_bufsz is 0 */
if
(
tx_oflag
==
RT_SERIAL_TX_NON_BLOCKING
)
{
LOG_E
(
"(%s) serial device with misconfigure: tx_bufsz = 0"
,
dev
->
parent
.
name
);
return
-
RT_EINVAL
;
}
dev
->
write
=
_serial_poll_tx
;
dev
->
open_flag
|=
RT_SERIAL_TX_BLOCKING
;
return
RT_EOK
;
}
/* Limits the minimum value of tx_bufsz */
if
(
serial
->
config
.
tx_bufsz
<
RT_SERIAL_TX_MINBUFSZ
)
serial
->
config
.
tx_bufsz
=
RT_SERIAL_TX_MINBUFSZ
;
if
(
tx_oflag
==
RT_SERIAL_TX_BLOCKING
)
{
/* When using RT_SERIAL_TX_BLOCKING, it is necessary to determine
* whether serial device needs to use buffer */
rt_err_t
optmode
;
/* The operating mode used by serial device */
/* Call the Control() API to get the operating mode */
optmode
=
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CHECK_OPTMODE
,
(
void
*
)
RT_DEVICE_FLAG_TX_BLOCKING
);
if
(
optmode
==
RT_SERIAL_TX_BLOCKING_BUFFER
)
{
/* If use RT_SERIAL_TX_BLOCKING_BUFFER, the ringbuffer is initialized */
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
rt_malloc
(
sizeof
(
struct
rt_serial_tx_fifo
)
+
serial
->
config
.
tx_bufsz
);
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
rt_ringbuffer_init
(
&
(
tx_fifo
->
rb
),
tx_fifo
->
buffer
,
serial
->
config
.
tx_bufsz
);
serial
->
serial_tx
=
tx_fifo
;
dev
->
write
=
_serial_fifo_tx_blocking_buf
;
}
else
{
/* If not use RT_SERIAL_TX_BLOCKING_BUFFER,
* the control() API is called to configure the serial device */
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
rt_malloc
(
sizeof
(
struct
rt_serial_tx_fifo
));
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
serial
->
serial_tx
=
tx_fifo
;
dev
->
write
=
_serial_fifo_tx_blocking_nbuf
;
/* Call the control() API to configure the serial device by RT_SERIAL_TX_BLOCKING*/
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CONFIG
,
(
void
*
)
RT_SERIAL_TX_BLOCKING
);
}
tx_fifo
->
activated
=
RT_FALSE
;
tx_fifo
->
put_size
=
0
;
rt_completion_init
(
&
(
tx_fifo
->
tx_cpt
));
dev
->
open_flag
|=
RT_SERIAL_TX_BLOCKING
;
return
RT_EOK
;
}
/* When using RT_SERIAL_TX_NON_BLOCKING, ringbuffer needs to be initialized,
* and initialize the tx_fifo->activated value is RT_FALSE.
*/
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
rt_malloc
(
sizeof
(
struct
rt_serial_tx_fifo
)
+
serial
->
config
.
tx_bufsz
);
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
tx_fifo
->
activated
=
RT_FALSE
;
tx_fifo
->
put_size
=
0
;
rt_ringbuffer_init
(
&
(
tx_fifo
->
rb
),
tx_fifo
->
buffer
,
serial
->
config
.
tx_bufsz
);
serial
->
serial_tx
=
tx_fifo
;
dev
->
write
=
_serial_fifo_tx_nonblocking
;
dev
->
open_flag
|=
RT_SERIAL_TX_NON_BLOCKING
;
/* Call the control() API to configure the serial device by RT_SERIAL_TX_NON_BLOCKING*/
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CONFIG
,
(
void
*
)
RT_SERIAL_TX_NON_BLOCKING
);
return
RT_EOK
;
}
/**
* @brief Enable serial receive mode.
* @param dev The pointer of device driver structure
* @param rx_oflag The flag of that the serial port opens.
* @return Return the status of the operation.
*/
static
rt_err_t
rt_serial_rx_enable
(
struct
rt_device
*
dev
,
rt_uint16_t
rx_oflag
)
{
struct
rt_serial_device
*
serial
;
struct
rt_serial_rx_fifo
*
rx_fifo
=
RT_NULL
;
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
if
(
serial
->
config
.
rx_bufsz
==
0
)
{
/* Cannot use RT_SERIAL_RX_NON_BLOCKING when rx_bufsz is 0 */
if
(
rx_oflag
==
RT_SERIAL_RX_NON_BLOCKING
)
{
LOG_E
(
"(%s) serial device with misconfigure: rx_bufsz = 0"
,
dev
->
parent
.
name
);
return
-
RT_EINVAL
;
}
dev
->
read
=
_serial_poll_rx
;
dev
->
open_flag
|=
RT_SERIAL_RX_BLOCKING
;
return
RT_EOK
;
}
/* Limits the minimum value of rx_bufsz */
if
(
serial
->
config
.
rx_bufsz
<
RT_SERIAL_RX_MINBUFSZ
)
serial
->
config
.
rx_bufsz
=
RT_SERIAL_RX_MINBUFSZ
;
rx_fifo
=
(
struct
rt_serial_rx_fifo
*
)
rt_malloc
(
sizeof
(
struct
rt_serial_rx_fifo
)
+
serial
->
config
.
rx_bufsz
);
RT_ASSERT
(
rx_fifo
!=
RT_NULL
);
rt_ringbuffer_init
(
&
(
rx_fifo
->
rb
),
rx_fifo
->
buffer
,
serial
->
config
.
rx_bufsz
);
rx_fifo
->
rx_index
=
serial
->
config
.
rx_bufsz
;
serial
->
serial_rx
=
rx_fifo
;
dev
->
read
=
_serial_fifo_rx
;
if
(
rx_oflag
==
RT_SERIAL_RX_NON_BLOCKING
)
{
dev
->
open_flag
|=
RT_SERIAL_RX_NON_BLOCKING
;
/* Call the control() API to configure the serial device by RT_SERIAL_RX_NON_BLOCKING*/
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CONFIG
,
(
void
*
)
RT_SERIAL_RX_NON_BLOCKING
);
return
RT_EOK
;
}
/* When using RT_SERIAL_RX_BLOCKING, rt_completion_init() and rx_cpt_index are initialized */
rx_fifo
->
rx_cpt_index
=
0
;
rt_completion_init
(
&
(
rx_fifo
->
rx_cpt
));
dev
->
open_flag
|=
RT_SERIAL_RX_BLOCKING
;
/* Call the control() API to configure the serial device by RT_SERIAL_RX_BLOCKING*/
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CONFIG
,
(
void
*
)
RT_SERIAL_RX_BLOCKING
);
return
RT_EOK
;
}
/**
* @brief Disable serial receive mode.
* @param dev The pointer of device driver structure
* @param rx_oflag The flag of that the serial port opens.
* @return Return the status of the operation.
*/
static
rt_err_t
rt_serial_rx_disable
(
struct
rt_device
*
dev
,
rt_uint16_t
rx_oflag
)
{
struct
rt_serial_device
*
serial
;
struct
rt_serial_rx_fifo
*
rx_fifo
;
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
dev
->
read
=
RT_NULL
;
if
(
serial
->
serial_rx
==
RT_NULL
)
return
RT_EOK
;
do
{
if
(
rx_oflag
==
RT_SERIAL_RX_NON_BLOCKING
)
{
dev
->
open_flag
&=
~
RT_SERIAL_RX_NON_BLOCKING
;
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_SERIAL_RX_NON_BLOCKING
);
break
;
}
dev
->
open_flag
&=
~
RT_SERIAL_RX_BLOCKING
;
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_SERIAL_RX_BLOCKING
);
}
while
(
0
);
rx_fifo
=
(
struct
rt_serial_rx_fifo
*
)
serial
->
serial_rx
;
RT_ASSERT
(
rx_fifo
!=
RT_NULL
);
rt_free
(
rx_fifo
);
serial
->
serial_rx
=
RT_NULL
;
return
RT_EOK
;
}
/**
* @brief Disable serial tranmit mode.
* @param dev The pointer of device driver structure
* @param rx_oflag The flag of that the serial port opens.
* @return Return the status of the operation.
*/
static
rt_err_t
rt_serial_tx_disable
(
struct
rt_device
*
dev
,
rt_uint16_t
tx_oflag
)
{
struct
rt_serial_device
*
serial
;
struct
rt_serial_tx_fifo
*
tx_fifo
;
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
dev
->
write
=
RT_NULL
;
if
(
serial
->
serial_tx
==
RT_NULL
)
return
RT_EOK
;
do
{
if
(
tx_oflag
==
RT_SERIAL_TX_NON_BLOCKING
)
{
dev
->
open_flag
&=
~
RT_SERIAL_TX_NON_BLOCKING
;
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_SERIAL_TX_NON_BLOCKING
);
break
;
}
dev
->
open_flag
&=
~
RT_SERIAL_TX_BLOCKING
;
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_SERIAL_TX_BLOCKING
);
}
while
(
0
);
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
serial
->
serial_tx
;
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
rt_free
(
tx_fifo
);
serial
->
serial_tx
=
RT_NULL
;
return
RT_EOK
;
}
/**
* @brief Initialize the serial device.
* @param dev The pointer of device driver structure
* @return Return the status of the operation.
*/
static
rt_err_t
rt_serial_init
(
struct
rt_device
*
dev
)
{
rt_err_t
result
=
RT_EOK
;
struct
rt_serial_device
*
serial
;
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
/* initialize rx/tx */
serial
->
serial_rx
=
RT_NULL
;
serial
->
serial_tx
=
RT_NULL
;
/* apply configuration */
if
(
serial
->
ops
->
configure
)
result
=
serial
->
ops
->
configure
(
serial
,
&
serial
->
config
);
return
result
;
}
/**
* @brief Open the serial device.
* @param dev The pointer of device driver structure
* @param oflag The flag of that the serial port opens.
* @return Return the status of the operation.
*/
static
rt_err_t
rt_serial_open
(
struct
rt_device
*
dev
,
rt_uint16_t
oflag
)
{
struct
rt_serial_device
*
serial
;
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
LOG_D
(
"open serial device: 0x%08x with open flag: 0x%04x"
,
dev
,
oflag
);
/* By default, the receive mode of a serial devide is RT_SERIAL_RX_NON_BLOCKING */
if
((
oflag
&
RT_SERIAL_RX_BLOCKING
)
==
RT_SERIAL_RX_BLOCKING
)
dev
->
open_flag
|=
RT_SERIAL_RX_BLOCKING
;
else
dev
->
open_flag
|=
RT_SERIAL_RX_NON_BLOCKING
;
/* By default, the transmit mode of a serial devide is RT_SERIAL_TX_BLOCKING */
if
((
oflag
&
RT_SERIAL_TX_NON_BLOCKING
)
==
RT_SERIAL_TX_NON_BLOCKING
)
dev
->
open_flag
|=
RT_SERIAL_TX_NON_BLOCKING
;
else
dev
->
open_flag
|=
RT_SERIAL_TX_BLOCKING
;
/* set steam flag */
if
((
oflag
&
RT_DEVICE_FLAG_STREAM
)
||
(
dev
->
open_flag
&
RT_DEVICE_FLAG_STREAM
))
dev
->
open_flag
|=
RT_DEVICE_FLAG_STREAM
;
/* initialize the Rx structure according to open flag */
if
(
serial
->
serial_rx
==
RT_NULL
)
rt_serial_rx_enable
(
dev
,
dev
->
open_flag
&
(
RT_SERIAL_RX_BLOCKING
|
RT_SERIAL_RX_NON_BLOCKING
));
/* initialize the Tx structure according to open flag */
if
(
serial
->
serial_tx
==
RT_NULL
)
rt_serial_tx_enable
(
dev
,
dev
->
open_flag
&
(
RT_SERIAL_TX_BLOCKING
|
RT_SERIAL_TX_NON_BLOCKING
));
return
RT_EOK
;
}
/**
* @brief Close the serial device.
* @param dev The pointer of device driver structure
* @return Return the status of the operation.
*/
static
rt_err_t
rt_serial_close
(
struct
rt_device
*
dev
)
{
struct
rt_serial_device
*
serial
;
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
/* this device has more reference count */
if
(
dev
->
ref_count
>
1
)
return
-
RT_ERROR
;
/* Disable serial receive mode. */
rt_serial_rx_disable
(
dev
,
dev
->
open_flag
&
(
RT_SERIAL_RX_BLOCKING
|
RT_SERIAL_RX_NON_BLOCKING
));
/* Disable serial tranmit mode. */
rt_serial_tx_disable
(
dev
,
dev
->
open_flag
&
(
RT_SERIAL_TX_BLOCKING
|
RT_SERIAL_TX_NON_BLOCKING
));
/* Call the control() API to close the serial device */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLOSE
,
RT_NULL
);
dev
->
flag
&=
~
RT_DEVICE_FLAG_ACTIVATED
;
return
RT_EOK
;
}
/**
* @brief Control the serial device.
* @param dev The pointer of device driver structure
* @param cmd The command value that controls the serial device
* @param args The parameter value that controls the serial device
* @return Return the status of the operation.
*/
static
rt_err_t
rt_serial_control
(
struct
rt_device
*
dev
,
int
cmd
,
void
*
args
)
{
rt_err_t
ret
=
RT_EOK
;
struct
rt_serial_device
*
serial
;
RT_ASSERT
(
dev
!=
RT_NULL
);
serial
=
(
struct
rt_serial_device
*
)
dev
;
switch
(
cmd
)
{
case
RT_DEVICE_CTRL_SUSPEND
:
/* suspend device */
dev
->
flag
|=
RT_DEVICE_FLAG_SUSPENDED
;
break
;
case
RT_DEVICE_CTRL_RESUME
:
/* resume device */
dev
->
flag
&=
~
RT_DEVICE_FLAG_SUSPENDED
;
break
;
case
RT_DEVICE_CTRL_CONFIG
:
if
(
args
!=
RT_NULL
)
{
struct
serial_configure
*
pconfig
=
(
struct
serial_configure
*
)
args
;
if
(
serial
->
parent
.
ref_count
)
{
/*can not change buffer size*/
return
-
RT_EBUSY
;
}
/* set serial configure */
serial
->
config
=
*
pconfig
;
serial
->
ops
->
configure
(
serial
,
(
struct
serial_configure
*
)
args
);
}
break
;
default
:
/* control device */
ret
=
serial
->
ops
->
control
(
serial
,
cmd
,
args
);
break
;
}
return
ret
;
}
#ifdef RT_USING_DEVICE_OPS
const
static
struct
rt_device_ops
serial_ops
=
{
rt_serial_init
,
rt_serial_open
,
rt_serial_close
,
rt_serial_read
,
rt_serial_write
,
rt_serial_control
};
#endif
/**
* @brief Register the serial device.
* @param serial RT-thread serial device.
* @param name The device driver's name
* @param flag The capabilities flag of device.
* @param data The device driver's data.
* @return Return the status of the operation.
*/
rt_err_t
rt_hw_serial_register
(
struct
rt_serial_device
*
serial
,
const
char
*
name
,
rt_uint32_t
flag
,
void
*
data
)
{
rt_err_t
ret
;
struct
rt_device
*
device
;
RT_ASSERT
(
serial
!=
RT_NULL
);
device
=
&
(
serial
->
parent
);
device
->
type
=
RT_Device_Class_Char
;
device
->
rx_indicate
=
RT_NULL
;
device
->
tx_complete
=
RT_NULL
;
#ifdef RT_USING_DEVICE_OPS
device
->
ops
=
&
serial_ops
;
#else
device
->
init
=
rt_serial_init
;
device
->
open
=
rt_serial_open
;
device
->
close
=
rt_serial_close
;
device
->
read
=
RT_NULL
;
device
->
write
=
RT_NULL
;
device
->
control
=
rt_serial_control
;
#endif
device
->
user_data
=
data
;
/* register a character device */
ret
=
rt_device_register
(
device
,
name
,
flag
);
#if defined(RT_USING_POSIX)
/* set fops */
device
->
fops
=
&
_serial_fops
;
#endif
return
ret
;
}
/**
* @brief ISR for serial interrupt
* @param serial RT-thread serial device.
* @param event ISR event type.
*/
void
rt_hw_serial_isr
(
struct
rt_serial_device
*
serial
,
int
event
)
{
RT_ASSERT
(
serial
!=
RT_NULL
);
switch
(
event
&
0xff
)
{
/* Interrupt receive event */
case
RT_SERIAL_EVENT_RX_IND
:
case
RT_SERIAL_EVENT_RX_DMADONE
:
{
struct
rt_serial_rx_fifo
*
rx_fifo
;
rt_size_t
rx_length
=
0
;
rx_fifo
=
(
struct
rt_serial_rx_fifo
*
)
serial
->
serial_rx
;
RT_ASSERT
(
rx_fifo
!=
RT_NULL
);
/* Get the length of the data from the ringbuffer */
rx_length
=
rt_ringbuffer_data_len
(
&
rx_fifo
->
rb
);
if
(
rx_length
==
0
)
break
;
if
(
serial
->
parent
.
open_flag
&
RT_SERIAL_RX_BLOCKING
)
{
if
(
rx_fifo
->
rx_cpt_index
&&
rx_length
>=
rx_fifo
->
rx_cpt_index
)
{
rx_fifo
->
rx_cpt_index
=
0
;
rt_completion_done
(
&
(
rx_fifo
->
rx_cpt
));
}
}
/* Trigger the receiving completion callback */
if
(
serial
->
parent
.
rx_indicate
!=
RT_NULL
)
serial
->
parent
.
rx_indicate
(
&
(
serial
->
parent
),
rx_length
);
break
;
}
/* Interrupt transmit event */
case
RT_SERIAL_EVENT_TX_DONE
:
{
struct
rt_serial_tx_fifo
*
tx_fifo
;
rt_size_t
tx_length
=
0
;
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
serial
->
serial_tx
;
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
/* Get the length of the data from the ringbuffer */
tx_length
=
rt_ringbuffer_data_len
(
&
tx_fifo
->
rb
);
/* If there is no data in tx_ringbuffer,
* then the transmit completion callback is triggered*/
if
(
tx_length
==
0
)
{
tx_fifo
->
activated
=
RT_FALSE
;
/* Trigger the transmit completion callback */
if
(
serial
->
parent
.
tx_complete
!=
RT_NULL
)
serial
->
parent
.
tx_complete
(
&
serial
->
parent
,
RT_NULL
);
if
(
serial
->
parent
.
open_flag
&
RT_SERIAL_TX_BLOCKING
)
rt_completion_done
(
&
(
tx_fifo
->
tx_cpt
));
break
;
}
/* Call the transmit interface for transmission again */
/* Note that in interrupt mode, tx_fifo->buffer and tx_length
* are inactive parameters */
serial
->
ops
->
transmit
(
serial
,
tx_fifo
->
buffer
,
tx_length
,
serial
->
parent
.
open_flag
&
(
\
RT_SERIAL_TX_BLOCKING
|
\
RT_SERIAL_TX_NON_BLOCKING
));
break
;
}
case
RT_SERIAL_EVENT_TX_DMADONE
:
{
struct
rt_serial_tx_fifo
*
tx_fifo
;
tx_fifo
=
(
struct
rt_serial_tx_fifo
*
)
serial
->
serial_tx
;
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
tx_fifo
->
activated
=
RT_FALSE
;
/* Trigger the transmit completion callback */
if
(
serial
->
parent
.
tx_complete
!=
RT_NULL
)
serial
->
parent
.
tx_complete
(
&
serial
->
parent
,
RT_NULL
);
if
(
serial
->
parent
.
open_flag
&
RT_SERIAL_TX_BLOCKING
)
{
rt_completion_done
(
&
(
tx_fifo
->
tx_cpt
));
break
;
}
rt_serial_update_read_index
(
&
tx_fifo
->
rb
,
tx_fifo
->
put_size
);
/* Get the length of the data from the ringbuffer.
* If there is some data in tx_ringbuffer,
* then call the transmit interface for transmission again */
if
(
rt_ringbuffer_data_len
(
&
tx_fifo
->
rb
))
{
tx_fifo
->
activated
=
RT_TRUE
;
rt_uint8_t
*
put_ptr
=
RT_NULL
;
/* Get the linear length buffer from rinbuffer */
tx_fifo
->
put_size
=
rt_serial_get_linear_buffer
(
&
(
tx_fifo
->
rb
),
&
put_ptr
);
/* Call the transmit interface for transmission again */
serial
->
ops
->
transmit
(
serial
,
put_ptr
,
tx_fifo
->
put_size
,
RT_SERIAL_TX_NON_BLOCKING
);
}
break
;
}
default:
break
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录