drv_can.c 33.2 KB
Newer Older
杨连钊 已提交
1 2 3 4 5 6 7 8 9
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-08-05     Xeon Xu      the first version
 * 2019-01-22     YLZ          port from stm324xx-HAL to bsp stm3210x-HAL
10
 * 2019-02-19     YLZ          add support EXTID RTR Frame. modify send, recv functions.
杨连钊 已提交
11
 *                             fix bug.port to BSP [stm32]
12 13
 * 2019-03-27     YLZ          support double can channels, support stm32F4xx (only Legacy mode).
 * 2019-06-17     YLZ          port to new STM32F1xx HAL V1.1.3.
14
 * 2021-02-02     YuZhe XU     fix bug in filter config
杨连钊 已提交
15 16 17
 */

#include "drv_can.h"
T
tyustli 已提交
18
#ifdef BSP_USING_CAN
杨连钊 已提交
19

T
tyustli 已提交
20 21
#define LOG_TAG    "drv_can"
#include <drv_log.h>
杨连钊 已提交
22

T
tyustli 已提交
23 24 25
/* 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[] =
杨连钊 已提交
26
{
27
    {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_3TQ | 3)},
杨连钊 已提交
28 29 30 31 32
    {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_5TQ  | CAN_BS2_3TQ | 5)},
    {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_3TQ | 6)},
    {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_3TQ | 12)},
    {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_3TQ | 24)},
    {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_3TQ | 30)},
33 34 35 36
    {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_3TQ | 60)},
    {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_3TQ | 150)},
    {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_3TQ | 300)}
};
T
tyustli 已提交
37 38
#elif defined (SOC_SERIES_STM32F4)/* APB1 45MHz(max) */
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
39 40 41 42 43 44 45 46 47 48
{
    {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_5TQ | 3)},
    {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ  | CAN_BS2_5TQ | 4)},
    {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_5TQ | 6)},
    {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_5TQ | 12)},
    {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_5TQ | 24)},
    {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_5TQ | 30)},
    {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_5TQ | 60)},
    {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_5TQ | 150)},
    {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_5TQ | 300)}
杨连钊 已提交
49
};
T
tyustli 已提交
50 51
#elif defined (SOC_SERIES_STM32F7)/* APB1 54MHz(max) */
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
杨连钊 已提交
52
{
T
tyustli 已提交
53 54 55 56 57 58 59 60 61
    {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ  | CAN_BS2_7TQ | 3)},
    {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ  | CAN_BS2_7TQ | 4)},
    {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ  | CAN_BS2_7TQ | 6)},
    {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ  | CAN_BS2_7TQ | 12)},
    {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ  | CAN_BS2_7TQ | 24)},
    {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ  | CAN_BS2_7TQ | 30)},
    {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ  | CAN_BS2_7TQ | 60)},
    {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ  | CAN_BS2_7TQ | 150)},
    {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ  | CAN_BS2_7TQ | 300)}
杨连钊 已提交
62
};
63 64 65 66 67 68 69 70 71 72 73 74 75
#elif defined (SOC_SERIES_STM32L4)/* APB1 80MHz(max) */
static const struct stm32_baud_rate_tab can_baud_rate_tab[] =
{
    {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_5TQ  | CAN_BS2_2TQ | 10)},
    {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_14TQ  | CAN_BS2_5TQ | 5)},
    {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_7TQ  | CAN_BS2_2TQ | 16)},
    {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ  | CAN_BS2_2TQ | 20)},
    {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ  | CAN_BS2_2TQ | 40)},
    {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ  | CAN_BS2_2TQ | 50)},
    {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ  | CAN_BS2_2TQ | 100)},
    {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ  | CAN_BS2_2TQ | 250)},
    {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_13TQ  | CAN_BS2_2TQ | 500)}
};
杨连钊 已提交
76 77 78
#endif

#ifdef BSP_USING_CAN1
T
tyustli 已提交
79
static struct stm32_can drv_can1 =
杨连钊 已提交
80
{
T
tyustli 已提交
81 82 83 84
    .name = "can1",
    .CanHandle.Instance = CAN1,
};
#endif
杨连钊 已提交
85 86

#ifdef BSP_USING_CAN2
T
tyustli 已提交
87
static struct stm32_can drv_can2 =
杨连钊 已提交
88
{
T
tyustli 已提交
89 90 91 92
    "can2",
    .CanHandle.Instance = CAN2,
};
#endif
杨连钊 已提交
93

