Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2301_76519099
rt-thread
提交
bb28784a
R
rt-thread
项目概览
2301_76519099
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
3
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bb28784a
编写于
2月 09, 2021
作者:
S
sheltonyu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1.add can and on-chip-flash drivers 2.fixed c++ compiler error
上级
68df79e8
变更
16
显示空白变更内容
内联
并排
Showing
16 changed file
with
1337 addition
and
8 deletion
+1337
-8
bsp/at32/Libraries/AT32_Std_Driver/AT32F4xx_StdPeriph_Driver/inc/at32f4xx_ertc.h
..._Std_Driver/AT32F4xx_StdPeriph_Driver/inc/at32f4xx_ertc.h
+3
-0
bsp/at32/Libraries/rt_drivers/SConscript
bsp/at32/Libraries/rt_drivers/SConscript
+6
-0
bsp/at32/Libraries/rt_drivers/drv_can.c
bsp/at32/Libraries/rt_drivers/drv_can.c
+878
-0
bsp/at32/Libraries/rt_drivers/drv_can.h
bsp/at32/Libraries/rt_drivers/drv_can.h
+58
-0
bsp/at32/Libraries/rt_drivers/drv_flash.c
bsp/at32/Libraries/rt_drivers/drv_flash.c
+210
-0
bsp/at32/Libraries/rt_drivers/drv_flash.h
bsp/at32/Libraries/rt_drivers/drv_flash.h
+30
-0
bsp/at32/at32f403a-start/README.md
bsp/at32/at32f403a-start/README.md
+6
-0
bsp/at32/at32f403a-start/board/Kconfig
bsp/at32/at32f403a-start/board/Kconfig
+17
-0
bsp/at32/at32f403a-start/board/board.h
bsp/at32/at32f403a-start/board/board.h
+7
-0
bsp/at32/at32f403a-start/board/msp/at32_msp.c
bsp/at32/at32f403a-start/board/msp/at32_msp.c
+43
-2
bsp/at32/at32f403a-start/board/msp/at32_msp.h
bsp/at32/at32f403a-start/board/msp/at32_msp.h
+3
-2
bsp/at32/at32f407-start/README.md
bsp/at32/at32f407-start/README.md
+6
-0
bsp/at32/at32f407-start/board/Kconfig
bsp/at32/at32f407-start/board/Kconfig
+17
-0
bsp/at32/at32f407-start/board/board.h
bsp/at32/at32f407-start/board/board.h
+7
-0
bsp/at32/at32f407-start/board/msp/at32_msp.c
bsp/at32/at32f407-start/board/msp/at32_msp.c
+43
-2
bsp/at32/at32f407-start/board/msp/at32_msp.h
bsp/at32/at32f407-start/board/msp/at32_msp.h
+3
-2
未找到文件。
bsp/at32/Libraries/AT32_Std_Driver/AT32F4xx_StdPeriph_Driver/inc/at32f4xx_ertc.h
浏览文件 @
bb28784a
...
...
@@ -11,6 +11,9 @@
#ifndef __AT32F4xx_ERTC_H
#define __AT32F4xx_ERTC_H
#ifdef __cplusplus
extern
"C"
{
#endif
/* Includes ------------------------------------------------------------------*/
#include "at32f4xx.h"
...
...
bsp/at32/Libraries/rt_drivers/SConscript
浏览文件 @
bb28784a
...
...
@@ -43,9 +43,15 @@ if GetDepend('BSP_USING_SRAM'):
if
GetDepend
(
'BSP_USING_RTC'
):
src
+=
[
'drv_rtc.c'
]
if
GetDepend
(
'BSP_USING_ON_CHIP_FLASH'
):
src
+=
[
'drv_flash.c'
]
if
GetDepend
([
'BSP_USING_WDT'
]):
src
+=
[
'drv_wdt.c'
]
if
GetDepend
([
'BSP_USING_CAN'
]):
src
+=
[
'drv_can.c'
]
if
GetDepend
([
'BSP_USING_SDIO'
]):
src
+=
[
'drv_sdio.c'
]
...
...
bsp/at32/Libraries/rt_drivers/drv_can.c
0 → 100644
浏览文件 @
bb28784a
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-09 shelton the first version
*/
#include "drv_can.h"
#ifdef BSP_USING_CAN
#define LOG_TAG "drv_can"
#include <drv_log.h>
/* attention !!! baud calculation example: apbclk / ((ss + bs1 + bs2) * brp), ep: 120 / ((1 + 8 + 3) * 10) = 1MHz*/
static
const
struct
at32_baud_rate_tab
can_baud_rate_tab
[]
=
{
{
CAN1MBaud
,
CAN_SJW_2tq
,
CAN_BS1_8tq
,
CAN_BS2_3tq
,
10
},
{
CAN800kBaud
,
CAN_SJW_2tq
,
CAN_BS1_7tq
,
CAN_BS2_2tq
,
15
},
{
CAN500kBaud
,
CAN_SJW_2tq
,
CAN_BS1_9tq
,
CAN_BS2_2tq
,
20
},
{
CAN250kBaud
,
CAN_SJW_2tq
,
CAN_BS1_9tq
,
CAN_BS2_2tq
,
40
},
{
CAN125kBaud
,
CAN_SJW_2tq
,
CAN_BS1_9tq
,
CAN_BS2_2tq
,
80
},
{
CAN100kBaud
,
CAN_SJW_2tq
,
CAN_BS1_13tq
,
CAN_BS2_2tq
,
75
},
{
CAN50kBaud
,
CAN_SJW_2tq
,
CAN_BS1_13tq
,
CAN_BS2_2tq
,
150
},
{
CAN20kBaud
,
CAN_SJW_2tq
,
CAN_BS1_13tq
,
CAN_BS2_2tq
,
375
},
{
CAN10kBaud
,
CAN_SJW_2tq
,
CAN_BS1_13tq
,
CAN_BS2_2tq
,
750
}
};
#ifdef BSP_USING_CAN1
static
struct
at32_can
can_instance1
=
{
.
name
=
"can1"
,
.
CanConfig
.
Instance
=
CAN1
,
};
#endif
#ifdef BSP_USING_CAN2
static
struct
at32_can
can_instance2
=
{
.
name
=
"can2"
,
.
CanConfig
.
Instance
=
CAN2
,
};
#endif
static
rt_uint32_t
get_can_baud_index
(
rt_uint32_t
baud
)
{
rt_uint32_t
len
,
index
;
len
=
sizeof
(
can_baud_rate_tab
)
/
sizeof
(
can_baud_rate_tab
[
0
]);
for
(
index
=
0
;
index
<
len
;
index
++
)
{
if
(
can_baud_rate_tab
[
index
].
baud_rate
==
baud
)
return
index
;
}
return
0
;
/* default baud is CAN1MBaud */
}
static
rt_err_t
_can_config
(
struct
rt_can_device
*
can
,
struct
can_configure
*
cfg
)
{
struct
at32_can
*
can_instance
;
rt_uint32_t
baud_index
;
RT_ASSERT
(
can
);
RT_ASSERT
(
cfg
);
can_instance
=
(
struct
at32_can
*
)
can
->
parent
.
user_data
;
RT_ASSERT
(
can_instance
);
at32_msp_can_init
((
void
*
)
can_instance
->
CanConfig
.
Instance
);
CAN_StructInit
(
&
(
can_instance
->
CanConfig
.
CanInit
));
can_instance
->
CanConfig
.
CanInit
.
CAN_Mode
=
DISABLE
;
can_instance
->
CanConfig
.
CanInit
.
CAN_ABO
=
ENABLE
;
can_instance
->
CanConfig
.
CanInit
.
CAN_AWU
=
ENABLE
;
can_instance
->
CanConfig
.
CanInit
.
CAN_NART
=
DISABLE
;
can_instance
->
CanConfig
.
CanInit
.
CAN_RFL
=
DISABLE
;
can_instance
->
CanConfig
.
CanInit
.
CAN_TFP
=
ENABLE
;
switch
(
cfg
->
mode
)
{
case
RT_CAN_MODE_NORMAL
:
can_instance
->
CanConfig
.
CanInit
.
CAN_Mode
=
CAN_Mode_Normal
;
break
;
case
RT_CAN_MODE_LISEN
:
can_instance
->
CanConfig
.
CanInit
.
CAN_Mode
=
CAN_Mode_Silent
;
break
;
case
RT_CAN_MODE_LOOPBACK
:
can_instance
->
CanConfig
.
CanInit
.
CAN_Mode
=
CAN_Mode_LoopBack
;
break
;
case
RT_CAN_MODE_LOOPBACKANLISEN
:
can_instance
->
CanConfig
.
CanInit
.
CAN_Mode
=
CAN_Mode_Silent_LoopBack
;
break
;
}
baud_index
=
get_can_baud_index
(
cfg
->
baud_rate
);
can_instance
->
CanConfig
.
CanInit
.
CAN_SJW
=
can_baud_rate_tab
[
baud_index
].
sjw
;
can_instance
->
CanConfig
.
CanInit
.
CAN_BS1
=
can_baud_rate_tab
[
baud_index
].
bs1
;
can_instance
->
CanConfig
.
CanInit
.
CAN_BS2
=
can_baud_rate_tab
[
baud_index
].
bs2
;
can_instance
->
CanConfig
.
CanInit
.
CAN_Prescaler
=
can_baud_rate_tab
[
baud_index
].
psc
;
/* init can */
if
(
CAN_Init
(
can_instance
->
CanConfig
.
Instance
,
&
(
can_instance
->
CanConfig
.
CanInit
))
!=
CAN_InitStatus_Success
)
{
return
-
RT_ERROR
;
}
/* default filter config */
CAN_FilterInit
(
can_instance
->
CanConfig
.
Instance
,
&
can_instance
->
CanConfig
.
FilterConfig
);
return
RT_EOK
;
}
static
rt_err_t
_can_control
(
struct
rt_can_device
*
can
,
int
cmd
,
void
*
arg
)
{
rt_uint32_t
argval
;
NVIC_InitType
NVIC_InitStruct
;
struct
at32_can
*
can_instance
;
struct
rt_can_filter_config
*
filter_cfg
;
RT_ASSERT
(
can
!=
RT_NULL
);
can_instance
=
(
struct
at32_can
*
)
can
->
parent
.
user_data
;
RT_ASSERT
(
can_instance
!=
RT_NULL
);
switch
(
cmd
)
{
case
RT_DEVICE_CTRL_CLR_INT
:
argval
=
(
rt_uint32_t
)
arg
;
if
(
argval
==
RT_DEVICE_FLAG_INT_RX
)
{
if
(
CAN1
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
USB_LP_CAN1_RX0_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
DISABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN1_RX1_IRQn
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#ifdef CAN2
if
(
CAN2
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN2_RX0_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
DISABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN2_RX1_IRQn
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#endif
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFP0
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFFU0
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFOV0
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFP1
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFFU1
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFOV1
,
DISABLE
);
}
else
if
(
argval
==
RT_DEVICE_FLAG_INT_TX
)
{
if
(
CAN1
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
USB_HP_CAN1_TX_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
DISABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#ifdef CAN2
if
(
CAN2
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN2_TX_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
DISABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#endif
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_TSME
,
DISABLE
);
}
else
if
(
argval
==
RT_DEVICE_CAN_INT_ERR
)
{
if
(
CAN1
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN1_SCE_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
DISABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#ifdef CAN2
if
(
CAN2
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN2_SCE_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
DISABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#endif
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_ERG
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_ERP
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_BU
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_LEC
,
DISABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_ERR
,
DISABLE
);
}
break
;
case
RT_DEVICE_CTRL_SET_INT
:
argval
=
(
rt_uint32_t
)
arg
;
if
(
argval
==
RT_DEVICE_FLAG_INT_RX
)
{
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFP0
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFFU0
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFOV0
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFP1
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFFU1
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_RFOV1
,
ENABLE
);
if
(
CAN1
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
USB_LP_CAN1_RX0_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN1_RX1_IRQn
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#ifdef CAN2
if
(
CAN2
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN2_RX0_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN2_RX1_IRQn
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#endif
}
else
if
(
argval
==
RT_DEVICE_FLAG_INT_TX
)
{
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_TSME
,
ENABLE
);
if
(
CAN1
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
USB_HP_CAN1_TX_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#ifdef CAN2
if
(
CAN2
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN2_TX_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#endif
}
else
if
(
argval
==
RT_DEVICE_CAN_INT_ERR
)
{
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_ERG
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_ERP
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_BU
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_LEC
,
ENABLE
);
CAN_INTConfig
(
can_instance
->
CanConfig
.
Instance
,
CAN_INT_ERR
,
ENABLE
);
if
(
CAN1
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN1_SCE_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#ifdef CAN2
if
(
CAN2
==
can_instance
->
CanConfig
.
Instance
)
{
NVIC_InitStruct
.
NVIC_IRQChannel
=
CAN2_SCE_IRQn
;
NVIC_InitStruct
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_InitStruct
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStruct
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_Init
(
&
NVIC_InitStruct
);
}
#endif
}
break
;
case
RT_CAN_CMD_SET_FILTER
:
if
(
RT_NULL
==
arg
)
{
/* default filter config */
CAN_FilterInit
(
can_instance
->
CanConfig
.
Instance
,
&
can_instance
->
CanConfig
.
FilterConfig
);
}
else
{
filter_cfg
=
(
struct
rt_can_filter_config
*
)
arg
;
/* get default filter */
for
(
int
i
=
0
;
i
<
filter_cfg
->
count
;
i
++
)
{
can_instance
->
CanConfig
.
FilterConfig
.
CAN_FilterNumber
=
filter_cfg
->
items
[
i
].
hdr
&
(
0x1fU
);
can_instance
->
CanConfig
.
FilterConfig
.
CAN_FilterIdHigh
=
(
filter_cfg
->
items
[
i
].
id
>>
13
)
&
0xFFFF
;
can_instance
->
CanConfig
.
FilterConfig
.
CAN_FilterIdLow
=
((
filter_cfg
->
items
[
i
].
id
<<
3
)
|
(
filter_cfg
->
items
[
i
].
ide
<<
2
)
|
(
filter_cfg
->
items
[
i
].
rtr
<<
1
))
&
0xFFFF
;
can_instance
->
CanConfig
.
FilterConfig
.
CAN_FilterMskIdHigh
=
(
filter_cfg
->
items
[
i
].
mask
>>
16
)
&
0xFFFF
;
can_instance
->
CanConfig
.
FilterConfig
.
CAN_FilterMskIdLow
=
filter_cfg
->
items
[
i
].
mask
&
0xFFFF
;
can_instance
->
CanConfig
.
FilterConfig
.
CAN_FilterMode
=
filter_cfg
->
items
[
i
].
mode
;
/* Filter conf */
CAN_FilterInit
(
can_instance
->
CanConfig
.
Instance
,
&
can_instance
->
CanConfig
.
FilterConfig
);
}
}
break
;
case
RT_CAN_CMD_SET_MODE
:
argval
=
(
rt_uint32_t
)
arg
;
if
(
argval
!=
RT_CAN_MODE_NORMAL
&&
argval
!=
RT_CAN_MODE_LISEN
&&
argval
!=
RT_CAN_MODE_LOOPBACK
&&
argval
!=
RT_CAN_MODE_LOOPBACKANLISEN
)
{
return
-
RT_ERROR
;
}
if
(
argval
!=
can_instance
->
device
.
config
.
mode
)
{
can_instance
->
device
.
config
.
mode
=
argval
;
return
_can_config
(
&
can_instance
->
device
,
&
can_instance
->
device
.
config
);
}
break
;
case
RT_CAN_CMD_SET_BAUD
:
argval
=
(
rt_uint32_t
)
arg
;
if
(
argval
!=
CAN1MBaud
&&
argval
!=
CAN800kBaud
&&
argval
!=
CAN500kBaud
&&
argval
!=
CAN250kBaud
&&
argval
!=
CAN125kBaud
&&
argval
!=
CAN100kBaud
&&
argval
!=
CAN50kBaud
&&
argval
!=
CAN20kBaud
&&
argval
!=
CAN10kBaud
)
{
return
-
RT_ERROR
;
}
if
(
argval
!=
can_instance
->
device
.
config
.
baud_rate
)
{
can_instance
->
device
.
config
.
baud_rate
=
argval
;
return
_can_config
(
&
can_instance
->
device
,
&
can_instance
->
device
.
config
);
}
break
;
case
RT_CAN_CMD_SET_PRIV
:
argval
=
(
rt_uint32_t
)
arg
;
if
(
argval
!=
RT_CAN_MODE_PRIV
&&
argval
!=
RT_CAN_MODE_NOPRIV
)
{
return
-
RT_ERROR
;
}
if
(
argval
!=
can_instance
->
device
.
config
.
privmode
)
{
can_instance
->
device
.
config
.
privmode
=
argval
;
return
_can_config
(
&
can_instance
->
device
,
&
can_instance
->
device
.
config
);
}
break
;
case
RT_CAN_CMD_GET_STATUS
:
{
rt_uint32_t
errtype
;
errtype
=
can_instance
->
CanConfig
.
Instance
->
ESTS
;
can_instance
->
device
.
status
.
rcverrcnt
=
errtype
>>
24
;
can_instance
->
device
.
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
can_instance
->
device
.
status
.
lasterrtype
=
errtype
&
0x70
;
can_instance
->
device
.
status
.
errcode
=
errtype
&
0x07
;
rt_memcpy
(
arg
,
&
can_instance
->
device
.
status
,
sizeof
(
can_instance
->
device
.
status
));
}
break
;
}
return
RT_EOK
;
}
static
int
_can_sendmsg
(
struct
rt_can_device
*
can
,
const
void
*
buf
,
rt_uint32_t
box_num
)
{
struct
CAN_Handler
*
hcan
;
hcan
=
&
((
struct
at32_can
*
)
can
->
parent
.
user_data
)
->
CanConfig
;
struct
rt_can_msg
*
pmsg
=
(
struct
rt_can_msg
*
)
buf
;
CanTxMsg
TxMessage
;
rt_uint32_t
i
;
/* Check the parameters */
RT_ASSERT
(
IS_CAN_DLC
(
pmsg
->
len
));
/*check select mailbox is empty */
switch
(
1
<<
box_num
)
{
case
CAN_TX_MAILBOX0
:
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TSME0
)
!=
CAN_TSTS_TSME0
)
{
/* Return function status */
return
-
RT_ERROR
;
}
break
;
case
CAN_TX_MAILBOX1
:
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TSME1
)
!=
CAN_TSTS_TSME1
)
{
/* Return function status */
return
-
RT_ERROR
;
}
break
;
case
CAN_TX_MAILBOX2
:
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TSME2
)
!=
CAN_TSTS_TSME2
)
{
/* Return function status */
return
-
RT_ERROR
;
}
break
;
default:
RT_ASSERT
(
0
);
break
;
}
if
(
RT_CAN_STDID
==
pmsg
->
ide
)
{
TxMessage
.
IDT
=
CAN_ID_STD
;
RT_ASSERT
(
IS_CAN_STDID
(
pmsg
->
id
));
TxMessage
.
StdId
=
pmsg
->
id
;
}
else
{
TxMessage
.
IDT
=
CAN_ID_EXT
;
RT_ASSERT
(
IS_CAN_EXTID
(
pmsg
->
id
));
TxMessage
.
ExtId
=
pmsg
->
id
;
}
if
(
RT_CAN_DTR
==
pmsg
->
rtr
)
{
TxMessage
.
RTR
=
CAN_RTR_DATA
;
}
else
{
TxMessage
.
RTR
=
CAN_RTR_REMOTE
;
}
/* Set up the DLC */
TxMessage
.
DLC
=
pmsg
->
len
&
0x0FU
;
/* Set up the data field */
TxMessage
.
Data
[
0
]
=
(
uint32_t
)
pmsg
->
data
[
0
];
TxMessage
.
Data
[
1
]
=
(
uint32_t
)
pmsg
->
data
[
1
];
TxMessage
.
Data
[
2
]
=
(
uint32_t
)
pmsg
->
data
[
2
];
TxMessage
.
Data
[
3
]
=
(
uint32_t
)
pmsg
->
data
[
3
];
TxMessage
.
Data
[
4
]
=
(
uint32_t
)
pmsg
->
data
[
4
];
TxMessage
.
Data
[
5
]
=
(
uint32_t
)
pmsg
->
data
[
5
];
TxMessage
.
Data
[
6
]
=
(
uint32_t
)
pmsg
->
data
[
6
];
TxMessage
.
Data
[
7
]
=
(
uint32_t
)
pmsg
->
data
[
7
];
CAN_Transmit
(
hcan
->
Instance
,
&
TxMessage
);
while
((
CAN_TransmitStatus
(
hcan
->
Instance
,
box_num
)
!=
CANTXOK
)
&&
(
i
!=
0xFFFF
))
{
i
++
;
}
return
RT_EOK
;
}
static
int
_can_recvmsg
(
struct
rt_can_device
*
can
,
void
*
buf
,
rt_uint32_t
fifo
)
{
struct
CAN_Handler
*
hcan
;
hcan
=
&
((
struct
at32_can
*
)
can
->
parent
.
user_data
)
->
CanConfig
;
struct
rt_can_msg
*
pmsg
=
(
struct
rt_can_msg
*
)
buf
;
CanRxMsg
RxMessage
;
RT_ASSERT
(
can
);
/* get data */
CAN_Receive
(
hcan
->
Instance
,
fifo
,
&
RxMessage
);
pmsg
->
data
[
0
]
=
RxMessage
.
Data
[
0
];
pmsg
->
data
[
1
]
=
RxMessage
.
Data
[
1
];
pmsg
->
data
[
2
]
=
RxMessage
.
Data
[
2
];
pmsg
->
data
[
3
]
=
RxMessage
.
Data
[
3
];
pmsg
->
data
[
4
]
=
RxMessage
.
Data
[
4
];
pmsg
->
data
[
5
]
=
RxMessage
.
Data
[
5
];
pmsg
->
data
[
6
]
=
RxMessage
.
Data
[
6
];
pmsg
->
data
[
7
]
=
RxMessage
.
Data
[
7
];
pmsg
->
len
=
RxMessage
.
DLC
;
pmsg
->
id
=
RxMessage
.
IDT
;
if
(
RxMessage
.
IDT
==
CAN_ID_STD
)
pmsg
->
id
=
RxMessage
.
StdId
;
else
pmsg
->
ide
=
RxMessage
.
ExtId
;
pmsg
->
rtr
=
RxMessage
.
RTR
;
return
RT_EOK
;
}
static
const
struct
rt_can_ops
_can_ops
=
{
_can_config
,
_can_control
,
_can_sendmsg
,
_can_recvmsg
,
};
static
void
_can_rx_isr
(
struct
rt_can_device
*
can
,
rt_uint32_t
fifo
)
{
struct
CAN_Handler
*
hcan
;
RT_ASSERT
(
can
);
hcan
=
&
((
struct
at32_can
*
)
can
->
parent
.
user_data
)
->
CanConfig
;
switch
(
fifo
)
{
case
CAN_FIFO0
:
/* save to user list */
if
(
CAN_MessagePending
(
hcan
->
Instance
,
CAN_FIFO0
)
&&
CAN_GetINTStatus
(
hcan
->
Instance
,
CAN_INT_RFP0
))
{
rt_hw_can_isr
(
can
,
RT_CAN_EVENT_RX_IND
|
fifo
<<
8
);
}
/* Check FULL flag for FIFO0 */
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RFFU0
)
&&
CAN_GetINTStatus
(
hcan
->
Instance
,
CAN_INT_RFFU0
))
{
/* Clear FIFO0 FULL Flag */
CAN_ClearFlag
(
hcan
->
Instance
,
CAN_FLAG_RFFU0
);
}
/* Check Overrun flag for FIFO0 */
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RFOV0
)
&&
CAN_GetINTStatus
(
hcan
->
Instance
,
CAN_INT_RFOV0
))
{
/* Clear FIFO0 Overrun Flag */
CAN_ClearFlag
(
hcan
->
Instance
,
CAN_FLAG_RFOV0
);
rt_hw_can_isr
(
can
,
RT_CAN_EVENT_RXOF_IND
|
fifo
<<
8
);
}
break
;
case
CAN_FIFO1
:
/* save to user list */
if
(
CAN_MessagePending
(
hcan
->
Instance
,
CAN_FIFO1
)
&&
CAN_GetINTStatus
(
hcan
->
Instance
,
CAN_INT_RFP1
))
{
rt_hw_can_isr
(
can
,
RT_CAN_EVENT_RX_IND
|
fifo
<<
8
);
}
/* Check FULL flag for FIFO1 */
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RFFU1
)
&&
CAN_GetINTStatus
(
hcan
->
Instance
,
CAN_INT_RFFU1
))
{
/* Clear FIFO1 FULL Flag */
CAN_ClearFlag
(
hcan
->
Instance
,
CAN_FLAG_RFFU1
);
}
/* Check Overrun flag for FIFO1 */
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RFOV1
)
&&
CAN_GetINTStatus
(
hcan
->
Instance
,
CAN_INT_RFOV1
))
{
/* Clear FIFO1 Overrun Flag */
CAN_ClearFlag
(
hcan
->
Instance
,
CAN_FLAG_RFOV1
);
rt_hw_can_isr
(
can
,
RT_CAN_EVENT_RXOF_IND
|
fifo
<<
8
);
}
break
;
}
}
#ifdef BSP_USING_CAN1
/**
* @brief This function handles CAN1 TX interrupts. transmit fifo0/1/2 is empty can trigger this interrupt
*/
void
USB_HP_CAN1_TX_IRQHandler
(
void
)
{
rt_interrupt_enter
();
struct
CAN_Handler
*
hcan
;
hcan
=
&
can_instance1
.
CanConfig
;
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RQCP0
))
{
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TOK0
)
==
CAN_TSTS_TOK0
)
{
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_DONE
|
0
<<
8
);
}
else
{
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
hcan
->
Instance
->
TSTS
|=
CAN_TSTS_RQC0
;
}
else
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RQCP1
))
{
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TOK1
)
==
CAN_TSTS_TOK1
)
{
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_DONE
|
1
<<
8
);
}
else
{
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
hcan
->
Instance
->
TSTS
|=
CAN_TSTS_RQC1
;
}
else
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RQCP2
))
{
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TOK2
)
==
CAN_TSTS_TOK2
)
{
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_DONE
|
2
<<
8
);
}
else
{
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
hcan
->
Instance
->
TSTS
|=
CAN_TSTS_RQC2
;
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 RX0 interrupts.
*/
void
USB_LP_CAN1_RX0_IRQHandler
(
void
)
{
rt_interrupt_enter
();
_can_rx_isr
(
&
can_instance1
.
device
,
CAN_FIFO0
);
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 RX1 interrupts.
*/
void
CAN1_RX1_IRQHandler
(
void
)
{
rt_interrupt_enter
();
_can_rx_isr
(
&
can_instance1
.
device
,
CAN_FIFO1
);
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 SCE interrupts.
*/
void
CAN1_SCE_IRQHandler
(
void
)
{
rt_uint32_t
errtype
;
struct
CAN_Handler
*
hcan
;
hcan
=
&
can_instance1
.
CanConfig
;
errtype
=
hcan
->
Instance
->
ESTS
;
rt_interrupt_enter
();
switch
((
errtype
&
0x70
)
>>
4
)
{
case
RT_CAN_BUS_BIT_PAD_ERR
:
can_instance1
.
device
.
status
.
bitpaderrcnt
++
;
break
;
case
RT_CAN_BUS_FORMAT_ERR
:
can_instance1
.
device
.
status
.
formaterrcnt
++
;
break
;
case
RT_CAN_BUS_ACK_ERR
:
/* attention !!! test ack err's unit is transmit unit */
can_instance1
.
device
.
status
.
ackerrcnt
++
;
if
(
!
(
can_instance1
.
CanConfig
.
Instance
->
TSTS
&
CAN_TSTS_TOK0
))
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
else
if
(
!
(
can_instance1
.
CanConfig
.
Instance
->
TSTS
&
CAN_TSTS_TOK0
))
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
else
if
(
!
(
can_instance1
.
CanConfig
.
Instance
->
TSTS
&
CAN_TSTS_TOK0
))
rt_hw_can_isr
(
&
can_instance1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
break
;
case
RT_CAN_BUS_IMPLICIT_BIT_ERR
:
case
RT_CAN_BUS_EXPLICIT_BIT_ERR
:
can_instance1
.
device
.
status
.
biterrcnt
++
;
break
;
case
RT_CAN_BUS_CRC_ERR
:
can_instance1
.
device
.
status
.
crcerrcnt
++
;
break
;
}
can_instance1
.
device
.
status
.
lasterrtype
=
errtype
&
0x70
;
can_instance1
.
device
.
status
.
rcverrcnt
=
errtype
>>
24
;
can_instance1
.
device
.
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
can_instance1
.
device
.
status
.
errcode
=
errtype
&
0x07
;
hcan
->
Instance
->
MSTS
|=
CAN_MSTS_ERIT
;
rt_interrupt_leave
();
}
#endif
/* BSP_USING_CAN1 */
#ifdef BSP_USING_CAN2
/**
* @brief This function handles CAN2 TX interrupts.
*/
void
CAN2_TX_IRQHandler
(
void
)
{
rt_interrupt_enter
();
struct
CAN_Handler
*
hcan
;
hcan
=
&
can_instance2
.
CanConfig
;
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RQCP0
))
{
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TOK0
)
==
CAN_TSTS_TOK0
)
{
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_DONE
|
0
<<
8
);
}
else
{
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
hcan
->
Instance
->
TSTS
|=
CAN_TSTS_RQC0
;
}
else
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RQCP1
))
{
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TOK1
)
==
CAN_TSTS_TOK1
)
{
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_DONE
|
1
<<
8
);
}
else
{
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
hcan
->
Instance
->
TSTS
|=
CAN_TSTS_RQC1
;
}
else
if
(
CAN_GetFlagStatus
(
hcan
->
Instance
,
CAN_FLAG_RQCP2
))
{
if
((
hcan
->
Instance
->
TSTS
&
CAN_TSTS_TOK2
)
==
CAN_TSTS_TOK2
)
{
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_DONE
|
2
<<
8
);
}
else
{
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
hcan
->
Instance
->
TSTS
|=
CAN_TSTS_RQC2
;
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 RX0 interrupts.
*/
void
CAN2_RX0_IRQHandler
(
void
)
{
rt_interrupt_enter
();
_can_rx_isr
(
&
can_instance2
.
device
,
CAN_FIFO0
);
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 RX1 interrupts.
*/
void
CAN2_RX1_IRQHandler
(
void
)
{
rt_interrupt_enter
();
_can_rx_isr
(
&
can_instance2
.
device
,
CAN_FIFO1
);
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 SCE interrupts.
*/
void
CAN2_SCE_IRQHandler
(
void
)
{
rt_uint32_t
errtype
;
struct
CAN_Handler
*
hcan
;
hcan
=
&
can_instance2
.
CanConfig
;
errtype
=
hcan
->
Instance
->
ESTS
;
rt_interrupt_enter
();
switch
((
errtype
&
0x70
)
>>
4
)
{
case
RT_CAN_BUS_BIT_PAD_ERR
:
can_instance2
.
device
.
status
.
bitpaderrcnt
++
;
break
;
case
RT_CAN_BUS_FORMAT_ERR
:
can_instance2
.
device
.
status
.
formaterrcnt
++
;
break
;
case
RT_CAN_BUS_ACK_ERR
:
can_instance2
.
device
.
status
.
ackerrcnt
++
;
if
(
!
(
can_instance1
.
CanConfig
.
Instance
->
TSTS
&
CAN_TSTS_TOK0
))
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
else
if
(
!
(
can_instance2
.
CanConfig
.
Instance
->
TSTS
&
CAN_TSTS_TOK0
))
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
else
if
(
!
(
can_instance2
.
CanConfig
.
Instance
->
TSTS
&
CAN_TSTS_TOK0
))
rt_hw_can_isr
(
&
can_instance2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
break
;
case
RT_CAN_BUS_IMPLICIT_BIT_ERR
:
case
RT_CAN_BUS_EXPLICIT_BIT_ERR
:
can_instance2
.
device
.
status
.
biterrcnt
++
;
break
;
case
RT_CAN_BUS_CRC_ERR
:
can_instance2
.
device
.
status
.
crcerrcnt
++
;
break
;
}
can_instance2
.
device
.
status
.
lasterrtype
=
errtype
&
0x70
;
can_instance2
.
device
.
status
.
rcverrcnt
=
errtype
>>
24
;
can_instance2
.
device
.
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
can_instance2
.
device
.
status
.
errcode
=
errtype
&
0x07
;
hcan
->
Instance
->
MSTS
|=
CAN_MSTS_ERIT
;
rt_interrupt_leave
();
}
#endif
/* BSP_USING_CAN2 */
/**
* @brief Error CAN callback.
* @param hcan pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.
* @retval None
*/
void
HAL_CAN_ErrorCallback
(
struct
CAN_Handler
*
hcan
)
{
CAN_INTConfig
(
hcan
->
Instance
,
CAN_INT_TSME
|
CAN_INT_RFP0
|
CAN_INT_RFFU0
|
CAN_INT_RFOV0
|
CAN_INT_RFP1
|
CAN_INT_RFFU1
|
CAN_INT_RFOV1
|
CAN_INT_ERG
|
CAN_INT_ERP
|
CAN_INT_LEC
|
CAN_INT_ERR
|
CAN_INT_WK
,
ENABLE
);
}
int
rt_hw_can_init
(
void
)
{
struct
can_configure
config
=
CANDEFAULTCONFIG
;
config
.
privmode
=
RT_CAN_MODE_NOPRIV
;
config
.
ticks
=
50
;
#ifdef RT_CAN_USING_HDR
config
.
maxhdr
=
14
;
#endif
/* config default filter */
CAN_FilterInitType
filterConf
=
{
0
};
filterConf
.
CAN_FilterIdHigh
=
0x0000
;
filterConf
.
CAN_FilterIdLow
=
0x0000
;
filterConf
.
CAN_FilterMskIdHigh
=
0x0000
;
filterConf
.
CAN_FilterMskIdLow
=
0x0000
;
filterConf
.
CAN_FilterFIFOAssignment
=
CAN_Filter_FIFO0
;
filterConf
.
CAN_FilterNumber
=
0
;
filterConf
.
CAN_FilterMode
=
CAN_FilterMode_IdMask
;
filterConf
.
CAN_FilterScale
=
CAN_FilterScale_32bit
;
filterConf
.
CAN_FilterActivation
=
ENABLE
;
#ifdef BSP_USING_CAN1
filterConf
.
CAN_FilterNumber
=
0
;
can_instance1
.
CanConfig
.
FilterConfig
=
filterConf
;
can_instance1
.
device
.
config
=
config
;
/* register CAN1 device */
rt_hw_can_register
(
&
can_instance1
.
device
,
can_instance1
.
name
,
&
_can_ops
,
&
can_instance1
);
#endif
/* BSP_USING_CAN1 */
#ifdef BSP_USING_CAN2
filterConf
.
CAN_FilterNumber
=
0
;
can_instance2
.
CanConfig
.
FilterConfig
=
filterConf
;
can_instance2
.
device
.
config
=
config
;
/* register CAN2 device */
rt_hw_can_register
(
&
can_instance2
.
device
,
can_instance2
.
name
,
&
_can_ops
,
&
can_instance2
);
#endif
/* BSP_USING_CAN2 */
return
0
;
}
INIT_BOARD_EXPORT
(
rt_hw_can_init
);
#endif
/* BSP_USING_CAN */
/************************** end of file ******************/
bsp/at32/Libraries/rt_drivers/drv_can.h
0 → 100644
浏览文件 @
bb28784a
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-09 shelton the first version
*/
#ifndef __DRV_CAN_H__
#define __DRV_CAN_H__
#ifdef __cplusplus
extern
"C"
{
#endif
#include <board.h>
#include <rtdevice.h>
#include <rtthread.h>
#define CAN_TX_MAILBOX0 (0x00000001U)
/*!< Tx Mailbox 0 */
#define CAN_TX_MAILBOX1 (0x00000002U)
/*!< Tx Mailbox 1 */
#define CAN_TX_MAILBOX2 (0x00000004U)
/*!< Tx Mailbox 2 */
struct
at32_baud_rate_tab
{
rt_uint32_t
baud_rate
;
rt_uint32_t
sjw
;
rt_uint32_t
bs1
;
rt_uint32_t
bs2
;
rt_uint32_t
psc
;
};
struct
CAN_Handler
{
CAN_Type
*
Instance
;
CAN_InitType
CanInit
;
CAN_FilterInitType
FilterConfig
;
};
/* at32 can device */
struct
at32_can
{
char
*
name
;
struct
CAN_Handler
CanConfig
;
struct
rt_can_device
device
;
/* inherit from can device */
};
int
rt_hw_can_init
(
void
);
#ifdef __cplusplus
}
#endif
#endif
/*__DRV_CAN_H__ */
/************************** end of file ******************/
bsp/at32/Libraries/rt_drivers/drv_flash.c
0 → 100644
浏览文件 @
bb28784a
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-09 shelton the first version
*/
#include <board.h>
#include <rtthread.h>
#ifdef BSP_USING_ON_CHIP_FLASH
#include "drv_flash.h"
#if defined(PKG_USING_FAL)
#include "fal.h"
#endif
//#define DRV_DEBUG
#define LOG_TAG "drv.flash"
#include <drv_log.h>
/**
* @brief Gets the page of a given address
* @param addr: address of the flash memory
* @retval The page of a given address
*/
static
rt_uint32_t
get_page
(
uint32_t
addr
)
{
rt_uint32_t
page
=
0
;
page
=
RT_ALIGN_DOWN
(
addr
,
FLASH_PAGE_SIZE
);
return
page
;
}
/**
* Read data from flash.
* @note This operation's units is word.
*
* @param addr flash address
* @param buf buffer to store read data
* @param size read bytes size
*
* @return result
*/
int
at32_flash_read
(
rt_uint32_t
addr
,
rt_uint8_t
*
buf
,
size_t
size
)
{
size_t
i
;
if
((
addr
+
size
)
>
AT32_FLASH_END_ADDRESS
)
{
LOG_E
(
"read outrange flash size! addr is (0x%p)"
,
(
void
*
)(
addr
+
size
));
return
-
RT_EINVAL
;
}
for
(
i
=
0
;
i
<
size
;
i
++
,
buf
++
,
addr
++
)
{
*
buf
=
*
(
rt_uint8_t
*
)
addr
;
}
return
size
;
}
/**
* Write data to flash.
* @note This operation's units is word.
* @note This operation must after erase. @see flash_erase.
*
* @param addr flash address
* @param buf the write data buffer
* @param size write bytes size
*
* @return result
*/
int
at32_flash_write
(
rt_uint32_t
addr
,
const
rt_uint8_t
*
buf
,
size_t
size
)
{
rt_err_t
result
=
RT_EOK
;
rt_uint32_t
end_addr
=
addr
+
size
;
if
(
addr
%
4
!=
0
)
{
LOG_E
(
"write addr must be 4-byte alignment"
);
return
-
RT_EINVAL
;
}
if
((
end_addr
)
>
AT32_FLASH_END_ADDRESS
)
{
LOG_E
(
"write outrange flash size! addr is (0x%p)"
,
(
void
*
)(
addr
+
size
));
return
-
RT_EINVAL
;
}
FLASH_Unlock
();
while
(
addr
<
end_addr
)
{
if
(
FLASH_ProgramWord
(
addr
,
*
((
rt_uint32_t
*
)
buf
))
==
FLASH_PRC_DONE
)
{
if
(
*
(
rt_uint32_t
*
)
addr
!=
*
(
rt_uint32_t
*
)
buf
)
{
result
=
-
RT_ERROR
;
break
;
}
addr
+=
4
;
buf
+=
4
;
}
else
{
result
=
-
RT_ERROR
;
break
;
}
}
FLASH_Lock
();
if
(
result
!=
RT_EOK
)
{
return
result
;
}
return
size
;
}
/**
* Erase data on flash .
* @note This operation is irreversible.
* @note This operation's units is different which on many chips.
*
* @param addr flash address
* @param size erase bytes size
*
* @return result
*/
int
at32_flash_erase
(
rt_uint32_t
addr
,
size_t
size
)
{
rt_err_t
result
=
RT_EOK
;
rt_uint32_t
end_addr
=
addr
+
size
;
rt_uint32_t
page_addr
=
0
;
FLASH_Unlock
();
if
((
end_addr
)
>
AT32_FLASH_END_ADDRESS
)
{
LOG_E
(
"erase outrange flash size! addr is (0x%p)"
,
(
void
*
)(
addr
+
size
));
return
-
RT_EINVAL
;
}
while
(
addr
<
end_addr
)
{
page_addr
=
get_page
(
addr
);
if
(
FLASH_ErasePage
(
page_addr
)
!=
FLASH_PRC_DONE
)
{
result
=
-
RT_ERROR
;
goto
__exit
;
}
addr
+=
FLASH_PAGE_SIZE
;
}
FLASH_Lock
();
__exit:
if
(
result
!=
RT_EOK
)
{
return
result
;
}
return
size
;
}
#if defined(PKG_USING_FAL)
static
int
fal_flash_read
(
long
offset
,
rt_uint8_t
*
buf
,
size_t
size
);
static
int
fal_flash_write
(
long
offset
,
const
rt_uint8_t
*
buf
,
size_t
size
);
static
int
fal_flash_erase
(
long
offset
,
size_t
size
);
const
struct
fal_flash_dev
at32_onchip_flash
=
{
"onchip_flash"
,
AT32_FLASH_START_ADRESS
,
AT32_FLASH_SIZE
,
FLASH_PAGE_SIZE
,
{
NULL
,
fal_flash_read
,
fal_flash_write
,
fal_flash_erase
}
};
static
int
fal_flash_read
(
long
offset
,
rt_uint8_t
*
buf
,
size_t
size
)
{
return
at32_flash_read
(
at32_onchip_flash
.
addr
+
offset
,
buf
,
size
);
}
static
int
fal_flash_write
(
long
offset
,
const
rt_uint8_t
*
buf
,
size_t
size
)
{
return
at32_flash_write
(
at32_onchip_flash
.
addr
+
offset
,
buf
,
size
);
}
static
int
fal_flash_erase
(
long
offset
,
size_t
size
)
{
return
at32_flash_erase
(
at32_onchip_flash
.
addr
+
offset
,
size
);
}
#endif
#endif
/* BSP_USING_ON_CHIP_FLASH */
bsp/at32/Libraries/rt_drivers/drv_flash.h
0 → 100644
浏览文件 @
bb28784a
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-09 shelton the first version
*/
#ifndef __DRV_FLASH_H__
#define __DRV_FLASH_H__
#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#ifdef __cplusplus
extern
"C"
{
#endif
int
at32_flash_read
(
rt_uint32_t
addr
,
rt_uint8_t
*
buf
,
size_t
size
);
int
at32_flash_write
(
rt_uint32_t
addr
,
const
rt_uint8_t
*
buf
,
size_t
size
);
int
at32_flash_erase
(
rt_uint32_t
addr
,
size_t
size
);
#ifdef __cplusplus
}
#endif
#endif
/* __DRV_FLASH_H__ */
bsp/at32/at32f403a-start/README.md
浏览文件 @
bb28784a
...
...
@@ -46,8 +46,10 @@ AT32F403A-START板级包支持MDK4﹑MDK5﹑IAR开发环境和GCC编译器,以
| PWM | 支持 | TMR1/2 |
| HWTIMER | 支持 | TMR3/4/5 |
| SDIO | 支持 | SDIO1 |
| CAN | 支持 | CAN1/2 |
| WDT | 支持 | |
| RTC | 支持 | |
| FLASH | 支持 | |
### IO在板级支持包中的映射情况
...
...
@@ -88,6 +90,10 @@ AT32F403A-START板级包支持MDK4﹑MDK5﹑IAR开发环境和GCC编译器,以
| PC3 | ADC1/2_IN13 |
| PC4 | ADC1/2_IN14 |
| PC5 | ADC1/2_IN15 |
| PA11 | CAN1_RX |
| PA12 | CAN1_TX |
| PB5 | CAN2_RX |
| PB6 | CAN2_TX |
## 使用说明
...
...
bsp/at32/at32f403a-start/board/Kconfig
浏览文件 @
bb28784a
...
...
@@ -24,6 +24,10 @@ menu "On-chip Peripheral Drivers"
select RT_USING_PIN
default y
config BSP_USING_ON_CHIP_FLASH
bool "Enable on-chip FLASH"
default n
menuconfig BSP_USING_RTC
bool "Enable RTC"
select RT_USING_RTC
...
...
@@ -151,6 +155,19 @@ menu "On-chip Peripheral Drivers"
default n
endif
menuconfig BSP_USING_CAN
bool "Enable CAN"
default n
select RT_USING_CAN
if BSP_USING_CAN
config BSP_USING_CAN1
bool "using CAN1"
default n
config BSP_USING_CAN2
bool "using CAN2"
default n
endif
menuconfig BSP_USING_SDIO
bool "Enable SDIO"
default n
...
...
bsp/at32/at32f403a-start/board/board.h
浏览文件 @
bb28784a
...
...
@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2020-01-15 shelton first version
* 2021-02-09 shelton add flash macros
*/
#ifndef __BOARD_H__
...
...
@@ -18,6 +19,12 @@
extern
"C"
{
#endif
/* Just only support for AT32F40xxG */
#define AT32_FLASH_START_ADRESS ((uint32_t)0x08000000)
#define FLASH_PAGE_SIZE (2 * 1024)
#define AT32_FLASH_SIZE (1024 * 1024)
#define AT32_FLASH_END_ADDRESS ((uint32_t)(AT32_FLASH_START_ADRESS + AT32_FLASH_SIZE))
/* Internal SRAM memory size[Kbytes] <96>, Default: 96*/
#define AT32_SRAM_SIZE 96
#define AT32_SRAM_END (0x20000000 + AT32_SRAM_SIZE * 1024)
...
...
bsp/at32/at32f403a-start/board/msp/at32_msp.c
浏览文件 @
bb28784a
...
...
@@ -2,8 +2,8 @@
******************************************************************************
* @file at32_msp.c
* @author Artery Technology
* @version V1.0.
0
* @date 202
0-01-10
* @version V1.0.
1
* @date 202
1-02-09
* @brief Msp source file
******************************************************************************
* @attention
...
...
@@ -256,3 +256,44 @@ void at32_msp_hwtmr_init(void *Instance)
#endif
}
#endif
#ifdef BSP_USING_CAN
void
at32_msp_can_init
(
void
*
Instance
)
{
GPIO_InitType
GPIO_InitStruct
;
CAN_Type
*
CANx
=
(
CAN_Type
*
)
Instance
;
GPIO_StructInit
(
&
GPIO_InitStruct
);
GPIO_InitStruct
.
GPIO_MaxSpeed
=
GPIO_MaxSpeed_50MHz
;
#ifdef BSP_USING_CAN1
if
(
CAN1
==
CANx
)
{
RCC_APB1PeriphClockCmd
(
RCC_APB1PERIPH_CAN1
,
ENABLE
);
RCC_APB2PeriphClockCmd
(
RCC_APB2PERIPH_GPIOA
,
ENABLE
);
GPIO_InitStruct
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_InitStruct
.
GPIO_Pins
=
GPIO_Pins_12
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_InitStruct
.
GPIO_Pins
=
GPIO_Pins_11
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStruct
);
}
#endif
#ifdef BSP_USING_CAN2
if
(
CAN2
==
CANx
)
{
RCC_APB1PeriphClockCmd
(
RCC_APB1PERIPH_CAN2
,
ENABLE
);
RCC_APB2PeriphClockCmd
(
RCC_APB2PERIPH_AFIO
,
ENABLE
);
RCC_APB2PeriphClockCmd
(
RCC_APB2PERIPH_GPIOB
,
ENABLE
);
GPIO_PinsRemapConfig
(
AFIO_MAP6_CAN2_0001
,
ENABLE
);
GPIO_InitStruct
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_InitStruct
.
GPIO_Pins
=
GPIO_Pins_6
;
GPIO_Init
(
GPIOB
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_InitStruct
.
GPIO_Pins
=
GPIO_Pins_5
;
GPIO_Init
(
GPIOB
,
&
GPIO_InitStruct
);
}
#endif
}
#endif
/* BSP_USING_CAN */
bsp/at32/at32f403a-start/board/msp/at32_msp.h
浏览文件 @
bb28784a
...
...
@@ -2,8 +2,8 @@
******************************************************************************
* @file at32_msp.h
* @author Artery Technology
* @version V1.0.
0
* @date 202
0-01-10
* @version V1.0.
1
* @date 202
1-02-09
* @brief Msp header file
******************************************************************************
* @attention
...
...
@@ -29,5 +29,6 @@ void at32_msp_i2c_init(void *Instance);
void
at32_msp_sdio_init
(
void
*
Instance
);
void
at32_msp_adc_init
(
void
*
Instance
);
void
at32_msp_hwtmr_init
(
void
*
Instance
);
void
at32_msp_can_init
(
void
*
Instance
);
#endif
/* __AT32_MSP_H__ */
bsp/at32/at32f407-start/README.md
浏览文件 @
bb28784a
...
...
@@ -46,8 +46,10 @@ AT32F407-START板级包支持MDK4﹑MDK5﹑IAR开发环境和GCC编译器,以
| PWM | 支持 | TMR1/2 |
| HWTIMER | 支持 | TMR3/4/5 |
| SDIO | 支持 | SDIO1 |
| CAN | 支持 | CAN1/2 |
| WDT | 支持 | |
| RTC | 支持 | |
| FLASH | 支持 | |
| ETH | 支持 | |
### IO在板级支持包中的映射情况
...
...
@@ -89,6 +91,10 @@ AT32F407-START板级包支持MDK4﹑MDK5﹑IAR开发环境和GCC编译器,以
| PC3 | ADC1/2_IN13 |
| PC4 | ADC1/2_IN14 |
| PC5 | ADC1/2_IN15 |
| PA11 | CAN1_RX |
| PA12 | CAN1_TX |
| PB5 | CAN2_RX |
| PB6 | CAN2_TX |
| PB11 | ETH_RMII_TX_EN |
| PB12 | ETH_RMII_TX0 |
| PB13 | ETH_RMII_TX1 |
...
...
bsp/at32/at32f407-start/board/Kconfig
浏览文件 @
bb28784a
...
...
@@ -24,6 +24,10 @@ menu "On-chip Peripheral Drivers"
select RT_USING_PIN
default y
config BSP_USING_ON_CHIP_FLASH
bool "Enable on-chip FLASH"
default n
config BSP_USING_ETH
bool "Enable Ethernet"
default n
...
...
@@ -157,6 +161,19 @@ menu "On-chip Peripheral Drivers"
default n
endif
menuconfig BSP_USING_CAN
bool "Enable CAN"
default n
select RT_USING_CAN
if BSP_USING_CAN
config BSP_USING_CAN1
bool "using CAN1"
default n
config BSP_USING_CAN2
bool "using CAN2"
default n
endif
menuconfig BSP_USING_SDIO
bool "Enable SDIO"
default n
...
...
bsp/at32/at32f407-start/board/board.h
浏览文件 @
bb28784a
...
...
@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2020-01-15 shelton first version
* 2021-02-09 shelton add flash macros
*/
#ifndef __BOARD_H__
...
...
@@ -18,6 +19,12 @@
extern
"C"
{
#endif
/* Just only support for AT32F40xxG */
#define AT32_FLASH_START_ADRESS ((uint32_t)0x08000000)
#define FLASH_PAGE_SIZE (2 * 1024)
#define AT32_FLASH_SIZE (1024 * 1024)
#define AT32_FLASH_END_ADDRESS ((uint32_t)(AT32_FLASH_START_ADRESS + AT32_FLASH_SIZE))
/* Internal SRAM memory size[Kbytes] <96>, Default: 96*/
#define AT32_SRAM_SIZE 96
#define AT32_SRAM_END (0x20000000 + AT32_SRAM_SIZE * 1024)
...
...
bsp/at32/at32f407-start/board/msp/at32_msp.c
浏览文件 @
bb28784a
...
...
@@ -2,8 +2,8 @@
******************************************************************************
* @file at32_msp.c
* @author Artery Technology
* @version V1.0.
0
* @date 202
0-01-10
* @version V1.0.
1
* @date 202
1-02-09
* @brief Msp source file
******************************************************************************
* @attention
...
...
@@ -256,3 +256,44 @@ void at32_msp_hwtmr_init(void *Instance)
#endif
}
#endif
#ifdef BSP_USING_CAN
void
at32_msp_can_init
(
void
*
Instance
)
{
GPIO_InitType
GPIO_InitStruct
;
CAN_Type
*
CANx
=
(
CAN_Type
*
)
Instance
;
GPIO_StructInit
(
&
GPIO_InitStruct
);
GPIO_InitStruct
.
GPIO_MaxSpeed
=
GPIO_MaxSpeed_50MHz
;
#ifdef BSP_USING_CAN1
if
(
CAN1
==
CANx
)
{
RCC_APB1PeriphClockCmd
(
RCC_APB1PERIPH_CAN1
,
ENABLE
);
RCC_APB2PeriphClockCmd
(
RCC_APB2PERIPH_GPIOA
,
ENABLE
);
GPIO_InitStruct
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_InitStruct
.
GPIO_Pins
=
GPIO_Pins_12
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_InitStruct
.
GPIO_Pins
=
GPIO_Pins_11
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStruct
);
}
#endif
#ifdef BSP_USING_CAN2
if
(
CAN2
==
CANx
)
{
RCC_APB1PeriphClockCmd
(
RCC_APB1PERIPH_CAN2
,
ENABLE
);
RCC_APB2PeriphClockCmd
(
RCC_APB2PERIPH_AFIO
,
ENABLE
);
RCC_APB2PeriphClockCmd
(
RCC_APB2PERIPH_GPIOB
,
ENABLE
);
GPIO_PinsRemapConfig
(
AFIO_MAP6_CAN2_0001
,
ENABLE
);
GPIO_InitStruct
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_InitStruct
.
GPIO_Pins
=
GPIO_Pins_6
;
GPIO_Init
(
GPIOB
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_InitStruct
.
GPIO_Pins
=
GPIO_Pins_5
;
GPIO_Init
(
GPIOB
,
&
GPIO_InitStruct
);
}
#endif
}
#endif
/* BSP_USING_CAN */
bsp/at32/at32f407-start/board/msp/at32_msp.h
浏览文件 @
bb28784a
...
...
@@ -2,8 +2,8 @@
******************************************************************************
* @file at32_msp.h
* @author Artery Technology
* @version V1.0.
0
* @date 202
0-01-10
* @version V1.0.
1
* @date 202
1-02-09
* @brief Msp header file
******************************************************************************
* @attention
...
...
@@ -29,5 +29,6 @@ void at32_msp_i2c_init(void *Instance);
void
at32_msp_sdio_init
(
void
*
Instance
);
void
at32_msp_adc_init
(
void
*
Instance
);
void
at32_msp_hwtmr_init
(
void
*
Instance
);
void
at32_msp_can_init
(
void
*
Instance
);
#endif
/* __AT32_MSP_H__ */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录