Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
三号室
rt-thread
提交
d06f9ac9
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,发现更多精彩内容 >>
未验证
提交
d06f9ac9
编写于
8月 16, 2018
作者:
lymzzyh
提交者:
GitHub
8月 16, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1716 from xeonxu/stm32hal_can
[STM32 BSP]CAN driver for stm32f4xx HAL.
上级
033e5f4f
33753f63
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
909 addition
and
3 deletion
+909
-3
bsp/stm32f4xx-HAL/Kconfig
bsp/stm32f4xx-HAL/Kconfig
+11
-1
bsp/stm32f4xx-HAL/drivers/SConscript
bsp/stm32f4xx-HAL/drivers/SConscript
+4
-1
bsp/stm32f4xx-HAL/drivers/drv_can.c
bsp/stm32f4xx-HAL/drivers/drv_can.c
+868
-0
bsp/stm32f4xx-HAL/drivers/drv_can.h
bsp/stm32f4xx-HAL/drivers/drv_can.h
+23
-0
bsp/stm32f4xx-HAL/drivers/stm32f4xx_hal_conf.h
bsp/stm32f4xx-HAL/drivers/stm32f4xx_hal_conf.h
+3
-1
未找到文件。
bsp/stm32f4xx-HAL/Kconfig
浏览文件 @
d06f9ac9
...
...
@@ -308,7 +308,17 @@ config RT_USING_UART2
config RT_USING_UART6
bool "Using UART6"
default n
if RT_USING_CAN
config USING_BXCAN1
bool "Enable CAN1 RX:PD0 TX:PD1. Do not select HDR."
default n
config USING_BXCAN2
bool "Enable CAN2 RX:PB12 TX:PB6. Do not select HDR."
default n
endif
if RT_USING_SPI
config RT_USING_SPI1
...
...
bsp/stm32f4xx-HAL/drivers/SConscript
浏览文件 @
d06f9ac9
...
...
@@ -35,7 +35,10 @@ if GetDepend(['RT_USING_USB_HOST']):
src
+=
[
'drv_usbh.c'
]
if
GetDepend
([
'RT_USING_I2C'
]):
src
+=
[
'drv_i2c.c'
]
src
+=
[
'drv_i2c.c'
]
if
GetDepend
([
'RT_USING_CAN'
]):
src
+=
[
'drv_can.c'
]
if
GetDepend
([
'RT_USING_PWM'
]):
src
+=
[
'drv_pwm.c'
]
...
...
bsp/stm32f4xx-HAL/drivers/drv_can.c
0 → 100644
浏览文件 @
d06f9ac9
/*
* File : drv_can.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2018, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2018-08-05 Xeon Xu the first version
*/
/* Includes ------------------------------------------------------------------*/
#include "drv_can.h"
#include "board.h"
#include <rtdevice.h>
#include <rthw.h>
#include <rtthread.h>
#define BS1SHIFT 16
#define BS2SHIFT 20
#define RRESCLSHIFT 0
#define SJWSHIFT 24
#define BS1MASK ( (0x0F) << BS1SHIFT )
#define BS2MASK ( (0x07) << BS2SHIFT )
#define RRESCLMASK ( 0x3FF << RRESCLSHIFT )
#define SJWMASK ( 0x3 << SJWSHIFT )
struct
stm_baud_rate_tab
{
rt_uint32_t
baud_rate
;
rt_uint32_t
confdata
;
};
/* STM32 can driver */
struct
stm32_drv_can
{
CAN_HandleTypeDef
CanHandle
;
CanTxMsgTypeDef
TxMessage
;
CanRxMsgTypeDef
RxMessage
;
CAN_FilterConfTypeDef
FilterConfig
;
};
static
const
struct
stm_baud_rate_tab
can_baud_rate_tab
[]
=
{
{
CAN1MBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_2TQ
|
CAN_BS2_4TQ
|
6
)},
{
CAN800kBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_5TQ
|
CAN_BS2_7TQ
|
4
)},
{
CAN500kBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_14TQ
|
CAN_BS2_6TQ
|
4
)},
{
CAN250kBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_1TQ
|
CAN_BS2_2TQ
|
42
)},
{
CAN125kBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_1TQ
|
CAN_BS2_2TQ
|
84
)},
{
CAN100kBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_1TQ
|
CAN_BS2_1TQ
|
140
)},
{
CAN50kBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_1TQ
|
CAN_BS2_1TQ
|
280
)},
{
CAN20kBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_1TQ
|
CAN_BS2_1TQ
|
700
)},
{
CAN10kBaud
,
(
CAN_SJW_1TQ
|
CAN_BS1_3TQ
|
CAN_BS2_4TQ
|
525
)}
};
#define BAUD_DATA(TYPE,NO) \
((can_baud_rate_tab[NO].confdata & TYPE##MASK))
static
rt_uint32_t
get_can_baud_index
(
rt_uint32_t
baud
)
{
rt_uint32_t
len
,
index
,
default_index
;
len
=
sizeof
(
can_baud_rate_tab
)
/
sizeof
(
can_baud_rate_tab
[
0
]);
default_index
=
len
;
for
(
index
=
0
;
index
<
len
;
index
++
)
{
if
(
can_baud_rate_tab
[
index
].
baud_rate
==
baud
)
return
index
;
if
(
can_baud_rate_tab
[
index
].
baud_rate
==
1000UL
*
250
)
default_index
=
index
;
}
if
(
default_index
!=
len
)
return
default_index
;
return
0
;
}
#ifdef USING_BXCAN1
static
struct
stm32_drv_can
drv_can1
;
struct
rt_can_device
dev_can1
;
void
CAN1_TX_IRQHandler
(
void
)
{
CAN_HandleTypeDef
*
hcan
;
rt_interrupt_enter
();
hcan
=
&
drv_can1
.
CanHandle
;
HAL_CAN_IRQHandler
(
hcan
);
if
(
__HAL_CAN_TRANSMIT_STATUS
(
hcan
,
CAN_TXMAILBOX_0
))
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_TX_DONE
|
0
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
}
if
(
__HAL_CAN_TRANSMIT_STATUS
(
hcan
,
CAN_TXMAILBOX_1
))
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_TX_DONE
|
1
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
}
if
(
__HAL_CAN_TRANSMIT_STATUS
(
hcan
,
CAN_TXMAILBOX_2
))
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_TX_DONE
|
2
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 RX0 interrupts.
*/
void
CAN1_RX0_IRQHandler
(
void
)
{
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can1
.
CanHandle
;
rt_interrupt_enter
();
HAL_CAN_IRQHandler
(
hcan
);
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_FOV0
))
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_RXOF_IND
|
0
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_RX_IND
|
0
<<
8
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 RX1 interrupts.
*/
void
CAN1_RX1_IRQHandler
(
void
)
{
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can1
.
CanHandle
;
rt_interrupt_enter
();
HAL_CAN_IRQHandler
(
hcan
);
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_FOV1
))
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_RXOF_IND
|
1
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can1
,
RT_CAN_EVENT_RX_IND
|
1
<<
8
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 SCE interrupts.
*/
void
CAN1_SCE_IRQHandler
(
void
)
{
rt_uint32_t
errtype
;
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can1
.
CanHandle
;
errtype
=
hcan
->
Instance
->
ESR
;
rt_interrupt_enter
();
HAL_CAN_IRQHandler
(
hcan
);
if
(
errtype
&
0x70
&&
dev_can1
.
status
.
lasterrtype
==
(
errtype
&
0x70
))
{
switch
((
errtype
&
0x70
)
>>
4
)
{
case
RT_CAN_BUS_BIT_PAD_ERR
:
dev_can1
.
status
.
bitpaderrcnt
++
;
break
;
case
RT_CAN_BUS_FORMAT_ERR
:
dev_can1
.
status
.
formaterrcnt
++
;
break
;
case
RT_CAN_BUS_ACK_ERR
:
dev_can1
.
status
.
ackerrcnt
++
;
break
;
case
RT_CAN_BUS_IMPLICIT_BIT_ERR
:
case
RT_CAN_BUS_EXPLICIT_BIT_ERR
:
dev_can1
.
status
.
biterrcnt
++
;
break
;
case
RT_CAN_BUS_CRC_ERR
:
dev_can1
.
status
.
crcerrcnt
++
;
break
;
}
dev_can1
.
status
.
lasterrtype
=
errtype
&
0x70
;
hcan
->
Instance
->
ESR
&=
~
0x70
;
}
dev_can1
.
status
.
rcverrcnt
=
errtype
>>
24
;
dev_can1
.
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
dev_can1
.
status
.
errcode
=
errtype
&
0x07
;
hcan
->
Instance
->
MSR
|=
CAN_MSR_ERRI
;
rt_interrupt_leave
();
}
#endif // USING_BXCAN1
#ifdef USING_BXCAN2
static
struct
stm32_drv_can
drv_can2
;
struct
rt_can_device
dev_can2
;
/**
* @brief This function handles CAN2 TX interrupts.
*/
void
CAN2_TX_IRQHandler
(
void
)
{
CAN_HandleTypeDef
*
hcan
;
rt_interrupt_enter
();
hcan
=
&
drv_can2
.
CanHandle
;
HAL_CAN_IRQHandler
(
hcan
);
if
(
__HAL_CAN_TRANSMIT_STATUS
(
hcan
,
CAN_TXMAILBOX_0
))
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_TX_DONE
|
0
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
}
if
(
__HAL_CAN_TRANSMIT_STATUS
(
hcan
,
CAN_TXMAILBOX_1
))
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_TX_DONE
|
1
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
}
if
(
__HAL_CAN_TRANSMIT_STATUS
(
hcan
,
CAN_TXMAILBOX_2
))
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_TX_DONE
|
2
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 RX0 interrupts.
*/
void
CAN2_RX0_IRQHandler
(
void
)
{
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can2
.
CanHandle
;
rt_interrupt_enter
();
HAL_CAN_IRQHandler
(
hcan
);
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_FOV0
))
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_RXOF_IND
|
0
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_RX_IND
|
0
<<
8
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 RX1 interrupts.
*/
void
CAN2_RX1_IRQHandler
(
void
)
{
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can2
.
CanHandle
;
rt_interrupt_enter
();
HAL_CAN_IRQHandler
(
hcan
);
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_FOV1
))
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_RXOF_IND
|
1
<<
8
);
}
else
{
rt_hw_can_isr
(
&
dev_can2
,
RT_CAN_EVENT_RX_IND
|
1
<<
8
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 SCE interrupts.
*/
void
CAN2_SCE_IRQHandler
(
void
)
{
rt_uint32_t
errtype
;
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can2
.
CanHandle
;
errtype
=
hcan
->
Instance
->
ESR
;
rt_interrupt_enter
();
HAL_CAN_IRQHandler
(
hcan
);
if
(
errtype
&
0x70
&&
dev_can2
.
status
.
lasterrtype
==
(
errtype
&
0x70
))
{
switch
((
errtype
&
0x70
)
>>
4
)
{
case
RT_CAN_BUS_BIT_PAD_ERR
:
dev_can2
.
status
.
bitpaderrcnt
++
;
break
;
case
RT_CAN_BUS_FORMAT_ERR
:
dev_can2
.
status
.
formaterrcnt
++
;
break
;
case
RT_CAN_BUS_ACK_ERR
:
dev_can2
.
status
.
ackerrcnt
++
;
break
;
case
RT_CAN_BUS_IMPLICIT_BIT_ERR
:
case
RT_CAN_BUS_EXPLICIT_BIT_ERR
:
dev_can2
.
status
.
biterrcnt
++
;
break
;
case
RT_CAN_BUS_CRC_ERR
:
dev_can2
.
status
.
crcerrcnt
++
;
break
;
}
dev_can2
.
status
.
lasterrtype
=
errtype
&
0x70
;
hcan
->
Instance
->
ESR
&=
~
0x70
;
}
dev_can2
.
status
.
rcverrcnt
=
errtype
>>
24
;
dev_can2
.
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
dev_can2
.
status
.
errcode
=
errtype
&
0x07
;
hcan
->
Instance
->
MSR
|=
CAN_MSR_ERRI
;
rt_interrupt_leave
();
}
#endif // USING_BXCAN2
/**
* @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
(
CAN_HandleTypeDef
*
hcan
)
{
/* TODO Error Callback */
/* Prevent unused argument(s) compilation warning */
UNUSED
(
hcan
);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_CAN_ErrorCallback could be implemented in the user file
*/
}
/**
* @brief Transmission complete callback in non blocking mode
* @param hcan: pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.
* @retval None
*/
void
HAL_CAN_TxCpltCallback
(
CAN_HandleTypeDef
*
hcan
)
{
switch
((
int
)
hcan
->
Instance
)
{
case
(
int
)
CAN1
:
/* User define */
break
;
case
(
int
)
CAN2
:
/* User define */
break
;
}
}
/**
* @brief Transmission complete callback in non blocking mode
* @param hcan: pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.
* @retval None
*/
void
HAL_CAN_RxCpltCallback
(
CAN_HandleTypeDef
*
hcan
)
{
HAL_CAN_Receive_IT
(
hcan
,
CAN_FIFO0
);
HAL_CAN_Receive_IT
(
hcan
,
CAN_FIFO1
);
}
static
rt_err_t
drv_configure
(
struct
rt_can_device
*
dev_can
,
struct
can_configure
*
cfg
)
{
struct
stm32_drv_can
*
drv_can
;
rt_uint32_t
baud_index
;
CAN_InitTypeDef
*
drv_init
;
CAN_FilterConfTypeDef
*
filterConf
;
RT_ASSERT
(
dev_can
);
RT_ASSERT
(
cfg
);
drv_can
=
(
struct
stm32_drv_can
*
)
dev_can
->
parent
.
user_data
;
drv_init
=
&
drv_can
->
CanHandle
.
Init
;
drv_init
->
TTCM
=
DISABLE
;
drv_init
->
ABOM
=
DISABLE
;
drv_init
->
AWUM
=
DISABLE
;
drv_init
->
NART
=
DISABLE
;
drv_init
->
RFLM
=
DISABLE
;
drv_init
->
TXFP
=
DISABLE
;
switch
(
cfg
->
mode
)
{
case
RT_CAN_MODE_NORMAL
:
drv_init
->
Mode
=
CAN_MODE_NORMAL
;
break
;
case
RT_CAN_MODE_LISEN
:
drv_init
->
Mode
=
CAN_MODE_SILENT
;
break
;
case
RT_CAN_MODE_LOOPBACK
:
drv_init
->
Mode
=
CAN_MODE_LOOPBACK
;
break
;
case
RT_CAN_MODE_LOOPBACKANLISEN
:
drv_init
->
Mode
=
CAN_MODE_SILENT_LOOPBACK
;
break
;
}
baud_index
=
get_can_baud_index
(
cfg
->
baud_rate
);
drv_init
->
SJW
=
BAUD_DATA
(
SJW
,
baud_index
);
drv_init
->
BS1
=
BAUD_DATA
(
BS1
,
baud_index
);
drv_init
->
BS2
=
BAUD_DATA
(
BS2
,
baud_index
);
drv_init
->
Prescaler
=
BAUD_DATA
(
RRESCL
,
baud_index
);
if
(
HAL_CAN_Init
(
&
drv_can
->
CanHandle
)
!=
HAL_OK
)
{
return
RT_ERROR
;
}
/* Filter conf */
filterConf
=
&
drv_can
->
FilterConfig
;
filterConf
->
FilterNumber
=
0
;
filterConf
->
FilterMode
=
CAN_FILTERMODE_IDMASK
;
filterConf
->
FilterScale
=
CAN_FILTERSCALE_32BIT
;
filterConf
->
FilterIdHigh
=
0x0000
;
filterConf
->
FilterIdLow
=
0x0000
;
filterConf
->
FilterMaskIdHigh
=
0x0000
;
filterConf
->
FilterMaskIdLow
=
0x0000
;
filterConf
->
FilterFIFOAssignment
=
0
;
filterConf
->
FilterActivation
=
ENABLE
;
filterConf
->
BankNumber
=
14
;
HAL_CAN_ConfigFilter
(
&
drv_can
->
CanHandle
,
filterConf
);
return
RT_EOK
;
}
static
rt_err_t
drv_control
(
struct
rt_can_device
*
can
,
int
cmd
,
void
*
arg
)
{
struct
stm32_drv_can
*
drv_can
;
rt_uint32_t
argval
;
drv_can
=
(
struct
stm32_drv_can
*
)
can
->
parent
.
user_data
;
assert_param
(
drv_can
!=
RT_NULL
);
switch
(
cmd
)
{
case
RT_DEVICE_CTRL_CLR_INT
:
argval
=
(
rt_uint32_t
)
arg
;
if
(
argval
==
RT_DEVICE_FLAG_INT_RX
)
{
if
(
CAN1
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_DisableIRQ
(
CAN1_RX0_IRQn
);
HAL_NVIC_DisableIRQ
(
CAN1_RX1_IRQn
);
}
else
{
HAL_NVIC_DisableIRQ
(
CAN2_RX0_IRQn
);
HAL_NVIC_DisableIRQ
(
CAN2_RX1_IRQn
);
}
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FMP0
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FF0
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FOV0
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FMP1
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FF1
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FOV1
);
}
else
if
(
argval
==
RT_DEVICE_FLAG_INT_TX
)
{
if
(
CAN1
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_DisableIRQ
(
CAN1_TX_IRQn
);
}
else
{
HAL_NVIC_DisableIRQ
(
CAN2_TX_IRQn
);
}
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_TME
);
}
else
if
(
argval
==
RT_DEVICE_CAN_INT_ERR
)
{
if
(
CAN1
==
drv_can
->
CanHandle
.
Instance
)
{
NVIC_DisableIRQ
(
CAN1_SCE_IRQn
);
}
else
{
NVIC_DisableIRQ
(
CAN2_SCE_IRQn
);
}
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_BOF
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_LEC
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_ERR
);
}
break
;
case
RT_DEVICE_CTRL_SET_INT
:
argval
=
(
rt_uint32_t
)
arg
;
if
(
argval
==
RT_DEVICE_FLAG_INT_RX
)
{
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FMP0
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FF0
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FOV0
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FMP1
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FF1
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_FOV1
);
if
(
CAN1
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_SetPriority
(
CAN1_RX0_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN1_RX0_IRQn
);
HAL_NVIC_SetPriority
(
CAN1_RX1_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN1_RX1_IRQn
);
}
else
{
HAL_NVIC_SetPriority
(
CAN2_RX0_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN2_RX0_IRQn
);
HAL_NVIC_SetPriority
(
CAN2_RX1_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN2_RX1_IRQn
);
}
}
else
if
(
argval
==
RT_DEVICE_FLAG_INT_TX
)
{
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_TME
);
if
(
CAN1
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_SetPriority
(
CAN1_TX_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN1_TX_IRQn
);
}
else
{
HAL_NVIC_SetPriority
(
CAN2_TX_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN2_TX_IRQn
);
}
}
else
if
(
argval
==
RT_DEVICE_CAN_INT_ERR
)
{
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_BOF
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_LEC
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_ERR
);
if
(
CAN1
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_SetPriority
(
CAN1_SCE_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN1_SCE_IRQn
);
}
else
{
HAL_NVIC_SetPriority
(
CAN2_SCE_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN2_SCE_IRQn
);
}
}
break
;
case
RT_CAN_CMD_SET_FILTER
:
/* TODO: filter*/
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
->
config
.
mode
)
{
can
->
config
.
mode
=
argval
;
if
(
HAL_CAN_Init
(
&
drv_can
->
CanHandle
)
!=
HAL_OK
)
{
return
RT_ERROR
;
}
}
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
->
config
.
baud_rate
)
{
CAN_InitTypeDef
*
drv_init
;
rt_uint32_t
baud_index
;
can
->
config
.
baud_rate
=
argval
;
drv_init
=
&
drv_can
->
CanHandle
.
Init
;
drv_init
->
TTCM
=
DISABLE
;
drv_init
->
ABOM
=
DISABLE
;
drv_init
->
AWUM
=
DISABLE
;
drv_init
->
NART
=
DISABLE
;
drv_init
->
RFLM
=
DISABLE
;
drv_init
->
TXFP
=
DISABLE
;
baud_index
=
get_can_baud_index
(
can
->
config
.
baud_rate
);
drv_init
->
SJW
=
BAUD_DATA
(
SJW
,
baud_index
);
drv_init
->
BS1
=
BAUD_DATA
(
BS1
,
baud_index
);
drv_init
->
BS2
=
BAUD_DATA
(
BS2
,
baud_index
);
drv_init
->
Prescaler
=
BAUD_DATA
(
RRESCL
,
baud_index
);
if
(
HAL_CAN_Init
(
&
drv_can
->
CanHandle
)
!=
HAL_OK
)
{
return
RT_ERROR
;
}
}
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
->
config
.
privmode
)
{
can
->
config
.
privmode
=
argval
;
if
(
HAL_CAN_Init
(
&
drv_can
->
CanHandle
)
!=
HAL_OK
)
{
return
RT_ERROR
;
}
}
break
;
case
RT_CAN_CMD_GET_STATUS
:
{
rt_uint32_t
errtype
;
errtype
=
drv_can
->
CanHandle
.
Instance
->
ESR
;
can
->
status
.
rcverrcnt
=
errtype
>>
24
;
can
->
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
can
->
status
.
errcode
=
errtype
&
0x07
;
if
(
arg
!=
&
can
->
status
)
{
rt_memcpy
(
arg
,
&
can
->
status
,
sizeof
(
can
->
status
));
}
}
break
;
}
return
RT_EOK
;
}
static
int
drv_sendmsg
(
struct
rt_can_device
*
can
,
const
void
*
buf
,
rt_uint32_t
boxno
)
{
CAN_HandleTypeDef
*
hcan
;
struct
rt_can_msg
*
pmsg
=
(
struct
rt_can_msg
*
)
buf
;
hcan
=
&
((
struct
stm32_drv_can
*
)
can
->
parent
.
user_data
)
->
CanHandle
;
hcan
->
pTxMsg
->
StdId
=
pmsg
->
id
;
hcan
->
pTxMsg
->
RTR
=
pmsg
->
rtr
;
hcan
->
pTxMsg
->
IDE
=
pmsg
->
ide
;
hcan
->
pTxMsg
->
DLC
=
pmsg
->
len
;
rt_memset
(
&
hcan
->
pTxMsg
->
Data
,
0x00
,
8
);
/* rt_memcpy(&hcan->pTxMsg->Data, &pmsg->data, 8); */
hcan
->
pTxMsg
->
Data
[
0
]
=
pmsg
->
data
[
0
];
hcan
->
pTxMsg
->
Data
[
1
]
=
pmsg
->
data
[
1
];
hcan
->
pTxMsg
->
Data
[
2
]
=
pmsg
->
data
[
2
];
hcan
->
pTxMsg
->
Data
[
3
]
=
pmsg
->
data
[
3
];
hcan
->
pTxMsg
->
Data
[
4
]
=
pmsg
->
data
[
4
];
hcan
->
pTxMsg
->
Data
[
5
]
=
pmsg
->
data
[
5
];
hcan
->
pTxMsg
->
Data
[
6
]
=
pmsg
->
data
[
6
];
hcan
->
pTxMsg
->
Data
[
7
]
=
pmsg
->
data
[
7
];
HAL_CAN_Transmit_IT
(
hcan
);
return
RT_EOK
;
}
static
int
drv_recvmsg
(
struct
rt_can_device
*
can
,
void
*
buf
,
rt_uint32_t
boxno
)
{
CAN_HandleTypeDef
*
hcan
;
struct
rt_can_msg
*
pmsg
=
(
struct
rt_can_msg
*
)
buf
;
hcan
=
&
((
struct
stm32_drv_can
*
)
can
->
parent
.
user_data
)
->
CanHandle
;
pmsg
->
id
=
hcan
->
pRxMsg
->
StdId
;
pmsg
->
rtr
=
hcan
->
pRxMsg
->
RTR
;
pmsg
->
ide
=
hcan
->
pRxMsg
->
IDE
;
pmsg
->
len
=
hcan
->
pRxMsg
->
DLC
;
/* rt_memcpy(&pmsg->data, &hcan->pRxMsg->Data, 8); */
pmsg
->
data
[
0
]
=
hcan
->
pRxMsg
->
Data
[
0
];
pmsg
->
data
[
1
]
=
hcan
->
pRxMsg
->
Data
[
1
];
pmsg
->
data
[
2
]
=
hcan
->
pRxMsg
->
Data
[
2
];
pmsg
->
data
[
3
]
=
hcan
->
pRxMsg
->
Data
[
3
];
pmsg
->
data
[
4
]
=
hcan
->
pRxMsg
->
Data
[
4
];
pmsg
->
data
[
5
]
=
hcan
->
pRxMsg
->
Data
[
5
];
pmsg
->
data
[
6
]
=
hcan
->
pRxMsg
->
Data
[
6
];
pmsg
->
data
[
7
]
=
hcan
->
pRxMsg
->
Data
[
7
];
return
RT_EOK
;
}
static
const
struct
rt_can_ops
drv_can_ops
=
{
drv_configure
,
drv_control
,
drv_sendmsg
,
drv_recvmsg
,
};
void
HAL_CAN_MspInit
(
CAN_HandleTypeDef
*
canHandle
)
{
GPIO_InitTypeDef
GPIO_InitStruct
;
if
(
canHandle
->
Instance
==
CAN1
)
{
/* CAN1 clock enable */
__HAL_RCC_CAN1_CLK_ENABLE
();
__HAL_RCC_GPIOD_CLK_ENABLE
();
/**CAN1 GPIO Configuration
PD0 ------> CAN1_RX
PD1 ------> CAN1_TX
*/
GPIO_InitStruct
.
Pin
=
GPIO_PIN_0
|
GPIO_PIN_1
;
GPIO_InitStruct
.
Mode
=
GPIO_MODE_AF_PP
;
GPIO_InitStruct
.
Pull
=
GPIO_NOPULL
;
GPIO_InitStruct
.
Speed
=
GPIO_SPEED_FREQ_VERY_HIGH
;
GPIO_InitStruct
.
Alternate
=
GPIO_AF9_CAN1
;
HAL_GPIO_Init
(
GPIOD
,
&
GPIO_InitStruct
);
}
else
if
(
canHandle
->
Instance
==
CAN2
)
{
/* CAN2 clock enable */
__HAL_RCC_CAN2_CLK_ENABLE
();
__HAL_RCC_GPIOB_CLK_ENABLE
();
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB6 ------> CAN2_TX
*/
GPIO_InitStruct
.
Pin
=
GPIO_PIN_12
|
GPIO_PIN_6
;
GPIO_InitStruct
.
Mode
=
GPIO_MODE_AF_PP
;
GPIO_InitStruct
.
Pull
=
GPIO_NOPULL
;
GPIO_InitStruct
.
Speed
=
GPIO_SPEED_FREQ_VERY_HIGH
;
GPIO_InitStruct
.
Alternate
=
GPIO_AF9_CAN2
;
HAL_GPIO_Init
(
GPIOB
,
&
GPIO_InitStruct
);
}
}
void
HAL_CAN_MspDeInit
(
CAN_HandleTypeDef
*
canHandle
)
{
if
(
canHandle
->
Instance
==
CAN1
)
{
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE
();
/**CAN1 GPIO Configuration
PD0 ------> CAN1_RX
PD1 ------> CAN1_TX
*/
HAL_GPIO_DeInit
(
GPIOD
,
GPIO_PIN_0
|
GPIO_PIN_2
);
HAL_NVIC_DisableIRQ
(
CAN1_TX_IRQn
);
HAL_NVIC_DisableIRQ
(
CAN1_RX0_IRQn
);
HAL_NVIC_DisableIRQ
(
CAN1_RX1_IRQn
);
}
else
if
(
canHandle
->
Instance
==
CAN2
)
{
__HAL_RCC_CAN2_CLK_DISABLE
();
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB6 ------> CAN2_TX
*/
HAL_GPIO_DeInit
(
GPIOB
,
GPIO_PIN_12
|
GPIO_PIN_6
);
HAL_NVIC_DisableIRQ
(
CAN2_TX_IRQn
);
HAL_NVIC_DisableIRQ
(
CAN2_RX0_IRQn
);
HAL_NVIC_DisableIRQ
(
CAN2_RX1_IRQn
);
}
}
int
hw_can_init
(
void
)
{
struct
stm32_drv_can
*
drv_can
;
struct
can_configure
config
=
CANDEFAULTCONFIG
;
config
.
privmode
=
0
;
config
.
ticks
=
50
;
config
.
sndboxnumber
=
3
;
#ifdef RT_CAN_USING_HDR
config
.
maxhdr
=
28
;
#endif
#ifdef USING_BXCAN1
drv_can
=
&
drv_can1
;
drv_can
->
CanHandle
.
Instance
=
CAN1
;
drv_can
->
CanHandle
.
pTxMsg
=
&
drv_can
->
TxMessage
;
drv_can
->
CanHandle
.
pRxMsg
=
&
drv_can
->
RxMessage
;
dev_can1
.
ops
=
&
drv_can_ops
;
dev_can1
.
config
=
config
;
/* register CAN1 device */
rt_hw_can_register
(
&
dev_can1
,
"can1"
,
&
drv_can_ops
,
drv_can
);
#endif
/* USING_BXCAN1 */
#ifdef USING_BXCAN2
drv_can
=
&
drv_can2
;
drv_can
->
CanHandle
.
Instance
=
CAN2
;
drv_can
->
CanHandle
.
pTxMsg
=
&
drv_can
->
TxMessage
;
drv_can
->
CanHandle
.
pRxMsg
=
&
drv_can
->
RxMessage
;
dev_can2
.
ops
=
&
drv_can_ops
;
dev_can2
.
config
=
config
;
/* register CAN2 device */
rt_hw_can_register
(
&
dev_can2
,
"can2"
,
&
drv_can_ops
,
drv_can
);
#endif
/* USING_BXCAN2 */
return
0
;
}
INIT_BOARD_EXPORT
(
hw_can_init
);
bsp/stm32f4xx-HAL/drivers/drv_can.h
0 → 100644
浏览文件 @
d06f9ac9
/*
* File : drv_can.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2018, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2018-08-05 Xeon Xu the first version
*/
#ifndef __CAN_H__
#define __CAN_H__
#ifdef __cplusplus
extern
"C"
{
#endif
extern
int
hw_can_init
(
void
);
#ifdef __cplusplus
}
#endif
#endif
/*__CAN_H__ */
bsp/stm32f4xx-HAL/drivers/stm32f4xx_hal_conf.h
浏览文件 @
d06f9ac9
...
...
@@ -52,7 +52,9 @@ extern "C" {
*/
#define HAL_MODULE_ENABLED
/* #define HAL_ADC_MODULE_ENABLED */
/* #define HAL_CAN_MODULE_ENABLED */
#ifdef RT_USING_CAN
#define HAL_CAN_MODULE_ENABLED
#endif
/* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_DAC_MODULE_ENABLED */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录