T
tyustli 已提交
94
static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
杨连钊 已提交
95
{
T
tyustli 已提交
96
    rt_uint32_t len, index;
杨连钊 已提交
97

T
tyustli 已提交
98 99
    len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
    for (index = 0; index < len; index++)
杨连钊 已提交
100
    {
T
tyustli 已提交
101 102
        if (can_baud_rate_tab[index].baud_rate == baud)
            return index;
杨连钊 已提交
103 104
    }

T
tyustli 已提交
105
    return 0; /* default baud is CAN1MBaud */
杨连钊 已提交
106 107
}

T
tyustli 已提交
108
static rt_err_t _can_config(struct rt_can_device *can, struct can_configure *cfg)
杨连钊 已提交
109
{
T
tyustli 已提交
110
    struct stm32_can *drv_can;
杨连钊 已提交
111 112
    rt_uint32_t baud_index;

T
tyustli 已提交
113
    RT_ASSERT(can);
杨连钊 已提交
114
    RT_ASSERT(cfg);
T
tyustli 已提交
115 116
    drv_can = (struct stm32_can *)can->parent.user_data;
    RT_ASSERT(drv_can);
杨连钊 已提交
117

T
tyustli 已提交
118 119 120 121 122 123
    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;
杨连钊 已提交
124 125 126 127

    switch (cfg->mode)
    {
    case RT_CAN_MODE_NORMAL:
T
tyustli 已提交
128
        drv_can->CanHandle.Init.Mode = CAN_MODE_NORMAL;
杨连钊 已提交
129 130
        break;
    case RT_CAN_MODE_LISEN:
T
tyustli 已提交
131
        drv_can->CanHandle.Init.Mode = CAN_MODE_SILENT;
杨连钊 已提交
132 133
        break;
    case RT_CAN_MODE_LOOPBACK:
T
tyustli 已提交
134
        drv_can->CanHandle.Init.Mode = CAN_MODE_LOOPBACK;
杨连钊 已提交
135 136
        break;
    case RT_CAN_MODE_LOOPBACKANLISEN:
T
tyustli 已提交
137
        drv_can->CanHandle.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
杨连钊 已提交
138 139 140 141
        break;
    }

    baud_index = get_can_baud_index(cfg->baud_rate);
T
tyustli 已提交
142 143 144 145 146
    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 */
杨连钊 已提交
147 148
    if (HAL_CAN_Init(&drv_can->CanHandle) != HAL_OK)
    {
T
tyustli 已提交
149
        return -RT_ERROR;
杨连钊 已提交
150
    }
T
tyustli 已提交
151 152

    /* default filter config */
153 154 155
    HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
    /* can start */
    HAL_CAN_Start(&drv_can->CanHandle);
T
tyustli 已提交
156

杨连钊 已提交
157 158 159
    return RT_EOK;
}

T
tyustli 已提交
160
static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
杨连钊 已提交
161 162
{
    rt_uint32_t argval;
T
tyustli 已提交
163 164 165 166 167 168
    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);
杨连钊 已提交
169 170 171 172 173 174 175

    switch (cmd)
    {
    case RT_DEVICE_CTRL_CLR_INT:
        argval = (rt_uint32_t) arg;
        if (argval == RT_DEVICE_FLAG_INT_RX)
        {
176 177
            if (CAN1 == drv_can->CanHandle.Instance)
            {
杨连钊 已提交
178 179 180
                HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
                HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
            }
T
tyustli 已提交
181 182
#ifdef CAN2
            if (CAN2 == drv_can->CanHandle.Instance)
杨连钊 已提交
183 184 185 186
            {
                HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
                HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
            }
T
tyustli 已提交
187
#endif
188 189 190 191 192 193
            __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);
            __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
            __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_FULL);
            __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_OVERRUN);
杨连钊 已提交
194 195 196 197 198 199 200
        }
        else if (argval == RT_DEVICE_FLAG_INT_TX)
        {
            if (CAN1 == drv_can->CanHandle.Instance)
            {
                HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
            }
T
tyustli 已提交
201 202
#ifdef CAN2
            if (CAN2 == drv_can->CanHandle.Instance)
杨连钊 已提交
203 204 205
            {
                HAL_NVIC_DisableIRQ(CAN2_TX_IRQn);
            }
T
tyustli 已提交
206
#endif
207
            __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_TX_MAILBOX_EMPTY);
