Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Mozi
rt-thread
提交
c81eebcd
R
rt-thread
项目概览
Mozi
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c81eebcd
编写于
8月 16, 2019
作者:
T
tyustli
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[bsp] [stm32] fix drv_can.c
上级
3b252d5b
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
639 addition
and
586 deletion
+639
-586
bsp/stm32/libraries/HAL_Drivers/drv_can.c
bsp/stm32/libraries/HAL_Drivers/drv_can.c
+526
-492
bsp/stm32/libraries/HAL_Drivers/drv_can.h
bsp/stm32/libraries/HAL_Drivers/drv_can.h
+26
-17
bsp/stm32/libraries/STM32H7xx_HAL/SConscript
bsp/stm32/libraries/STM32H7xx_HAL/SConscript
+4
-4
components/drivers/can/can.c
components/drivers/can/can.c
+79
-69
components/drivers/include/drivers/can.h
components/drivers/include/drivers/can.h
+3
-3
components/finsh/cmd.c
components/finsh/cmd.c
+1
-1
未找到文件。
bsp/stm32/libraries/HAL_Drivers/drv_can.c
浏览文件 @
c81eebcd
...
...
@@ -14,13 +14,14 @@
*/
#include "drv_can.h"
#ifdef BSP_USING_CAN
#ifdef RT_USING_CAN
#define LOG_TAG "drv_can"
#include <drv_log.h>
static
void
drv_rx_isr
(
struct
rt_can_device
*
can
,
rt_uint32_t
fifo
);
#if defined (SOC_SERIES_STM32F1)
static
const
struct
stm_baud_rate_tab
can_baud_rate_tab
[]
=
/* attention !!! baud calculation example: Tclk / ((ss + bs1 + bs2) * brp) 36 / ((1 + 8 + 3) * 3) = 1MHz*/
#if defined (SOC_SERIES_STM32F1)
/* APB1 36MHz(max) */
static
const
struct
stm32_baud_rate_tab
can_baud_rate_tab
[]
=
{
{
CAN1MBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_8TQ
|
CAN_BS2_3TQ
|
3
)},
{
CAN800kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_5TQ
|
CAN_BS2_3TQ
|
5
)},
...
...
@@ -32,8 +33,8 @@ static const struct stm_baud_rate_tab can_baud_rate_tab[] =
{
CAN20kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_8TQ
|
CAN_BS2_3TQ
|
150
)},
{
CAN10kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_8TQ
|
CAN_BS2_3TQ
|
300
)}
};
#elif defined (SOC_S
TM32F429IG)
static
const
struct
stm_baud_rate_tab
can_baud_rate_tab
[]
=
#elif defined (SOC_S
ERIES_STM32F4)
/* APB1 45MHz(max) */
static
const
struct
stm
32
_baud_rate_tab
can_baud_rate_tab
[]
=
{
{
CAN1MBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_9TQ
|
CAN_BS2_5TQ
|
3
)},
{
CAN800kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_8TQ
|
CAN_BS2_5TQ
|
4
)},
...
...
@@ -45,368 +46,112 @@ static const struct stm_baud_rate_tab can_baud_rate_tab[] =
{
CAN20kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_9TQ
|
CAN_BS2_5TQ
|
150
)},
{
CAN10kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_9TQ
|
CAN_BS2_5TQ
|
300
)}
};
#elif defined (SOC_SERIES_STM32F
4)
static
const
struct
stm_baud_rate_tab
can_baud_rate_tab
[]
=
#elif defined (SOC_SERIES_STM32F
7)
/* APB1 54MHz(max) */
static
const
struct
stm
32
_baud_rate_tab
can_baud_rate_tab
[]
=
{
{
CAN1MBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_4
TQ
|
3
)},
{
CAN800kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
8TQ
|
CAN_BS2_4
TQ
|
4
)},
{
CAN500kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_4
TQ
|
6
)},
{
CAN250kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_4
TQ
|
12
)},
{
CAN125kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_4
TQ
|
24
)},
{
CAN100kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_4
TQ
|
30
)},
{
CAN50kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_4
TQ
|
60
)},
{
CAN20kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_4
TQ
|
150
)},
{
CAN10kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_4
TQ
|
300
)}
{
CAN1MBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
10TQ
|
CAN_BS2_7
TQ
|
3
)},
{
CAN800kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
9TQ
|
CAN_BS2_7
TQ
|
4
)},
{
CAN500kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
10TQ
|
CAN_BS2_7
TQ
|
6
)},
{
CAN250kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
10TQ
|
CAN_BS2_7
TQ
|
12
)},
{
CAN125kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
10TQ
|
CAN_BS2_7
TQ
|
24
)},
{
CAN100kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
10TQ
|
CAN_BS2_7
TQ
|
30
)},
{
CAN50kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
10TQ
|
CAN_BS2_7
TQ
|
60
)},
{
CAN20kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
10TQ
|
CAN_BS2_7
TQ
|
150
)},
{
CAN10kBaud
,
(
CAN_SJW_2TQ
|
CAN_BS1_
10TQ
|
CAN_BS2_7
TQ
|
300
)}
};
#endif
#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 BSP_USING_CAN1
static
struct
stm32_drv_can
drv_can1
;
struct
rt_can_device
dev_can1
;
/**
* @brief This function handles CAN1 TX interrupts.
*/
void
CAN1_TX_IRQHandler
(
void
)
{
rt_interrupt_enter
();
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can1
.
CanHandle
;
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP0
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK0
))
{
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
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP0
);
}
else
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP1
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK1
))
{
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
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP1
);
}
else
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP2
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK2
))
{
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
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP2
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 RX0 interrupts.
*/
void
CAN1_RX0_IRQHandler
(
void
)
{
rt_interrupt_enter
();
drv_rx_isr
(
&
dev_can1
,
CAN_RX_FIFO0
);
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 RX1 interrupts.
*/
void
CAN1_RX1_IRQHandler
(
void
)
static
struct
stm32_can
drv_can1
=
{
rt_interrupt_enter
();
drv_rx_isr
(
&
dev_can1
,
CAN_RX_FIFO1
);
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
/* BSP_USING_CAN1 */
.
name
=
"can1"
,
.
CanHandle
.
Instance
=
CAN1
,
};
#endif
#ifdef BSP_USING_CAN2
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
)
static
struct
stm32_can
drv_can2
=
{
rt_interrupt_enter
();
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can2
.
CanHandle
;
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP0
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK0
))
{
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
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP0
);
}
else
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP1
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK1
))
{
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
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP1
);
}
else
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP2
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK2
))
{
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
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP2
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 RX0 interrupts.
*/
void
CAN2_RX0_IRQHandler
(
void
)
{
rt_interrupt_enter
();
drv_rx_isr
(
&
dev_can2
,
CAN_RX_FIFO0
);
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 RX1 interrupts.
*/
void
CAN2_RX1_IRQHandler
(
void
)
{
rt_interrupt_enter
();
drv_rx_isr
(
&
dev_can2
,
CAN_RX_FIFO1
);
rt_interrupt_leave
();
}
"can2"
,
.
CanHandle
.
Instance
=
CAN2
,
};
#endif
/**
* @brief This function handles CAN2 SCE interrupts.
*/
void
CAN2_SCE_IRQHandler
(
void
)
static
rt_uint32_t
get_can_baud_index
(
rt_uint32_t
baud
)
{
rt_uint32_t
errtype
;
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can2
.
CanHandle
;
errtype
=
hcan
->
Instance
->
ESR
;
rt_uint32_t
len
,
index
;
rt_interrupt_enter
();
HAL_CAN_IRQHandler
(
hcan
);
if
(
errtype
&
0x70
&&
dev_can2
.
status
.
lasterrtype
==
(
errtype
&
0x70
))
len
=
sizeof
(
can_baud_rate_tab
)
/
sizeof
(
can_baud_rate_tab
[
0
]);
for
(
index
=
0
;
index
<
len
;
index
++
)
{
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
;
if
(
can_baud_rate_tab
[
index
].
baud_rate
==
baud
)
return
index
;
}
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
/* 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
(
CAN_HandleTypeDef
*
hcan
)
{
__HAL_CAN_ENABLE_IT
(
hcan
,
CAN_IT_ERROR_WARNING
|
CAN_IT_ERROR_PASSIVE
|
CAN_IT_BUSOFF
|
CAN_IT_LAST_ERROR_CODE
|
CAN_IT_ERROR
|
CAN_IT_RX_FIFO0_MSG_PENDING
|
CAN_IT_RX_FIFO0_OVERRUN
|
CAN_IT_RX_FIFO1_MSG_PENDING
|
CAN_IT_RX_FIFO1_OVERRUN
|
CAN_IT_TX_MAILBOX_EMPTY
);
return
0
;
/* default baud is CAN1MBaud */
}
static
rt_err_t
drv_configure
(
struct
rt_can_device
*
dev_can
,
struct
can_configure
*
cfg
)
static
rt_err_t
_can_config
(
struct
rt_can_device
*
can
,
struct
can_configure
*
cfg
)
{
struct
stm32_
drv_
can
*
drv_can
;
struct
stm32_can
*
drv_can
;
rt_uint32_t
baud_index
;
CAN_InitTypeDef
*
drv_init
;
RT_ASSERT
(
dev_
can
);
RT_ASSERT
(
can
);
RT_ASSERT
(
cfg
);
drv_can
=
(
struct
stm32_can
*
)
can
->
parent
.
user_data
;
RT_ASSERT
(
drv_can
);
drv_can
=
(
struct
stm32_drv_can
*
)
dev_can
->
parent
.
user_data
;
drv_init
=
&
drv_can
->
CanHandle
.
Init
;
drv_init
->
TimeTriggeredMode
=
DISABLE
;
drv_init
->
AutoBusOff
=
ENABLE
;
drv_init
->
AutoWakeUp
=
DISABLE
;
drv_init
->
AutoRetransmission
=
DISABLE
;
drv_init
->
ReceiveFifoLocked
=
DISABLE
;
drv_init
->
TransmitFifoPriority
=
ENABLE
;
drv_can
->
CanHandle
.
Init
.
TimeTriggeredMode
=
DISABLE
;
drv_can
->
CanHandle
.
Init
.
AutoBusOff
=
ENABLE
;
drv_can
->
CanHandle
.
Init
.
AutoWakeUp
=
DISABLE
;
drv_can
->
CanHandle
.
Init
.
AutoRetransmission
=
DISABLE
;
drv_can
->
CanHandle
.
Init
.
ReceiveFifoLocked
=
DISABLE
;
drv_can
->
CanHandle
.
Init
.
TransmitFifoPriority
=
ENABLE
;
switch
(
cfg
->
mode
)
{
case
RT_CAN_MODE_NORMAL
:
drv_
init
->
Mode
=
CAN_MODE_NORMAL
;
drv_
can
->
CanHandle
.
Init
.
Mode
=
CAN_MODE_NORMAL
;
break
;
case
RT_CAN_MODE_LISEN
:
drv_
init
->
Mode
=
CAN_MODE_SILENT
;
drv_
can
->
CanHandle
.
Init
.
Mode
=
CAN_MODE_SILENT
;
break
;
case
RT_CAN_MODE_LOOPBACK
:
drv_
init
->
Mode
=
CAN_MODE_LOOPBACK
;
drv_
can
->
CanHandle
.
Init
.
Mode
=
CAN_MODE_LOOPBACK
;
break
;
case
RT_CAN_MODE_LOOPBACKANLISEN
:
drv_
init
->
Mode
=
CAN_MODE_SILENT_LOOPBACK
;
drv_
can
->
CanHandle
.
Init
.
Mode
=
CAN_MODE_SILENT_LOOPBACK
;
break
;
}
baud_index
=
get_can_baud_index
(
cfg
->
baud_rate
);
drv_init
->
SyncJumpWidth
=
BAUD_DATA
(
SJW
,
baud_index
);
drv_init
->
TimeSeg1
=
BAUD_DATA
(
BS1
,
baud_index
);
drv_init
->
TimeSeg2
=
BAUD_DATA
(
BS2
,
baud_index
);
drv_init
->
Prescaler
=
BAUD_DATA
(
RRESCL
,
baud_index
);
drv_can
->
CanHandle
.
Init
.
SyncJumpWidth
=
BAUD_DATA
(
SJW
,
baud_index
);
drv_can
->
CanHandle
.
Init
.
TimeSeg1
=
BAUD_DATA
(
BS1
,
baud_index
);
drv_can
->
CanHandle
.
Init
.
TimeSeg2
=
BAUD_DATA
(
BS2
,
baud_index
);
drv_can
->
CanHandle
.
Init
.
Prescaler
=
BAUD_DATA
(
RRESCL
,
baud_index
);
/* init can */
if
(
HAL_CAN_Init
(
&
drv_can
->
CanHandle
)
!=
HAL_OK
)
{
return
RT_ERROR
;
return
-
RT_ERROR
;
}
/*
Filter conf
*/
/*
default filter config
*/
HAL_CAN_ConfigFilter
(
&
drv_can
->
CanHandle
,
&
drv_can
->
FilterConfig
);
/* can start */
HAL_CAN_Start
(
&
drv_can
->
CanHandle
);
return
RT_EOK
;
}
static
rt_err_t
drv
_control
(
struct
rt_can_device
*
can
,
int
cmd
,
void
*
arg
)
static
rt_err_t
_can
_control
(
struct
rt_can_device
*
can
,
int
cmd
,
void
*
arg
)
{
struct
stm32_drv_can
*
drv_can
=
RT_NULL
;
rt_uint32_t
argval
;
struct
rt_can_filter_config
*
filter_cfg
=
RT_NULL
;
CAN_FilterTypeDef
can_filter
;
drv_can
=
(
struct
stm32_drv_can
*
)
can
->
parent
.
user_data
;
assert_param
(
drv_can
!=
RT_NULL
);
struct
stm32_can
*
drv_can
;
struct
rt_can_filter_config
*
filter_cfg
;
RT_ASSERT
(
can
!=
RT_NULL
);
drv_can
=
(
struct
stm32_can
*
)
can
->
parent
.
user_data
;
RT_ASSERT
(
drv_can
!=
RT_NULL
);
switch
(
cmd
)
{
...
...
@@ -419,13 +164,13 @@ static rt_err_t drv_control(struct rt_can_device *can, int cmd, void *arg)
HAL_NVIC_DisableIRQ
(
CAN1_RX0_IRQn
);
HAL_NVIC_DisableIRQ
(
CAN1_RX1_IRQn
);
}
#ifdef CAN2
else
#ifdef CAN2
if
(
CAN2
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_DisableIRQ
(
CAN2_RX0_IRQn
);
HAL_NVIC_DisableIRQ
(
CAN2_RX1_IRQn
);
}
#endif
#endif
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_RX_FIFO0_MSG_PENDING
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_RX_FIFO0_FULL
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_RX_FIFO0_OVERRUN
);
...
...
@@ -439,12 +184,12 @@ static rt_err_t drv_control(struct rt_can_device *can, int cmd, void *arg)
{
HAL_NVIC_DisableIRQ
(
CAN1_TX_IRQn
);
}
#ifdef CAN2
else
#ifdef CAN2
if
(
CAN2
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_DisableIRQ
(
CAN2_TX_IRQn
);
}
#endif
#endif
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_TX_MAILBOX_EMPTY
);
}
else
if
(
argval
==
RT_DEVICE_CAN_INT_ERR
)
...
...
@@ -453,12 +198,14 @@ static rt_err_t drv_control(struct rt_can_device *can, int cmd, void *arg)
{
NVIC_DisableIRQ
(
CAN1_SCE_IRQn
);
}
#ifdef CAN2
else
#ifdef CAN2
if
(
CAN2
==
drv_can
->
CanHandle
.
Instance
)
{
NVIC_DisableIRQ
(
CAN2_SCE_IRQn
);
}
#endif
#endif
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_ERROR_WARNING
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_ERROR_PASSIVE
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_BUSOFF
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_LAST_ERROR_CODE
);
__HAL_CAN_DISABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_ERROR
);
...
...
@@ -482,15 +229,15 @@ static rt_err_t drv_control(struct rt_can_device *can, int cmd, void *arg)
HAL_NVIC_SetPriority
(
CAN1_RX1_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN1_RX1_IRQn
);
}
#ifdef CAN2
else
#ifdef CAN2
if
(
CAN2
==
drv_can
->
CanHandle
.
Instance
)
{
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
);
}
#endif
#endif
}
else
if
(
argval
==
RT_DEVICE_FLAG_INT_TX
)
{
...
...
@@ -501,16 +248,18 @@ static rt_err_t drv_control(struct rt_can_device *can, int cmd, void *arg)
HAL_NVIC_SetPriority
(
CAN1_TX_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN1_TX_IRQn
);
}
#ifdef CAN2
else
#ifdef CAN2
if
(
CAN2
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_SetPriority
(
CAN2_TX_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN2_TX_IRQn
);
}
#endif
#endif
}
else
if
(
argval
==
RT_DEVICE_CAN_INT_ERR
)
{
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_ERROR_WARNING
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_ERROR_PASSIVE
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_BUSOFF
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_LAST_ERROR_CODE
);
__HAL_CAN_ENABLE_IT
(
&
drv_can
->
CanHandle
,
CAN_IT_ERROR
);
...
...
@@ -520,100 +269,98 @@ static rt_err_t drv_control(struct rt_can_device *can, int cmd, void *arg)
HAL_NVIC_SetPriority
(
CAN1_SCE_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN1_SCE_IRQn
);
}
#ifdef CAN2
else
#ifdef CAN2
if
(
CAN2
==
drv_can
->
CanHandle
.
Instance
)
{
HAL_NVIC_SetPriority
(
CAN2_SCE_IRQn
,
1
,
0
);
HAL_NVIC_EnableIRQ
(
CAN2_SCE_IRQn
);
}
#endif
#endif
}
break
;
case
RT_CAN_CMD_SET_FILTER
:
if
(
RT_NULL
==
arg
)
{
/* default
Filter conf
*/
/* default
filter config
*/
HAL_CAN_ConfigFilter
(
&
drv_can
->
CanHandle
,
&
drv_can
->
FilterConfig
);
}
else
{
filter_cfg
=
(
struct
rt_can_filter_config
*
)
arg
;
/* get default filter */
can_filter
=
drv_can
->
FilterConfig
;
for
(
int
i
=
0
;
i
<
filter_cfg
->
count
;
++
i
)
for
(
int
i
=
0
;
i
<
filter_cfg
->
count
;
i
++
)
{
can_filter
.
FilterBank
=
filter_cfg
->
items
[
i
].
hdr
;
can_filter
.
FilterIdHigh
=
(
filter_cfg
->
items
[
i
].
id
>>
13
)
&
0xFFFF
;
can_filter
.
FilterIdLow
=
((
filter_cfg
->
items
[
i
].
id
<<
3
)
|
(
filter_cfg
->
items
[
i
].
ide
<<
2
)
|
(
filter_cfg
->
items
[
i
].
rtr
<<
1
))
&
0xFFFF
;
can_filter
.
FilterMaskIdHigh
=
(
filter_cfg
->
items
[
i
].
mask
>>
16
)
&
0xFFFF
;
can_filter
.
FilterMaskIdLow
=
filter_cfg
->
items
[
i
].
mask
&
0xFFFF
;
can_filter
.
FilterMode
=
filter_cfg
->
items
[
i
].
mode
;
drv_can
->
FilterConfig
.
FilterBank
=
filter_cfg
->
items
[
i
].
hdr
;
drv_can
->
FilterConfig
.
FilterIdHigh
=
(
filter_cfg
->
items
[
i
].
id
>>
13
)
&
0xFFFF
;
drv_can
->
FilterConfig
.
FilterIdLow
=
((
filter_cfg
->
items
[
i
].
id
<<
3
)
|
(
filter_cfg
->
items
[
i
].
ide
<<
2
)
|
(
filter_cfg
->
items
[
i
].
rtr
<<
1
))
&
0xFFFF
;
drv_can
->
FilterConfig
.
FilterMaskIdHigh
=
(
filter_cfg
->
items
[
i
].
mask
>>
16
)
&
0xFFFF
;
drv_can
->
FilterConfig
.
FilterMaskIdLow
=
filter_cfg
->
items
[
i
].
mask
&
0xFFFF
;
drv_can
->
FilterConfig
.
FilterMode
=
filter_cfg
->
items
[
i
].
mode
;
/* Filter conf */
HAL_CAN_ConfigFilter
(
&
drv_can
->
CanHandle
,
&
can_filter
);
HAL_CAN_ConfigFilter
(
&
drv_can
->
CanHandle
,
&
drv_can
->
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
)
argval
!=
RT_CAN_MODE_LISEN
&&
argval
!=
RT_CAN_MODE_LOOPBACK
&&
argval
!=
RT_CAN_MODE_LOOPBACKANLISEN
)
{
return
RT_ERROR
;
return
-
RT_ERROR
;
}
if
(
argval
!=
can
->
config
.
mode
)
if
(
argval
!=
drv_can
->
device
.
config
.
mode
)
{
can
->
config
.
mode
=
argval
;
return
drv_configure
(
can
,
&
can
->
config
);
drv_can
->
device
.
config
.
mode
=
argval
;
return
_can_config
(
&
drv_can
->
device
,
&
drv_can
->
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
)
argval
!=
CAN800kBaud
&&
argval
!=
CAN500kBaud
&&
argval
!=
CAN250kBaud
&&
argval
!=
CAN125kBaud
&&
argval
!=
CAN100kBaud
&&
argval
!=
CAN50kBaud
&&
argval
!=
CAN20kBaud
&&
argval
!=
CAN10kBaud
)
{
return
RT_ERROR
;
return
-
RT_ERROR
;
}
if
(
argval
!=
can
->
config
.
baud_rate
)
if
(
argval
!=
drv_can
->
device
.
config
.
baud_rate
)
{
can
->
config
.
baud_rate
=
argval
;
return
drv_configure
(
can
,
&
can
->
config
);
drv_can
->
device
.
config
.
baud_rate
=
argval
;
return
_can_config
(
&
drv_can
->
device
,
&
drv_can
->
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
)
argval
!=
RT_CAN_MODE_NOPRIV
)
{
return
RT_ERROR
;
return
-
RT_ERROR
;
}
if
(
argval
!=
can
->
config
.
privmode
)
if
(
argval
!=
drv_can
->
device
.
config
.
privmode
)
{
can
->
config
.
privmode
=
argval
;
return
drv_configure
(
can
,
&
can
->
config
);
drv_can
->
device
.
config
.
privmode
=
argval
;
return
_can_config
(
&
drv_can
->
device
,
&
drv_can
->
device
.
config
);
}
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
));
}
drv_can
->
device
.
status
.
rcverrcnt
=
errtype
>>
24
;
drv_can
->
device
.
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
drv_can
->
device
.
status
.
lasterrtype
=
errtype
&
0x70
;
drv_can
->
device
.
status
.
errcode
=
errtype
&
0x07
;
rt_memcpy
(
arg
,
&
drv_can
->
device
.
status
,
sizeof
(
drv_can
->
device
.
status
));
}
break
;
}
...
...
@@ -621,19 +368,28 @@ static rt_err_t drv_control(struct rt_can_device *can, int cmd, void *arg)
return
RT_EOK
;
}
static
int
drv_sendmsg
(
struct
rt_can_device
*
can
,
const
void
*
buf
,
rt_uint32_t
boxno
)
static
int
_can_sendmsg
(
struct
rt_can_device
*
can
,
const
void
*
buf
,
rt_uint32_t
box_num
)
{
CAN_HandleTypeDef
*
hcan
=
RT_NULL
;
hcan
=
&
((
struct
stm32_
drv_
can
*
)
can
->
parent
.
user_data
)
->
CanHandle
;
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
((
struct
stm32_can
*
)
can
->
parent
.
user_data
)
->
CanHandle
;
struct
rt_can_msg
*
pmsg
=
(
struct
rt_can_msg
*
)
buf
;
CAN_TxHeaderTypeDef
txheader
=
{
0
};
/*check Select mailbox is empty */
switch
(
1
<<
boxno
)
HAL_CAN_StateTypeDef
state
=
hcan
->
State
;
/* Check the parameters */
RT_ASSERT
(
IS_CAN_IDTYPE
(
pmsg
->
ide
));
RT_ASSERT
(
IS_CAN_RTR
(
pmsg
->
rtr
));
RT_ASSERT
(
IS_CAN_DLC
(
pmsg
->
len
));
if
((
state
==
HAL_CAN_STATE_READY
)
||
(
state
==
HAL_CAN_STATE_LISTENING
))
{
case
CAN_TX_MAILBOX0
:
if
(
HAL_IS_BIT_SET
(
hcan
->
Instance
->
TSR
,
CAN_TSR_TME0
)
!=
SET
)
{
/*check select mailbox is empty */
switch
(
1
<<
box_num
)
{
case
CAN_TX_MAILBOX0
:
if
(
HAL_IS_BIT_SET
(
hcan
->
Instance
->
TSR
,
CAN_TSR_TME0
)
!=
SET
)
{
/* Change CAN state */
hcan
->
State
=
HAL_CAN_STATE_ERROR
;
/* Return function status */
...
...
@@ -641,8 +397,8 @@ static int drv_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t b
}
break
;
case
CAN_TX_MAILBOX1
:
if
(
HAL_IS_BIT_SET
(
hcan
->
Instance
->
TSR
,
CAN_TSR_TME1
)
!=
SET
)
{
if
(
HAL_IS_BIT_SET
(
hcan
->
Instance
->
TSR
,
CAN_TSR_TME1
)
!=
SET
)
{
/* Change CAN state */
hcan
->
State
=
HAL_CAN_STATE_ERROR
;
/* Return function status */
...
...
@@ -650,8 +406,8 @@ static int drv_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t b
}
break
;
case
CAN_TX_MAILBOX2
:
if
(
HAL_IS_BIT_SET
(
hcan
->
Instance
->
TSR
,
CAN_TSR_TME2
)
!=
SET
)
{
if
(
HAL_IS_BIT_SET
(
hcan
->
Instance
->
TSR
,
CAN_TSR_TME2
)
!=
SET
)
{
/* Change CAN state */
hcan
->
State
=
HAL_CAN_STATE_ERROR
;
/* Return function status */
...
...
@@ -661,62 +417,124 @@ static int drv_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t b
default:
RT_ASSERT
(
0
);
break
;
}
if
(
RT_CAN_STDID
==
pmsg
->
ide
)
{
txheader
.
IDE
=
CAN_ID_STD
;
txheader
.
StdId
=
pmsg
->
id
;
}
if
(
RT_CAN_STDID
==
pmsg
->
ide
)
{
txheader
.
IDE
=
CAN_ID_STD
;
RT_ASSERT
(
IS_CAN_STDID
(
pmsg
->
id
));
txheader
.
StdId
=
pmsg
->
id
;
}
else
{
txheader
.
IDE
=
CAN_ID_EXT
;
RT_ASSERT
(
IS_CAN_EXTID
(
pmsg
->
id
));
txheader
.
ExtId
=
pmsg
->
id
;
}
if
(
RT_CAN_DTR
==
pmsg
->
rtr
)
{
txheader
.
RTR
=
CAN_RTR_DATA
;
}
else
{
txheader
.
RTR
=
CAN_RTR_REMOTE
;
}
/* Set up the Id */
if
(
RT_CAN_STDID
==
pmsg
->
ide
)
{
hcan
->
Instance
->
sTxMailBox
[
box_num
].
TIR
|=
(
txheader
.
StdId
<<
CAN_TI0R_STID_Pos
)
|
txheader
.
RTR
;
}
else
{
hcan
->
Instance
->
sTxMailBox
[
box_num
].
TIR
|=
(
txheader
.
ExtId
<<
CAN_TI0R_EXID_Pos
)
|
txheader
.
IDE
|
txheader
.
RTR
;
}
/* Set up the DLC */
hcan
->
Instance
->
sTxMailBox
[
box_num
].
TDTR
=
pmsg
->
len
&
0x0FU
;
/* Set up the data field */
WRITE_REG
(
hcan
->
Instance
->
sTxMailBox
[
box_num
].
TDHR
,
((
uint32_t
)
pmsg
->
data
[
7
]
<<
CAN_TDH0R_DATA7_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
6
]
<<
CAN_TDH0R_DATA6_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
5
]
<<
CAN_TDH0R_DATA5_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
4
]
<<
CAN_TDH0R_DATA4_Pos
));
WRITE_REG
(
hcan
->
Instance
->
sTxMailBox
[
box_num
].
TDLR
,
((
uint32_t
)
pmsg
->
data
[
3
]
<<
CAN_TDL0R_DATA3_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
2
]
<<
CAN_TDL0R_DATA2_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
1
]
<<
CAN_TDL0R_DATA1_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
0
]
<<
CAN_TDL0R_DATA0_Pos
));
/* Request transmission */
SET_BIT
(
hcan
->
Instance
->
sTxMailBox
[
box_num
].
TIR
,
CAN_TI0R_TXRQ
);
return
RT_EOK
;
}
else
{
txheader
.
IDE
=
CAN_ID_EXT
;
txheader
.
ExtId
=
pmsg
->
id
;
/* Update error code */
hcan
->
ErrorCode
|=
HAL_CAN_ERROR_NOT_INITIALIZED
;
return
-
RT_ERROR
;
}
if
(
RT_CAN_DTR
==
pmsg
->
rtr
)
}
static
int
_can_recvmsg
(
struct
rt_can_device
*
can
,
void
*
buf
,
rt_uint32_t
fifo
)
{
HAL_StatusTypeDef
status
;
CAN_HandleTypeDef
*
hcan
;
struct
rt_can_msg
*
pmsg
;
CAN_RxHeaderTypeDef
rxheader
=
{
0
};
RT_ASSERT
(
can
);
hcan
=
&
((
struct
stm32_can
*
)
can
->
parent
.
user_data
)
->
CanHandle
;
pmsg
=
(
struct
rt_can_msg
*
)
buf
;
/* get data */
status
=
HAL_CAN_GetRxMessage
(
hcan
,
fifo
,
&
rxheader
,
pmsg
->
data
);
if
(
HAL_OK
!=
status
)
return
-
RT_ERROR
;
/* get id */
if
(
CAN_ID_STD
==
rxheader
.
IDE
)
{
txheader
.
RTR
=
CAN_RTR_DATA
;
pmsg
->
ide
=
RT_CAN_STDID
;
pmsg
->
id
=
rxheader
.
StdId
;
}
else
{
txheader
.
RTR
=
CAN_RTR_REMOTE
;
pmsg
->
ide
=
RT_CAN_EXTID
;
pmsg
->
id
=
rxheader
.
ExtId
;
}
/* clear TIR */
hcan
->
Instance
->
sTxMailBox
[
boxno
].
TIR
&=
CAN_TI0R_TXRQ
;
/* Set up the Id */
if
(
RT_CAN_STDID
==
pmsg
->
ide
)
/* get type */
if
(
CAN_RTR_DATA
==
rxheader
.
RTR
)
{
hcan
->
Instance
->
sTxMailBox
[
boxno
].
TIR
|=
(
txheader
.
StdId
<<
CAN_TI0R_STID_Pos
)
|
txheader
.
IDE
|
txheader
.
R
TR
;
pmsg
->
rtr
=
RT_CAN_D
TR
;
}
else
{
hcan
->
Instance
->
sTxMailBox
[
boxno
].
TIR
|=
(
txheader
.
ExtId
<<
CAN_TI0R_EXID_Pos
)
|
txheader
.
IDE
|
txheader
.
RTR
;
pmsg
->
rtr
=
RT_CAN_
RTR
;
}
/* Set up the DLC */
hcan
->
Instance
->
sTxMailBox
[
boxno
].
TDTR
=
pmsg
->
len
&
0x0FU
;
/* Set up the data field */
WRITE_REG
(
hcan
->
Instance
->
sTxMailBox
[
boxno
].
TDHR
,
((
uint32_t
)
pmsg
->
data
[
7
]
<<
CAN_TDH0R_DATA7_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
6
]
<<
CAN_TDH0R_DATA6_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
5
]
<<
CAN_TDH0R_DATA5_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
4
]
<<
CAN_TDH0R_DATA4_Pos
));
WRITE_REG
(
hcan
->
Instance
->
sTxMailBox
[
boxno
].
TDLR
,
((
uint32_t
)
pmsg
->
data
[
3
]
<<
CAN_TDL0R_DATA3_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
2
]
<<
CAN_TDL0R_DATA2_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
1
]
<<
CAN_TDL0R_DATA1_Pos
)
|
((
uint32_t
)
pmsg
->
data
[
0
]
<<
CAN_TDL0R_DATA0_Pos
));
/* Request transmission */
SET_BIT
(
hcan
->
Instance
->
sTxMailBox
[
boxno
].
TIR
,
CAN_TI0R_TXRQ
);
/* get len */
pmsg
->
len
=
rxheader
.
DLC
;
/* get hdr */
pmsg
->
hdr
=
rxheader
.
FilterMatchIndex
;
return
RT_EOK
;
}
static
void
drv_rx_isr
(
struct
rt_can_device
*
can
,
rt_uint32_t
fifo
)
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
)
{
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
((
struct
stm32_drv_can
*
)
can
->
parent
.
user_data
)
->
CanHandle
;
RT_ASSERT
(
can
);
hcan
=
&
((
struct
stm32_can
*
)
can
->
parent
.
user_data
)
->
CanHandle
;
switch
(
fifo
)
{
case
CAN_RX_FIFO0
:
...
...
@@ -731,7 +549,7 @@ static void drv_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
/* Clear FIFO0 FULL Flag */
__HAL_CAN_CLEAR_FLAG
(
hcan
,
CAN_FLAG_FF0
);
}
/* Check Overrun flag for FIFO0 */
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_FOV0
)
&&
__HAL_CAN_GET_IT_SOURCE
(
hcan
,
CAN_IT_RX_FIFO0_OVERRUN
))
{
...
...
@@ -752,7 +570,7 @@ static void drv_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
/* Clear FIFO1 FULL Flag */
__HAL_CAN_CLEAR_FLAG
(
hcan
,
CAN_FLAG_FF1
);
}
/* Check Overrun flag for FIFO1 */
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_FOV1
)
&&
__HAL_CAN_GET_IT_SOURCE
(
hcan
,
CAN_IT_RX_FIFO1_OVERRUN
))
{
...
...
@@ -764,105 +582,321 @@ static void drv_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
}
}
static
int
drv_recvmsg
(
struct
rt_can_device
*
can
,
void
*
buf
,
rt_uint32_t
fifo
)
#ifdef BSP_USING_CAN1
/**
* @brief This function handles CAN1 TX interrupts. transmit fifo0/1/2 is empty can trigger this interrupt
*/
void
CAN1_TX_IRQHandler
(
void
)
{
HAL_StatusTypeDef
status
;
CAN_HandleTypeDef
*
hcan
=
RT_NULL
;
struct
rt_can_msg
*
pmsg
=
(
struct
rt_can_msg
*
)
buf
;
hcan
=
&
((
struct
stm32_drv_can
*
)
can
->
parent
.
user_data
)
->
CanHandle
;
CAN_RxHeaderTypeDef
rxheader
=
{
0
};
/* get data */
status
=
HAL_CAN_GetRxMessage
(
hcan
,
fifo
,
&
rxheader
,
pmsg
->
data
);
if
(
HAL_OK
!=
status
)
return
-
RT_ERROR
;
/* get id */
if
(
CAN_ID_STD
==
rxheader
.
IDE
)
rt_interrupt_enter
();
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can1
.
CanHandle
;
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP0
))
{
pmsg
->
ide
=
RT_CAN_STDID
;
pmsg
->
id
=
rxheader
.
StdId
;
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK0
))
{
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_DONE
|
0
<<
8
);
}
else
{
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP0
);
}
else
else
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP1
))
{
pmsg
->
ide
=
RT_CAN_EXTID
;
pmsg
->
id
=
rxheader
.
ExtId
;
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK1
))
{
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_DONE
|
1
<<
8
);
}
else
{
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP1
);
}
/* get type */
if
(
CAN_RTR_DATA
==
rxheader
.
RTR
)
else
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP2
))
{
pmsg
->
rtr
=
RT_CAN_DTR
;
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK2
))
{
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_DONE
|
2
<<
8
);
}
else
{
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP2
);
}
else
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 RX0 interrupts.
*/
void
CAN1_RX0_IRQHandler
(
void
)
{
rt_interrupt_enter
();
_can_rx_isr
(
&
drv_can1
.
device
,
CAN_RX_FIFO0
);
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN1 RX1 interrupts.
*/
void
CAN1_RX1_IRQHandler
(
void
)
{
rt_interrupt_enter
();
_can_rx_isr
(
&
drv_can1
.
device
,
CAN_RX_FIFO1
);
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
);
switch
((
errtype
&
0x70
)
>>
4
)
{
pmsg
->
rtr
=
RT_CAN_RTR
;
case
RT_CAN_BUS_BIT_PAD_ERR
:
drv_can1
.
device
.
status
.
bitpaderrcnt
++
;
break
;
case
RT_CAN_BUS_FORMAT_ERR
:
drv_can1
.
device
.
status
.
formaterrcnt
++
;
break
;
case
RT_CAN_BUS_ACK_ERR
:
/* attention !!! test ack err's unit is transmit unit */
drv_can1
.
device
.
status
.
ackerrcnt
++
;
if
(
!
READ_BIT
(
drv_can1
.
CanHandle
.
Instance
->
TSR
,
CAN_FLAG_TXOK0
))
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
else
if
(
!
READ_BIT
(
drv_can1
.
CanHandle
.
Instance
->
TSR
,
CAN_FLAG_TXOK0
))
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
else
if
(
!
READ_BIT
(
drv_can1
.
CanHandle
.
Instance
->
TSR
,
CAN_FLAG_TXOK0
))
rt_hw_can_isr
(
&
drv_can1
.
device
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
break
;
case
RT_CAN_BUS_IMPLICIT_BIT_ERR
:
case
RT_CAN_BUS_EXPLICIT_BIT_ERR
:
drv_can1
.
device
.
status
.
biterrcnt
++
;
break
;
case
RT_CAN_BUS_CRC_ERR
:
drv_can1
.
device
.
status
.
crcerrcnt
++
;
break
;
}
/* get len */
pmsg
->
len
=
rxheader
.
DLC
;
/* get hdr */
pmsg
->
hdr
=
rxheader
.
FilterMatchIndex
;
return
RT_EOK
;
drv_can1
.
device
.
status
.
lasterrtype
=
errtype
&
0x70
;
drv_can1
.
device
.
status
.
rcverrcnt
=
errtype
>>
24
;
drv_can1
.
device
.
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
drv_can1
.
device
.
status
.
errcode
=
errtype
&
0x07
;
hcan
->
Instance
->
MSR
|=
CAN_MSR_ERRI
;
rt_interrupt_leave
();
}
#endif
/* BSP_USING_CAN1 */
static
const
struct
rt_can_ops
drv_can_ops
=
#ifdef BSP_USING_CAN2
/**
* @brief This function handles CAN2 TX interrupts.
*/
void
CAN2_TX_IRQHandler
(
void
)
{
drv_configure
,
drv_control
,
drv_sendmsg
,
drv_recvmsg
,
};
rt_interrupt_enter
();
CAN_HandleTypeDef
*
hcan
;
hcan
=
&
drv_can2
.
CanHandle
;
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP0
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK0
))
{
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_DONE
|
0
<<
8
);
}
else
{
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP0
);
}
else
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP1
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK1
))
{
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_DONE
|
1
<<
8
);
}
else
{
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP1
);
}
else
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_RQCP2
))
{
if
(
__HAL_CAN_GET_FLAG
(
hcan
,
CAN_FLAG_TXOK2
))
{
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_DONE
|
2
<<
8
);
}
else
{
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
}
/* Write 0 to Clear transmission status flag RQCPx */
SET_BIT
(
hcan
->
Instance
->
TSR
,
CAN_TSR_RQCP2
);
}
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 RX0 interrupts.
*/
void
CAN2_RX0_IRQHandler
(
void
)
{
rt_interrupt_enter
();
_can_rx_isr
(
&
drv_can2
.
device
,
CAN_RX_FIFO0
);
rt_interrupt_leave
();
}
/**
* @brief This function handles CAN2 RX1 interrupts.
*/
void
CAN2_RX1_IRQHandler
(
void
)
{
rt_interrupt_enter
();
_can_rx_isr
(
&
drv_can2
.
device
,
CAN_RX_FIFO1
);
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
);
switch
((
errtype
&
0x70
)
>>
4
)
{
case
RT_CAN_BUS_BIT_PAD_ERR
:
drv_can2
.
device
.
status
.
bitpaderrcnt
++
;
break
;
case
RT_CAN_BUS_FORMAT_ERR
:
drv_can2
.
device
.
status
.
formaterrcnt
++
;
break
;
case
RT_CAN_BUS_ACK_ERR
:
drv_can2
.
device
.
status
.
ackerrcnt
++
;
if
(
!
READ_BIT
(
drv_can1
.
CanHandle
.
Instance
->
TSR
,
CAN_FLAG_TXOK0
))
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
0
<<
8
);
else
if
(
!
READ_BIT
(
drv_can2
.
CanHandle
.
Instance
->
TSR
,
CAN_FLAG_TXOK0
))
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
1
<<
8
);
else
if
(
!
READ_BIT
(
drv_can2
.
CanHandle
.
Instance
->
TSR
,
CAN_FLAG_TXOK0
))
rt_hw_can_isr
(
&
drv_can2
.
device
,
RT_CAN_EVENT_TX_FAIL
|
2
<<
8
);
break
;
case
RT_CAN_BUS_IMPLICIT_BIT_ERR
:
case
RT_CAN_BUS_EXPLICIT_BIT_ERR
:
drv_can2
.
device
.
status
.
biterrcnt
++
;
break
;
case
RT_CAN_BUS_CRC_ERR
:
drv_can2
.
device
.
status
.
crcerrcnt
++
;
break
;
}
drv_can2
.
device
.
status
.
lasterrtype
=
errtype
&
0x70
;
drv_can2
.
device
.
status
.
rcverrcnt
=
errtype
>>
24
;
drv_can2
.
device
.
status
.
snderrcnt
=
(
errtype
>>
16
&
0xFF
);
drv_can2
.
device
.
status
.
errcode
=
errtype
&
0x07
;
hcan
->
Instance
->
MSR
|=
CAN_MSR_ERRI
;
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
(
CAN_HandleTypeDef
*
hcan
)
{
__HAL_CAN_ENABLE_IT
(
hcan
,
CAN_IT_ERROR_WARNING
|
CAN_IT_ERROR_PASSIVE
|
CAN_IT_BUSOFF
|
CAN_IT_LAST_ERROR_CODE
|
CAN_IT_ERROR
|
CAN_IT_RX_FIFO0_MSG_PENDING
|
CAN_IT_RX_FIFO0_OVERRUN
|
CAN_IT_RX_FIFO0_FULL
|
CAN_IT_RX_FIFO1_MSG_PENDING
|
CAN_IT_RX_FIFO1_OVERRUN
|
CAN_IT_RX_FIFO1_FULL
|
CAN_IT_TX_MAILBOX_EMPTY
);
}
int
rt_hw_can_init
(
void
)
{
struct
stm32_drv_can
*
drv_can
;
struct
can_configure
config
=
CANDEFAULTCONFIG
;
config
.
privmode
=
0
;
config
.
privmode
=
RT_CAN_MODE_NOPRIV
;
config
.
ticks
=
50
;
config
.
sndboxnumber
=
3
;
config
.
msgboxsz
=
32
;
#ifdef RT_CAN_USING_HDR
config
.
maxhdr
=
14
;
#ifdef CAN2
#ifdef CAN2
config
.
maxhdr
=
28
;
#endif
#endif
#endif
/* config default filter */
CAN_FilterTypeDef
filterConf
=
{
0
};
filterConf
.
FilterBank
=
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
=
CAN_FILTER_FIFO0
;
filterConf
.
FilterBank
=
0
;
filterConf
.
FilterMode
=
CAN_FILTERMODE_IDMASK
;
filterConf
.
FilterScale
=
CAN_FILTERSCALE_32BIT
;
filterConf
.
FilterActivation
=
ENABLE
;
filterConf
.
SlaveStartFilterBank
=
14
;
#ifdef BSP_USING_CAN1
filterConf
.
FilterBank
=
0
;
drv_can1
.
FilterConfig
=
filterConf
;
drv_can
=
&
drv_can1
;
drv_can
->
CanHandle
.
Instance
=
CAN1
;
dev_can1
.
ops
=
&
drv_can_ops
;
dev_can1
.
config
=
config
;
drv_can1
.
device
.
config
=
config
;
/* register CAN1 device */
rt_hw_can_register
(
&
dev_can1
,
"can1"
,
&
drv_can_ops
,
drv_can
);
rt_hw_can_register
(
&
drv_can1
.
device
,
drv_can1
.
name
,
&
_can_ops
,
&
drv_can1
);
#endif
/* BSP_USING_CAN1 */
#ifdef BSP_USING_CAN2
filterConf
.
FilterBank
=
filterConf
.
SlaveStartFilterBank
;
drv_can2
.
FilterConfig
=
filterConf
;
drv_can
=
&
drv_can2
;
drv_can
->
CanHandle
.
Instance
=
CAN2
;
dev_can2
.
ops
=
&
drv_can_ops
;
dev_can2
.
config
=
config
;
drv_can2
.
device
.
config
=
config
;
/* register CAN2 device */
rt_hw_can_register
(
&
dev_can2
,
"can2"
,
&
drv_can_ops
,
drv_can
);
rt_hw_can_register
(
&
drv_can2
.
device
,
drv_can2
.
name
,
&
_can_ops
,
&
drv_can2
);
#endif
/* BSP_USING_CAN2 */
return
0
;
}
INIT_BOARD_EXPORT
(
rt_hw_can_init
);
#endif
/* RT_USING_CAN */
#endif
/* BSP_USING_CAN */
/************************** end of file ******************/
bsp/stm32/libraries/HAL_Drivers/drv_can.h
浏览文件 @
c81eebcd
...
...
@@ -11,40 +11,49 @@
* 2019-02-19 YLZ port to BSP [stm32]
* 2019-06-17 YLZ modify struct stm32_drv_can.
*/
#ifndef __DRV_CAN_H__
#define __DRV_CAN_H__
#ifdef __cplusplus
extern
"C"
{
#endif
#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 )
#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
struct
stm
32
_baud_rate_tab
{
rt_uint32_t
baud_rate
;
rt_uint32_t
confdata
;
rt_uint32_t
conf
ig_
data
;
};
#define BAUD_DATA(TYPE,NO) ((can_baud_rate_tab[NO].config_data & TYPE##MASK))
/*
STM32 can driver
*/
struct
stm32_
drv_
can
/*
stm32 can device
*/
struct
stm32_can
{
char
*
name
;
CAN_HandleTypeDef
CanHandle
;
CAN_FilterTypeDef
FilterConfig
;
struct
rt_can_device
device
;
/* inherit from can device */
};
#ifdef __cplusplus
extern
"C"
{
#endif
int
rt_hw_can_init
(
void
);
#ifdef __cplusplus
}
}
#endif
#endif
/*__DRV_CAN_H__ */
/************************** end of file ******************/
bsp/stm32/libraries/STM32H7xx_HAL/SConscript
浏览文件 @
c81eebcd
...
...
@@ -29,9 +29,9 @@ STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c
'''
)
if
GetDepend
([
'RT_USING_SERIAL'
]):
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c'
]
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_usart.c'
]
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c'
]
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c'
]
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_usart.c'
]
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c'
]
if
GetDepend
([
'RT_USING_I2C'
]):
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c'
]
...
...
@@ -49,7 +49,7 @@ if GetDepend(['RT_USING_USB_HOST']) or GetDepend(['RT_USING_USB_DEVICE']):
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c'
]
if
GetDepend
([
'RT_USING_CAN'
]):
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_can.c'
]
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_
fd
can.c'
]
if
GetDepend
([
'RT_USING_HWTIMER'
])
or
GetDepend
([
'RT_USING_PWM'
]):
src
+=
[
'STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c'
]
...
...
components/drivers/can/can.c
浏览文件 @
c81eebcd
...
...
@@ -27,10 +27,15 @@ static rt_err_t rt_can_init(struct rt_device *dev)
/* initialize rx/tx */
can
->
can_rx
=
RT_NULL
;
can
->
can_tx
=
RT_NULL
;
#ifdef RT_CAN_USING_HDR
can
->
hdr
=
RT_NULL
;
#endif
/* apply configuration */
if
(
can
->
ops
->
configure
)
result
=
can
->
ops
->
configure
(
can
,
&
can
->
config
);
else
result
=
-
RT_ENOSYS
;
return
result
;
}
...
...
@@ -293,7 +298,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
can
->
can_rx
=
rx_fifo
;
dev
->
open_flag
|=
RT_DEVICE_FLAG_INT_RX
;
/*
configure low level device
*/
/*
open can rx interrupt
*/
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
}
}
...
...
@@ -311,7 +316,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
tx_fifo
->
buffer
=
(
struct
rt_can_sndbxinx_list
*
)(
tx_fifo
+
1
);
rt_memset
(
tx_fifo
->
buffer
,
0
,
can
->
config
.
sndboxnumber
*
sizeof
(
struct
rt_can_sndbxinx_list
));
can
->
config
.
sndboxnumber
*
sizeof
(
struct
rt_can_sndbxinx_list
));
rt_list_init
(
&
tx_fifo
->
freelist
);
for
(
i
=
0
;
i
<
can
->
config
.
sndboxnumber
;
i
++
)
{
...
...
@@ -325,7 +330,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
can
->
can_tx
=
tx_fifo
;
dev
->
open_flag
|=
RT_DEVICE_FLAG_INT_TX
;
/*
configure low level device
*/
/*
open can tx interrupt
*/
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_TX
);
}
}
...
...
@@ -406,7 +411,7 @@ static rt_err_t rt_can_close(struct rt_device *dev)
rt_free
(
rx_fifo
);
dev
->
open_flag
&=
~
RT_DEVICE_FLAG_INT_RX
;
can
->
can_rx
=
RT_NULL
;
/* c
onfigure low level device
*/
/* c
lear can rx interrupt
*/
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
}
...
...
@@ -420,7 +425,7 @@ static rt_err_t rt_can_close(struct rt_device *dev)
rt_free
(
tx_fifo
);
dev
->
open_flag
&=
~
RT_DEVICE_FLAG_INT_TX
;
can
->
can_tx
=
RT_NULL
;
/* c
onfigure low level device
*/
/* c
lear can tx interrupt
*/
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_TX
);
}
...
...
@@ -484,6 +489,7 @@ static rt_err_t rt_can_control(struct rt_device *dev,
struct
rt_can_device
*
can
;
rt_err_t
res
;
res
=
RT_EOK
;
RT_ASSERT
(
dev
!=
RT_NULL
);
can
=
(
struct
rt_can_device
*
)
dev
;
...
...
@@ -501,8 +507,9 @@ static rt_err_t rt_can_control(struct rt_device *dev,
case
RT_DEVICE_CTRL_CONFIG
:
/* configure device */
can
->
ops
->
configure
(
can
,
(
struct
can_configure
*
)
args
);
res
=
can
->
ops
->
configure
(
can
,
(
struct
can_configure
*
)
args
);
break
;
case
RT_CAN_CMD_SET_PRIV
:
/* configure device */
if
((
rt_uint32_t
)
args
!=
can
->
config
.
privmode
)
...
...
@@ -513,7 +520,6 @@ static rt_err_t rt_can_control(struct rt_device *dev,
res
=
can
->
ops
->
control
(
can
,
cmd
,
args
);
if
(
res
!=
RT_EOK
)
return
res
;
tx_fifo
=
(
struct
rt_can_tx_fifo
*
)
can
->
can_tx
;
if
(
can
->
config
.
privmode
)
{
...
...
@@ -522,11 +528,11 @@ static rt_err_t rt_can_control(struct rt_device *dev,
level
=
rt_hw_interrupt_disable
();
if
(
rt_list_isempty
(
&
tx_fifo
->
buffer
[
i
].
list
))
{
rt_sem_release
(
&
(
tx_fifo
->
sem
));
rt_sem_release
(
&
(
tx_fifo
->
sem
));
}
else
{
rt_list_remove
(
&
tx_fifo
->
buffer
[
i
].
list
);
rt_list_remove
(
&
tx_fifo
->
buffer
[
i
].
list
);
}
rt_hw_interrupt_enable
(
level
);
}
...
...
@@ -544,7 +550,6 @@ static rt_err_t rt_can_control(struct rt_device *dev,
rt_hw_interrupt_enable
(
level
);
}
}
return
RT_EOK
;
}
break
;
...
...
@@ -561,74 +566,73 @@ static rt_err_t rt_can_control(struct rt_device *dev,
return
res
;
}
{
struct
rt_can_filter_config
*
pfilter
;
struct
rt_can_filter_item
*
pitem
;
rt_uint32_t
count
;
rt_base_t
level
;
struct
rt_can_filter_config
*
pfilter
;
struct
rt_can_filter_item
*
pitem
;
rt_uint32_t
count
;
rt_base_t
level
;
pfilter
=
(
struct
rt_can_filter_config
*
)
args
;
count
=
pfilter
->
count
;
pitem
=
pfilter
->
items
;
if
(
pfilter
->
actived
)
pfilter
=
(
struct
rt_can_filter_config
*
)
args
;
RT_ASSERT
(
pfilter
);
count
=
pfilter
->
count
;
pitem
=
pfilter
->
items
;
if
(
pfilter
->
actived
)
{
while
(
count
)
{
while
(
count
)
if
(
pitem
->
hdr
>=
can
->
config
.
maxhdr
||
pitem
->
hdr
<
0
)
{
if
(
pitem
->
hdr
>=
can
->
config
.
maxhdr
||
pitem
->
hdr
<
0
)
{
count
--
;
pitem
++
;
continue
;
}
level
=
rt_hw_interrupt_disable
();
if
(
!
can
->
hdr
[
pitem
->
hdr
].
connected
)
{
rt_hw_interrupt_enable
(
level
);
rt_memcpy
(
&
can
->
hdr
[
pitem
->
hdr
].
filter
,
pitem
,
sizeof
(
struct
rt_can_filter_item
));
level
=
rt_hw_interrupt_disable
();
can
->
hdr
[
pitem
->
hdr
].
connected
=
1
;
can
->
hdr
[
pitem
->
hdr
].
msgs
=
0
;
rt_list_init
(
&
can
->
hdr
[
pitem
->
hdr
].
list
);
}
rt_hw_interrupt_enable
(
level
);
count
--
;
pitem
++
;
continue
;
}
level
=
rt_hw_interrupt_disable
();
if
(
!
can
->
hdr
[
pitem
->
hdr
].
connected
)
{
rt_hw_interrupt_enable
(
level
);
rt_memcpy
(
&
can
->
hdr
[
pitem
->
hdr
].
filter
,
pitem
,
sizeof
(
struct
rt_can_filter_item
));
level
=
rt_hw_interrupt_disable
();
can
->
hdr
[
pitem
->
hdr
].
connected
=
1
;
can
->
hdr
[
pitem
->
hdr
].
msgs
=
0
;
rt_list_init
(
&
can
->
hdr
[
pitem
->
hdr
].
list
);
}
rt_hw_interrupt_enable
(
level
);
count
--
;
pitem
++
;
}
else
}
else
{
while
(
count
)
{
while
(
count
)
if
(
pitem
->
hdr
>=
can
->
config
.
maxhdr
||
pitem
->
hdr
<
0
)
{
if
(
pitem
->
hdr
>=
can
->
config
.
maxhdr
||
pitem
->
hdr
<
0
)
{
count
--
;
pitem
++
;
continue
;
}
level
=
rt_hw_interrupt_disable
();
count
--
;
pitem
++
;
continue
;
}
level
=
rt_hw_interrupt_disable
();
if
(
can
->
hdr
[
pitem
->
hdr
].
connected
)
if
(
can
->
hdr
[
pitem
->
hdr
].
connected
)
{
can
->
hdr
[
pitem
->
hdr
].
connected
=
0
;
can
->
hdr
[
pitem
->
hdr
].
msgs
=
0
;
if
(
!
rt_list_isempty
(
&
can
->
hdr
[
pitem
->
hdr
].
list
))
{
can
->
hdr
[
pitem
->
hdr
].
connected
=
0
;
can
->
hdr
[
pitem
->
hdr
].
msgs
=
0
;
if
(
!
rt_list_isempty
(
&
can
->
hdr
[
pitem
->
hdr
].
list
))
{
rt_list_remove
(
can
->
hdr
[
pitem
->
hdr
].
list
.
next
);
}
rt_hw_interrupt_enable
(
level
);
rt_memset
(
&
can
->
hdr
[
pitem
->
hdr
].
filter
,
0
,
sizeof
(
struct
rt_can_filter_item
));
rt_list_remove
(
can
->
hdr
[
pitem
->
hdr
].
list
.
next
);
}
else
{
rt_hw_interrupt_enable
(
level
);
}
count
--
;
pitem
++
;
rt_hw_interrupt_enable
(
level
);
rt_memset
(
&
can
->
hdr
[
pitem
->
hdr
].
filter
,
0
,
sizeof
(
struct
rt_can_filter_item
));
}
else
{
rt_hw_interrupt_enable
(
level
);
}
count
--
;
pitem
++
;
}
}
break
;
...
...
@@ -642,12 +646,16 @@ static rt_err_t rt_can_control(struct rt_device *dev,
/* control device */
if
(
can
->
ops
->
control
!=
RT_NULL
)
{
can
->
ops
->
control
(
can
,
cmd
,
args
);
res
=
can
->
ops
->
control
(
can
,
cmd
,
args
);
}
else
{
res
=
-
RT_ENOSYS
;
}
break
;
}
return
RT_EOK
;
return
res
;
}
/*
...
...
@@ -655,8 +663,10 @@ static rt_err_t rt_can_control(struct rt_device *dev,
*/
static
void
cantimeout
(
void
*
arg
)
{
rt_can_t
can
=
(
rt_can_t
)
arg
;
rt_can_t
can
;
can
=
(
rt_can_t
)
arg
;
RT_ASSERT
(
can
);
rt_device_control
((
rt_device_t
)
can
,
RT_CAN_CMD_GET_STATUS
,
(
void
*
)
&
can
->
status
);
if
(
can
->
status_indicate
.
ind
!=
RT_NULL
)
...
...
@@ -690,7 +700,7 @@ const static struct rt_device_ops can_device_ops =
/*
* can register
*/
rt_err_t
rt_hw_can_register
(
struct
rt_can_device
*
can
,
rt_err_t
rt_hw_can_register
(
struct
rt_can_device
*
can
,
const
char
*
name
,
const
struct
rt_can_ops
*
ops
,
void
*
data
)
...
...
components/drivers/include/drivers/can.h
浏览文件 @
c81eebcd
...
...
@@ -221,7 +221,7 @@ struct rt_can_msg
rt_uint32_t
rsv
:
1
;
rt_uint32_t
len
:
8
;
rt_uint32_t
priv
:
8
;
rt_
u
int32_t
hdr
:
8
;
rt_int32_t
hdr
:
8
;
rt_uint32_t
reserved
:
8
;
rt_uint8_t
data
[
8
];
};
...
...
@@ -252,7 +252,7 @@ struct rt_can_rx_fifo
#define RT_CAN_EVENT_RX_IND 0x01
/* Rx indication */
#define RT_CAN_EVENT_TX_DONE 0x02
/* Tx complete */
#define RT_CAN_EVENT_TX_FAIL 0x03
/* Tx
complete
*/
#define RT_CAN_EVENT_TX_FAIL 0x03
/* Tx
fail
*/
#define RT_CAN_EVENT_RX_TIMEOUT 0x05
/* Rx timeout */
#define RT_CAN_EVENT_RXOF_IND 0x06
/* Rx overflow */
...
...
@@ -278,7 +278,7 @@ struct rt_can_ops
int
(
*
recvmsg
)(
struct
rt_can_device
*
can
,
void
*
buf
,
rt_uint32_t
boxno
);
};
rt_err_t
rt_hw_can_register
(
struct
rt_can_device
*
can
,
rt_err_t
rt_hw_can_register
(
struct
rt_can_device
*
can
,
const
char
*
name
,
const
struct
rt_can_ops
*
ops
,
void
*
data
);
...
...
components/finsh/cmd.c
浏览文件 @
c81eebcd
...
...
@@ -847,7 +847,7 @@ long list_device(void)
device
->
parent
.
name
,
(
device
->
type
<=
RT_Device_Class_Unknown
)
?
device_type_str
[
device
->
type
]
:
device_type_str
[
RT_Device_Class_Unknown
],
device_type_str
[
RT_Device_Class_Unknown
-
1
],
device
->
ref_count
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录