杨连钊 已提交
208 209 210 211 212 213 214
        }
        else if (argval == RT_DEVICE_CAN_INT_ERR)
        {
            if (CAN1 == drv_can->CanHandle.Instance)
            {
                NVIC_DisableIRQ(CAN1_SCE_IRQn);
            }
T
tyustli 已提交
215 216
#ifdef CAN2
            if (CAN2 == drv_can->CanHandle.Instance)
杨连钊 已提交
217 218 219
            {
                NVIC_DisableIRQ(CAN2_SCE_IRQn);
            }
T
tyustli 已提交
220 221 222
#endif
            __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_WARNING);
            __HAL_CAN_DISABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_PASSIVE);
223 224 225
            __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);
杨连钊 已提交
226 227 228 229 230 231
        }
        break;
    case RT_DEVICE_CTRL_SET_INT:
        argval = (rt_uint32_t) arg;
        if (argval == RT_DEVICE_FLAG_INT_RX)
        {
232 233 234 235 236 237
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING);
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_FULL);
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO0_OVERRUN);
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_MSG_PENDING);
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_FULL);
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_RX_FIFO1_OVERRUN);
杨连钊 已提交
238 239 240 241 242 243 244 245

            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);
            }
T
tyustli 已提交
246 247
#ifdef CAN2
            if (CAN2 == drv_can->CanHandle.Instance)
杨连钊 已提交
248 249 250 251 252 253
            {
                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);
            }
T
tyustli 已提交
254
#endif
杨连钊 已提交
255 256 257
        }
        else if (argval == RT_DEVICE_FLAG_INT_TX)
        {
258
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_TX_MAILBOX_EMPTY);
杨连钊 已提交
259 260 261 262 263 264

            if (CAN1 == drv_can->CanHandle.Instance)
            {
                HAL_NVIC_SetPriority(CAN1_TX_IRQn, 1, 0);
                HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
            }
T
tyustli 已提交
265 266
#ifdef CAN2
            if (CAN2 == drv_can->CanHandle.Instance)
杨连钊 已提交
267 268 269 270
            {
                HAL_NVIC_SetPriority(CAN2_TX_IRQn, 1, 0);
                HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
            }
T
tyustli 已提交
271
#endif
杨连钊 已提交
272 273 274
        }
        else if (argval == RT_DEVICE_CAN_INT_ERR)
        {
T
tyustli 已提交
275 276
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_WARNING);
            __HAL_CAN_ENABLE_IT(&drv_can->CanHandle, CAN_IT_ERROR_PASSIVE);
277 278 279
            __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);
杨连钊 已提交
280 281 282 283 284 285

            if (CAN1 == drv_can->CanHandle.Instance)
            {
                HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 0);
                HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
            }
T
tyustli 已提交
286 287
#ifdef CAN2
            if (CAN2 == drv_can->CanHandle.Instance)
杨连钊 已提交
288 289 290 291
            {
                HAL_NVIC_SetPriority(CAN2_SCE_IRQn, 1, 0);
                HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn);
            }
T
tyustli 已提交
292
#endif
杨连钊 已提交
293 294 295
        }
        break;
    case RT_CAN_CMD_SET_FILTER:
296 297 298 299 300 301 302
    {
        rt_uint32_t id_h = 0;
        rt_uint32_t id_l = 0;
        rt_uint32_t mask_h = 0;
        rt_uint32_t mask_l = 0;
        rt_uint32_t mask_l_tail = 0;  //CAN_FxR2 bit [2:0]

303 304
        if (RT_NULL == arg)
        {
T
tyustli 已提交
305
            /* default filter config */
306 307 308 309 310 311
            HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
        }
        else
        {
            filter_cfg = (struct rt_can_filter_config *)arg;
            /* get default filter */
T
tyustli 已提交
312
            for (int i = 0; i < filter_cfg->count; i++)
313
            {
314 315 316 317 318 319 320 321
                if (filter_cfg->items[i].hdr == -1)
                {
                    drv_can->FilterConfig.FilterBank = i;
                }
                else
                {
                    drv_can->FilterConfig.FilterBank = filter_cfg->items[i].hdr;
                }
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
                 /**
                 * ID     | CAN_FxR1[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0]       |
                 * MASK   | CAN_FxR2[31:24] | CAN_FxR1[23:16] | CAN_FxR1[15:8] | CAN_FxR1[7:0]       |
                 * STD ID |     STID[10:3]  | STDID[2:0] |<-                21bit                  ->|
                 * EXT ID |    EXTID[28:21] | EXTID[20:13]    | EXTID[12:5]    | EXTID[4:0] IDE RTR 0|
                 * @note the 32bit STD ID must << 21 to fill CAN_FxR1[31:21] and EXT ID must << 3,
                 *       -> but the id bit of struct rt_can_filter_item is 29, 
                 *       -> so STD id << 18 and EXT id Don't need << 3, when get the high 16bit.
                 *       -> FilterIdHigh : (((STDid << 18) or (EXT id)) >> 13) & 0xFFFF,
                 *       -> FilterIdLow:   ((STDid << 18) or (EXT id << 3)) & 0xFFFF. 
                 * @note the mask bit of struct rt_can_filter_item is 32, 
                 *       -> FilterMaskIdHigh: (((STD mask << 21) or (EXT mask <<3)) >> 16) & 0xFFFF  
                 *       -> FilterMaskIdLow: ((STD mask << 21) or (EXT mask <<3)) & 0xFFFF  
                 */
                if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDMASK)
                {
                    /* make sure the CAN_FxR1[2:0](IDE RTR) work */
                    mask_l_tail = 0x06;
                }
                else if (filter_cfg->items[i].mode == CAN_FILTERMODE_IDLIST)
                {
                    /* same as CAN_FxR1 */
                    mask_l_tail = (filter_cfg->items[i].ide << 2) | 
                                   (filter_cfg->items[i].rtr << 1);
                }
                if (filter_cfg->items[i].ide == RT_CAN_STDID)
                {
                    id_h = ((filter_cfg->items[i].id << 18) >> 13) & 0xFFFF;
                    id_l = ((filter_cfg->items[i].id << 18) | 
                            (filter_cfg->items[i].ide << 2) | 
                            (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
                    mask_h = ((filter_cfg->items[i].mask << 21) >> 16) & 0xFFFF;
                    mask_l = ((filter_cfg->items[i].mask << 21) | mask_l_tail) & 0xFFFF;
                }
                else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
                {
                    id_h = (filter_cfg->items[i].id >> 13) & 0xFFFF;
C
cosmo 已提交
359
                    id_l = ((filter_cfg->items[i].id << 3)   | 
360 361 362 363 364 365 366 367 368 369
                            (filter_cfg->items[i].ide << 2)  | 
                            (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
                    mask_h = ((filter_cfg->items[i].mask << 3) >> 16) & 0xFFFF;
                    mask_l = ((filter_cfg->items[i].mask << 3) | mask_l_tail) & 0xFFFF;
                }
                drv_can->FilterConfig.FilterIdHigh = id_h;
                drv_can->FilterConfig.FilterIdLow = id_l;
                drv_can->FilterConfig.FilterMaskIdHigh = mask_h;
                drv_can->FilterConfig.FilterMaskIdLow = mask_l;
                    
T
tyustli 已提交
370
                drv_can->FilterConfig.FilterMode = filter_cfg->items[i].mode;
371
                /* Filter conf */
T
tyustli 已提交
372
                HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig);
373 374
            }
        }
杨连钊 已提交
375
        break;
376
    }
杨连钊 已提交
377 378
    case RT_CAN_CMD_SET_MODE:
        argval = (rt_uint32_t) arg;
379
        if (argval != RT_CAN_MODE_NORMAL &&
T
tyustli 已提交
380 381 382
                argval != RT_CAN_MODE_LISEN &&
                argval != RT_CAN_MODE_LOOPBACK &&
                argval != RT_CAN_MODE_LOOPBACKANLISEN)
杨连钊 已提交
383
        {
T
tyustli 已提交
384
            return -RT_ERROR;
杨连钊 已提交
385
        }
T
tyustli 已提交
386
        if (argval != drv_can->device.config.mode)
杨连钊 已提交
387
        {
T
tyustli 已提交
388 389
            drv_can->device.config.mode = argval;
            return _can_config(&drv_can->device, &drv_can->device.config);
杨连钊 已提交
390 391 392 393 394
        }
        break;
    case RT_CAN_CMD_SET_BAUD:
        argval = (rt_uint32_t) arg;
        if (argval != CAN1MBaud &&
T
tyustli 已提交
395 396 397 398 399 400 401 402
                argval != CAN800kBaud &&
                argval != CAN500kBaud &&
                argval != CAN250kBaud &&
                argval != CAN125kBaud &&
                argval != CAN100kBaud &&
                argval != CAN50kBaud  &&
                argval != CAN20kBaud  &&
                argval != CAN10kBaud)
杨连钊 已提交
403
        {
T
tyustli 已提交
404
            return -RT_ERROR;
杨连钊 已提交
405
        }
T
tyustli 已提交
406
        if (argval != drv_can->device.config.baud_rate)
杨连钊 已提交
407
        {
T
tyustli 已提交
408 409
            drv_can->device.config.baud_rate = argval;
            return _can_config(&drv_can->device, &drv_can->device.config);
杨连钊 已提交
410 411 412 413
        }
        break;
    case RT_CAN_CMD_SET_PRIV:
        argval = (rt_uint32_t) arg;
414
        if (argval != RT_CAN_MODE_PRIV &&
T
tyustli 已提交
415
                argval != RT_CAN_MODE_NOPRIV)
杨连钊 已提交
416
        {
T
tyustli 已提交
417
            return -RT_ERROR;
杨连钊 已提交
418
        }
T
tyustli 已提交
419
        if (argval != drv_can->device.config.privmode)
杨连钊 已提交
420
        {
T
tyustli 已提交
421 422
            drv_can->device.config.privmode = argval;
            return _can_config(&drv_can->device, &drv_can->device.config);
杨连钊 已提交
423 424 425 426 427 428
        }
        break;
    case RT_CAN_CMD_GET_STATUS:
    {
        rt_uint32_t errtype;
        errtype = drv_can->CanHandle.Instance->ESR;
T
tyustli 已提交
429 430 431 432 433 434
        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));
杨连钊 已提交
435 436 437 438 439 440 441
    }
    break;
    }

    return RT_EOK;
}

T
tyustli 已提交
442
static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
杨连钊 已提交
443
{
T
tyustli 已提交
444 445
    CAN_HandleTypeDef *hcan;
    hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
杨连钊 已提交
446
    struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
447
    CAN_TxHeaderTypeDef txheader = {0};
T
tyustli 已提交
448 449 450 451 452 453 454
    HAL_CAN_StateTypeDef state = hcan->State;

    /* Check the parameters */
    RT_ASSERT(IS_CAN_DLC(pmsg->len));

    if ((state == HAL_CAN_STATE_READY) ||
            (state == HAL_CAN_STATE_LISTENING))
455
    {
T
tyustli 已提交
456 457 458 459 460 461
        /*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)
            {
462 463 464 465 466 467 468
                /* Change CAN state */
                hcan->State = HAL_CAN_STATE_ERROR;
                /* Return function status */
                return -RT_ERROR;
            }
            break;
        case CAN_TX_MAILBOX1:
T
tyustli 已提交
469 470
            if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1) != SET)
            {
471 472 473 474 475 476 477
                /* Change CAN state */
                hcan->State = HAL_CAN_STATE_ERROR;
                /* Return function status */
                return -RT_ERROR;
            }
            break;
        case CAN_TX_MAILBOX2:
T
tyustli 已提交
478 479
            if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2) != SET)
            {
480 481 482 483 484 485 486 487 488
                /* Change CAN state */
                hcan->State = HAL_CAN_STATE_ERROR;
                /* Return function status */
                return -RT_ERROR;
            }
            break;
        default:
            RT_ASSERT(0);
            break;
T
tyustli 已提交
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
        }

        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;
        }
T
tyustli 已提交
512 513
        /* clear TIR */
        hcan->Instance->sTxMailBox[box_num].TIR &= CAN_TI0R_TXRQ;
T
tyustli 已提交
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
        /* 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;
杨连钊 已提交
540
    }
541
    else
杨连钊 已提交
542
    {
T
tyustli 已提交
543 544 545 546
        /* Update error code */
        hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;

        return -RT_ERROR;
杨连钊 已提交
547
    }
T
tyustli 已提交
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
}

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)
杨连钊 已提交
568
    {
T
tyustli 已提交
569 570
        pmsg->ide = RT_CAN_STDID;
        pmsg->id = rxheader.StdId;
杨连钊 已提交
571
    }
572
    else
杨连钊 已提交
573
    {
T
tyustli 已提交
574 575
        pmsg->ide = RT_CAN_EXTID;
        pmsg->id = rxheader.ExtId;
杨连钊 已提交
576
    }
T
tyustli 已提交
577 578
    /* get type */
    if (CAN_RTR_DATA == rxheader.RTR)
杨连钊 已提交
579
    {
T
tyustli 已提交
580
        pmsg->rtr = RT_CAN_DTR;
杨连钊 已提交
581 582 583
    }
    else
    {
T
tyustli 已提交
584
        pmsg->rtr = RT_CAN_RTR;
杨连钊 已提交
585
    }
T
tyustli 已提交
586 587 588
    /* get len */
    pmsg->len = rxheader.DLC;
    /* get hdr */
589 590 591 592 593 594 595 596 597
    if (hcan->Instance == CAN1)
    {
        pmsg->hdr = (rxheader.FilterMatchIndex + 1) >> 1;
    }
#ifdef CAN2
    else if (hcan->Instance == CAN2)
    {
       pmsg->hdr = (rxheader.FilterMatchIndex >> 1) + 14;
    }
598
#endif
T
tyustli 已提交
599

杨连钊 已提交
600 601 602
    return RT_EOK;
}

T
tyustli 已提交
603 604 605 606 607 608 609 610 611 612

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)
杨连钊 已提交
613
{
614
    CAN_HandleTypeDef *hcan;
T
tyustli 已提交
615 616 617
    RT_ASSERT(can);
    hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;

618
    switch (fifo)
杨连钊 已提交
619
    {
620
    case CAN_RX_FIFO0:
621 622 623 624 625 626 627 628 629 630 631
        /* save to user list */
        if (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO0_MSG_PENDING))
        {
            rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
        }
        /* Check FULL flag for FIFO0 */
        if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF0) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO0_FULL))
        {
            /* Clear FIFO0 FULL Flag */
            __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
        }
T
tyustli 已提交
632

633 634 635 636 637 638 639
        /* 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))
        {
            /* Clear FIFO0 Overrun Flag */
            __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
            rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
        }
640 641
        break;
    case CAN_RX_FIFO1:
642 643 644 645 646 647 648 649 650 651 652
        /* save to user list */
        if (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO1) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO1_MSG_PENDING))
        {
            rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
        }
        /* Check FULL flag for FIFO1 */
        if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FF1) && __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_RX_FIFO1_FULL))
        {
            /* Clear FIFO1 FULL Flag */
            __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
        }
T
tyustli 已提交
653

654 655 656 657 658 659 660
        /* 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))
        {
            /* Clear FIFO1 Overrun Flag */
            __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
            rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
        }
661
        break;
杨连钊 已提交
662
    }
663
}
664

T
tyustli 已提交
665 666 667 668 669
#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)
670
{
T
tyustli 已提交
671 672 673 674
    rt_interrupt_enter();
    CAN_HandleTypeDef *hcan;
    hcan = &drv_can1.CanHandle;
    if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP0))
杨连钊 已提交
675
    {
T
tyustli 已提交
676 677 678 679 680 681 682 683 684 685
        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);
杨连钊 已提交
686
    }
T
tyustli 已提交
687
    else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP1))
杨连钊 已提交
688
    {
T
tyustli 已提交
689 690 691 692 693 694 695 696 697 698
        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);
杨连钊 已提交
699
    }
T
tyustli 已提交
700
    else if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_RQCP2))
杨连钊 已提交
701
    {
T
tyustli 已提交
702 703 704 705 706 707 708 709 710 711
        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);
杨连钊 已提交
712
    }
T
tyustli 已提交
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
    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)
杨连钊 已提交
751
    {
T
tyustli 已提交
752 753 754 755 756 757 758 759 760 761
    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);
762
        else if (!READ_BIT(drv_can1.CanHandle.Instance->TSR, CAN_FLAG_TXOK1))
T
tyustli 已提交
763
            rt_hw_can_isr(&drv_can1.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
764
        else if (!READ_BIT(drv_can1.CanHandle.Instance->TSR, CAN_FLAG_TXOK2))
T
tyustli 已提交
765 766 767 768 769 770 771 772 773
            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;
杨连钊 已提交
774
    }
T
tyustli 已提交
775 776 777 778 779 780 781

    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();
杨连钊 已提交
782
}
T
tyustli 已提交
783
#endif /* BSP_USING_CAN1 */
杨连钊 已提交
784

T
tyustli 已提交
785 786 787 788 789
#ifdef BSP_USING_CAN2
/**
 * @brief This function handles CAN2 TX interrupts.
 */
void CAN2_TX_IRQHandler(void)
杨连钊 已提交
790
{
T
tyustli 已提交
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
    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++;
880
        if (!READ_BIT(drv_can2.CanHandle.Instance->TSR, CAN_FLAG_TXOK0))
T
tyustli 已提交
881
            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
882
        else if (!READ_BIT(drv_can2.CanHandle.Instance->TSR, CAN_FLAG_TXOK1))
T
tyustli 已提交
883
            rt_hw_can_isr(&drv_can2.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
884
        else if (!READ_BIT(drv_can2.CanHandle.Instance->TSR, CAN_FLAG_TXOK2))
T
tyustli 已提交
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
            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);
}
杨连钊 已提交
926 927 928 929

int rt_hw_can_init(void)
{
    struct can_configure config = CANDEFAULTCONFIG;
T
tyustli 已提交
930
    config.privmode = RT_CAN_MODE_NOPRIV;
杨连钊 已提交
931 932 933
    config.ticks = 50;
#ifdef RT_CAN_USING_HDR
    config.maxhdr = 14;
T
tyustli 已提交
934
#ifdef CAN2
杨连钊 已提交
935
    config.maxhdr = 28;
T
tyustli 已提交
936
#endif
937
#endif
938 939 940 941 942 943 944
    /* config default filter */
    CAN_FilterTypeDef filterConf = {0};
    filterConf.FilterIdHigh = 0x0000;
    filterConf.FilterIdLow = 0x0000;
    filterConf.FilterMaskIdHigh = 0x0000;
    filterConf.FilterMaskIdLow = 0x0000;
    filterConf.FilterFIFOAssignment = CAN_FILTER_FIFO0;
T
tyustli 已提交
945 946 947
    filterConf.FilterBank = 0;
    filterConf.FilterMode = CAN_FILTERMODE_IDMASK;
    filterConf.FilterScale = CAN_FILTERSCALE_32BIT;
948 949
    filterConf.FilterActivation = ENABLE;
    filterConf.SlaveStartFilterBank = 14;
T
tyustli 已提交
950

杨连钊 已提交
951
#ifdef BSP_USING_CAN1
952
    filterConf.FilterBank = 0;
T
tyustli 已提交
953

954
    drv_can1.FilterConfig = filterConf;
T
tyustli 已提交
955
    drv_can1.device.config = config;
杨连钊 已提交
956
    /* register CAN1 device */
T
tyustli 已提交
957 958 959 960
    rt_hw_can_register(&drv_can1.device,
                       drv_can1.name,
                       &_can_ops,
                       &drv_can1);
杨连钊 已提交
961 962 963
#endif /* BSP_USING_CAN1 */

#ifdef BSP_USING_CAN2
964
    filterConf.FilterBank = filterConf.SlaveStartFilterBank;
T
tyustli 已提交
965

966
    drv_can2.FilterConfig = filterConf;
T
tyustli 已提交
967
    drv_can2.device.config = config;
杨连钊 已提交
968
    /* register CAN2 device */
T
tyustli 已提交
969 970 971 972
    rt_hw_can_register(&drv_can2.device,
                       drv_can2.name,
                       &_can_ops,
                       &drv_can2);
杨连钊 已提交
973 974 975 976
#endif /* BSP_USING_CAN2 */

    return 0;
}
T
tyustli 已提交
977

杨连钊 已提交
978
INIT_BOARD_EXPORT(rt_hw_can_init);
T
tyustli 已提交
979 980 981 982

#endif /* BSP_USING_CAN */

/************************** end of file ******************/