Controller Area Network library for NUCLEO boards equipped with CAN peripheral.

Dependents:   Nucleo-Courtois CANBLE CANnucleo_Hello3 Nucleo_Serialprintf ... more

Controller Area Network library for the NUCLEO and DISCOVERY boards equipped with CAN peripheral


Information

Because CAN support has been finally implemented into the mbed library also for the ST boards there is no need to use the CANnucleo library anymore (however you may if you want). The CAN_Hello example is trying to demonstrate the mbed built-in CAN API with NUCLEO boards.


Provides CAN support for the following boards:

with the following features:

  • Easy to use. Delete the mbed library from your project and import the latest mbed-dev and CANnucleo libraries. In the mbed-dev library open the device.h file associated with the selected target board and add #undef DEVICE_CAN as follows:

device.h

#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H

//=======================================
#define DEVICE_ID_LENGTH       24

#undef DEVICE_CAN

#include "objects.h"

#endif

See the CANnucleo_Hello demo for more details.

  • Automatic recovery from bus-off state can be enabled/disabled in the constructor (defaults to ENABLE).
  • Up to 14 filters (0 - 13) are available for the application to set up for message filtering performed by hardware.
    For more details see below or have a look at the comments in CANnucleo.cpp.
  • One CAN channel per NUCLEO board is supported. The CAN peripheral can be connected either to pins PA_11, PA_12 (Receiver, Transmitter) or to pins PB_8, PB_9 (Receiver, Transmitter). This is configured when creating a CAN instance.
  • Simplifies adding/getting data to/from a CAN message by using the << (append) and the >> (extract) operators.

Import programCANnucleo_Hello

Using CAN bus with NUCLEO boards (Demo for the CANnucleo library).



Filtering performed by the built-in CAN controller without disturbing the CPU

CANnucleo supports only mask mode and 32-bit filter scale. Identifier list mode filtering and 16-bit filter scale are not supported. There are 14 filters available (0 - 13) for the application to set up. Each filter is a 32-bit filter defined by a filter ID and a filter mask. If no filter is set up then no CAN message is accepted! That's why filter #0 is set up in the constructor to accept all CAN messages by default. On reception of a message it is compared with filter #0. If there is a match, the message is accepted and stored. If there is no match, the incoming identifier is then compared with the next filter. If the received identifier does not match any of the identifiers configured in the filters, the message is discarded by hardware without disturbing the software.

CAN filter function - designed to setup a CAN filter

int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle)

Parameters

id - 'Filter ID' defines the bit values to be compared with the corresponding received bits.

Mapping of 32-bits (4-bytes) :

STID[10:3]STID[2:0] EXID[17:13]EXID[12:5]EXID[4:0] IDE RTR 0
  • STID - Stardard Identifier bits
  • EXID - Extended Identifier bits
  • [x:y]- bit range
  • IDE - Identifier Extension bit (0 -> Standard Identifier, 1 -> Extended Identifier)
  • RTR - Remote Transmission Request bit (0 -> Remote Transmission Request, 1 -> Standard message)

mask - 'Filter mask' defines which bits of the 'Filter ID' are compared with the received bits and which are disregarded.
Mapping of 32-bits (4-bytes) :

STID[10:3]STID[2:0] EXID[17:13]EXID[12:5]EXID[4:0] IDE RTR 0
  • STID - Stardard Identifier bits
  • EXID - Extended Identifier bits
  • [x:y]- bit range
  • IDE - Identifier Extension bit
  • RTR - Remote Transmission Request bit
  • 1 -> bit is considered
  • 0 -> bit is disregarded

format - This parameter must be CANAny
handle - Selects the filter. This parameter must be a number between 0 and 13.
retval - 0 - successful, 1 - error, 2 - busy, 3 - time out

Example of filter set up and filtering

Let's assume we would like to accept only messages with standard identifier 0x207:

STID[15:0] = 0x207 = 00000010 00000111


We map the STID to filter ID by shifting the bits adequately:

Filter ID = STID << (16 + (15 - 10)) = STID << 21 = 01000000 11100000 00000000 00000000


To compare only the bits representing STID we set the filter mask appropriately:

Filter mask = 11111111 11100000 00000000 00000100 = 0xFFE00004
              |||||||| |||                    |
              -------- ---                    |
                  |     |                     |
           STID[10:3]  STID[2:0]             IDE


Recall that filter #0 has been set up in the constructor to accept all CAN messages by default. So we have to reconfigure it. If we were set up filter #1 here then filter #0 would accept all the messages and no message would reach filter #1!
To reconfigure (set up) filter #0 we call:

can.filter(0x207 << 21, 0xFFE00004, CANAny, 0);


            Only these bits of 'Filter id' (set to 1 here in 'Filter mask') are compared 
            with the corresponding bits of received message (the others are disregarded)
                                |
                 ---------------------------------
                 |||||||| |||                    |
   Filter mask = 11111111 11100000 00000000 00000100 (= 0xFFE00004)
   Filter id   = 01000000 11100000 00000000 00000000 (= 0x40E00000)
                 |||||||| |||                    |
                 ---------------------------------
                                |
            To accept the message the values of these bits must match.
            Otherwise the message is passed to the next filter or
            discarded if this was the last active filter.
                                |
                 ---------------------------------
                 |||||||| |||                    |
   Received id = 01000000 11100000 00000000 00000010 (= 0x40E00002)
                             ||||| |||||||| ||||| ||
                             -----------------------
                                         |
                          These bits (set to 0 in 'Filter mask') are disregarded (masked).
                          They can have arbitrary values.


NOTE: For the meaning of individual bits see the mapping of 32-bits explained above.

We can use the filter function to setup more (up to 14) CAN filters for example as follows:

can.filter(0x207 << 21, 0xFFE00004, CANAny, 0);    // filter #0
can.filter(0x251 << 21, 0xFFE00004, CANAny, 1);    // filter #1
can.filter(0x304 << 21, 0xFFE00004, CANAny, 2);    // filter #2
...
Committer:
hudakz
Date:
Sun Jul 19 09:06:26 2015 +0000
Revision:
0:e29bc8e0dddd
Child:
1:eb04f7f0478d
rev 00

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:e29bc8e0dddd 1 /**
hudakz 0:e29bc8e0dddd 2 ******************************************************************************
hudakz 0:e29bc8e0dddd 3 * @file stm32f1xx_hal_msp.c
hudakz 0:e29bc8e0dddd 4 * @author MCD Application Team
hudakz 0:e29bc8e0dddd 5 * @version V1.0.0
hudakz 0:e29bc8e0dddd 6 * @date 17-December-2014
hudakz 0:e29bc8e0dddd 7 * @brief HAL MSP module.
hudakz 0:e29bc8e0dddd 8 ******************************************************************************
hudakz 0:e29bc8e0dddd 9 * @attention
hudakz 0:e29bc8e0dddd 10 *
hudakz 0:e29bc8e0dddd 11 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
hudakz 0:e29bc8e0dddd 12 *
hudakz 0:e29bc8e0dddd 13 * Redistribution and use in source and binary forms, with or without modification,
hudakz 0:e29bc8e0dddd 14 * are permitted provided that the following conditions are met:
hudakz 0:e29bc8e0dddd 15 * 1. Redistributions of source code must retain the above copyright notice,
hudakz 0:e29bc8e0dddd 16 * this list of conditions and the following disclaimer.
hudakz 0:e29bc8e0dddd 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
hudakz 0:e29bc8e0dddd 18 * this list of conditions and the following disclaimer in the documentation
hudakz 0:e29bc8e0dddd 19 * and/or other materials provided with the distribution.
hudakz 0:e29bc8e0dddd 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
hudakz 0:e29bc8e0dddd 21 * may be used to endorse or promote products derived from this software
hudakz 0:e29bc8e0dddd 22 * without specific prior written permission.
hudakz 0:e29bc8e0dddd 23 *
hudakz 0:e29bc8e0dddd 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
hudakz 0:e29bc8e0dddd 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
hudakz 0:e29bc8e0dddd 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
hudakz 0:e29bc8e0dddd 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
hudakz 0:e29bc8e0dddd 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
hudakz 0:e29bc8e0dddd 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
hudakz 0:e29bc8e0dddd 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
hudakz 0:e29bc8e0dddd 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
hudakz 0:e29bc8e0dddd 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
hudakz 0:e29bc8e0dddd 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
hudakz 0:e29bc8e0dddd 34 *
hudakz 0:e29bc8e0dddd 35 ******************************************************************************
hudakz 0:e29bc8e0dddd 36 *
hudakz 0:e29bc8e0dddd 37 * Modified by Zoltan Hudak <hudakz@inbox.com>
hudakz 0:e29bc8e0dddd 38 *
hudakz 0:e29bc8e0dddd 39 ******************************************************************************
hudakz 0:e29bc8e0dddd 40 */
hudakz 0:e29bc8e0dddd 41 #include "stm32f1xx_hal.h"
hudakz 0:e29bc8e0dddd 42 #include "can_api.h"
hudakz 0:e29bc8e0dddd 43 #include "pinmap.h"
hudakz 0:e29bc8e0dddd 44
hudakz 0:e29bc8e0dddd 45 CAN_HandleTypeDef _canHandle;
hudakz 0:e29bc8e0dddd 46 CanRxMsgTypeDef _canRxMsg;
hudakz 0:e29bc8e0dddd 47 CanTxMsgTypeDef _canTxMsg;
hudakz 0:e29bc8e0dddd 48 PinName _rxPin;
hudakz 0:e29bc8e0dddd 49 PinName _txPin;
hudakz 0:e29bc8e0dddd 50
hudakz 0:e29bc8e0dddd 51 void (*rxCompleteCallback) (void);
hudakz 0:e29bc8e0dddd 52
hudakz 0:e29bc8e0dddd 53 /**
hudakz 0:e29bc8e0dddd 54 * @brief CAN initialization.
hudakz 0:e29bc8e0dddd 55 * @param obj: can_t object
hudakz 0:e29bc8e0dddd 56 * @param rxPin: RX pin name
hudakz 0:e29bc8e0dddd 57 * @param txPin: TX pin name
hudakz 0:e29bc8e0dddd 58 * @retval None
hudakz 0:e29bc8e0dddd 59 */
hudakz 0:e29bc8e0dddd 60 void initCAN(can_t* obj, PinName rxPin, PinName txPin) {
hudakz 0:e29bc8e0dddd 61 _rxPin = rxPin;
hudakz 0:e29bc8e0dddd 62 _txPin = txPin;
hudakz 0:e29bc8e0dddd 63
hudakz 0:e29bc8e0dddd 64 _canHandle.Instance = CAN1;
hudakz 0:e29bc8e0dddd 65 _canHandle.pTxMsg = &_canTxMsg;
hudakz 0:e29bc8e0dddd 66 _canHandle.pRxMsg = &_canRxMsg;
hudakz 0:e29bc8e0dddd 67
hudakz 0:e29bc8e0dddd 68 _canHandle.Init.TTCM = DISABLE;
hudakz 0:e29bc8e0dddd 69 _canHandle.Init.ABOM = DISABLE;
hudakz 0:e29bc8e0dddd 70 _canHandle.Init.AWUM = DISABLE;
hudakz 0:e29bc8e0dddd 71 _canHandle.Init.NART = DISABLE;
hudakz 0:e29bc8e0dddd 72 _canHandle.Init.RFLM = DISABLE;
hudakz 0:e29bc8e0dddd 73 _canHandle.Init.TXFP = DISABLE;
hudakz 0:e29bc8e0dddd 74 _canHandle.Init.Mode = CAN_MODE_NORMAL;
hudakz 0:e29bc8e0dddd 75
hudakz 0:e29bc8e0dddd 76 // 125kbps bit rate (default)
hudakz 0:e29bc8e0dddd 77 #if defined(TARGET_NUCLEO_F103RB) || \
hudakz 0:e29bc8e0dddd 78 defined(TARGET_NUCLEO_F302R8) || \
hudakz 0:e29bc8e0dddd 79 defined(TARGET_NUCLEO_F334R8) || \
hudakz 0:e29bc8e0dddd 80 defined(TARGET_NUCLEO_F303RE) || \
hudakz 0:e29bc8e0dddd 81 defined(TARGET_DISCO_F334C8)
hudakz 0:e29bc8e0dddd 82 // APB1 pheripheral clock = 36000000Hz
hudakz 0:e29bc8e0dddd 83 _canHandle.Init.Prescaler = 18; // number of time quanta = 36000000/18/125000 = 16
hudakz 0:e29bc8e0dddd 84 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 85 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at (1 + 11) / 16 * 100 = 75%
hudakz 0:e29bc8e0dddd 86 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 0:e29bc8e0dddd 87 #elif defined(TARGET_NUCLEO_F070RB) || \
hudakz 0:e29bc8e0dddd 88 defined(TARGET_NUCLEO_F072RB) || \
hudakz 0:e29bc8e0dddd 89 defined(TARGET_NUCLEO_F091RC)
hudakz 0:e29bc8e0dddd 90 // APB1 pheripheral clock = 48000000Hz
hudakz 0:e29bc8e0dddd 91 _canHandle.Init.Prescaler = 24; // number of time quanta = 48000000/24/125000 = 16
hudakz 0:e29bc8e0dddd 92 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 93 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 0:e29bc8e0dddd 94 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 0:e29bc8e0dddd 95 #endif
hudakz 0:e29bc8e0dddd 96
hudakz 0:e29bc8e0dddd 97 HAL_CAN_Init(&_canHandle);
hudakz 0:e29bc8e0dddd 98 }
hudakz 0:e29bc8e0dddd 99
hudakz 0:e29bc8e0dddd 100 /**
hudakz 0:e29bc8e0dddd 101 * @brief CAN MSP Initialization
hudakz 0:e29bc8e0dddd 102 * @param hcan: CAN handle pointer
hudakz 0:e29bc8e0dddd 103 * @retval None
hudakz 0:e29bc8e0dddd 104 */
hudakz 0:e29bc8e0dddd 105 void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) {
hudakz 0:e29bc8e0dddd 106 GPIO_InitTypeDef GPIO_InitStruct;
hudakz 0:e29bc8e0dddd 107
hudakz 0:e29bc8e0dddd 108 if((_rxPin == PA_11) && (_txPin == PA_12)) {
hudakz 0:e29bc8e0dddd 109
hudakz 0:e29bc8e0dddd 110 /* CAN1 Periph clock enable */
hudakz 0:e29bc8e0dddd 111 __HAL_RCC_CAN1_CLK_ENABLE();
hudakz 0:e29bc8e0dddd 112
hudakz 0:e29bc8e0dddd 113 /* Enable GPIO clock */
hudakz 0:e29bc8e0dddd 114 __HAL_RCC_GPIOA_CLK_ENABLE();
hudakz 0:e29bc8e0dddd 115
hudakz 0:e29bc8e0dddd 116 /* Enable AFIO clock and remap CAN PINs to PA11 and PA12*/
hudakz 0:e29bc8e0dddd 117 __HAL_RCC_AFIO_CLK_ENABLE();
hudakz 0:e29bc8e0dddd 118 __HAL_AFIO_REMAP_CAN1_1();
hudakz 0:e29bc8e0dddd 119
hudakz 0:e29bc8e0dddd 120 /* CAN1 RX GPIO pin configuration */
hudakz 0:e29bc8e0dddd 121 GPIO_InitStruct.Pin = GPIO_PIN_11;
hudakz 0:e29bc8e0dddd 122 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
hudakz 0:e29bc8e0dddd 123 GPIO_InitStruct.Pull = GPIO_NOPULL;
hudakz 0:e29bc8e0dddd 124 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hudakz 0:e29bc8e0dddd 125
hudakz 0:e29bc8e0dddd 126 GPIO_InitStruct.Pin = GPIO_PIN_12;
hudakz 0:e29bc8e0dddd 127 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
hudakz 0:e29bc8e0dddd 128 GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
hudakz 0:e29bc8e0dddd 129 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hudakz 0:e29bc8e0dddd 130 }
hudakz 0:e29bc8e0dddd 131 else
hudakz 0:e29bc8e0dddd 132 if((_rxPin == PB_8) && (_txPin == PB_9)) {
hudakz 0:e29bc8e0dddd 133
hudakz 0:e29bc8e0dddd 134 /* CAN1 Periph clock enable */
hudakz 0:e29bc8e0dddd 135 __HAL_RCC_CAN1_CLK_ENABLE();
hudakz 0:e29bc8e0dddd 136
hudakz 0:e29bc8e0dddd 137 /* Enable GPIO clock */
hudakz 0:e29bc8e0dddd 138 __HAL_RCC_GPIOB_CLK_ENABLE();
hudakz 0:e29bc8e0dddd 139
hudakz 0:e29bc8e0dddd 140 /* Enable AFIO clock and remap CAN PINs to PB_8 and PB_9*/
hudakz 0:e29bc8e0dddd 141 __HAL_RCC_AFIO_CLK_ENABLE();
hudakz 0:e29bc8e0dddd 142 __HAL_AFIO_REMAP_CAN1_2();
hudakz 0:e29bc8e0dddd 143
hudakz 0:e29bc8e0dddd 144 /* CAN1 RX GPIO pin configuration */
hudakz 0:e29bc8e0dddd 145 GPIO_InitStruct.Pin = GPIO_PIN_8;
hudakz 0:e29bc8e0dddd 146 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
hudakz 0:e29bc8e0dddd 147 GPIO_InitStruct.Pull = GPIO_NOPULL;
hudakz 0:e29bc8e0dddd 148 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
hudakz 0:e29bc8e0dddd 149
hudakz 0:e29bc8e0dddd 150 GPIO_InitStruct.Pin = GPIO_PIN_9;
hudakz 0:e29bc8e0dddd 151 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
hudakz 0:e29bc8e0dddd 152 GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
hudakz 0:e29bc8e0dddd 153 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
hudakz 0:e29bc8e0dddd 154 }
hudakz 0:e29bc8e0dddd 155 else
hudakz 0:e29bc8e0dddd 156 return;
hudakz 0:e29bc8e0dddd 157
hudakz 0:e29bc8e0dddd 158 /* NVIC configuration for CAN1 Reception complete interrupt */
hudakz 0:e29bc8e0dddd 159 HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 1, 0);
hudakz 0:e29bc8e0dddd 160 HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
hudakz 0:e29bc8e0dddd 161 }
hudakz 0:e29bc8e0dddd 162
hudakz 0:e29bc8e0dddd 163 /**
hudakz 0:e29bc8e0dddd 164 * @brief CAN MSP De-Initialization
hudakz 0:e29bc8e0dddd 165 * This function frees the hardware resources used:
hudakz 0:e29bc8e0dddd 166 * - Disable the Peripheral's clock
hudakz 0:e29bc8e0dddd 167 * - Revert GPIO to their default state
hudakz 0:e29bc8e0dddd 168 * @param hcan: CAN handle pointer
hudakz 0:e29bc8e0dddd 169 * @retval None
hudakz 0:e29bc8e0dddd 170 */
hudakz 0:e29bc8e0dddd 171 void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan) {
hudakz 0:e29bc8e0dddd 172
hudakz 0:e29bc8e0dddd 173 /* Reset peripherals */
hudakz 0:e29bc8e0dddd 174
hudakz 0:e29bc8e0dddd 175 __HAL_RCC_CAN1_FORCE_RESET();
hudakz 0:e29bc8e0dddd 176 __HAL_RCC_CAN1_RELEASE_RESET();
hudakz 0:e29bc8e0dddd 177
hudakz 0:e29bc8e0dddd 178 /* Disable peripherals and GPIO Clocks */
hudakz 0:e29bc8e0dddd 179 if((_rxPin == PA_11) && (_txPin == PA_12)) {
hudakz 0:e29bc8e0dddd 180
hudakz 0:e29bc8e0dddd 181 /* De-initialize the CAN1 TX GPIO pin */
hudakz 0:e29bc8e0dddd 182 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11);
hudakz 0:e29bc8e0dddd 183
hudakz 0:e29bc8e0dddd 184 /* De-initialize the CAN1 RX GPIO pin */
hudakz 0:e29bc8e0dddd 185 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12);
hudakz 0:e29bc8e0dddd 186 }
hudakz 0:e29bc8e0dddd 187 else {
hudakz 0:e29bc8e0dddd 188
hudakz 0:e29bc8e0dddd 189 /* De-initialize the CAN1 TX GPIO pin */
hudakz 0:e29bc8e0dddd 190 HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8);
hudakz 0:e29bc8e0dddd 191
hudakz 0:e29bc8e0dddd 192 /* De-initialize the CAN1 RX GPIO pin */
hudakz 0:e29bc8e0dddd 193 HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);
hudakz 0:e29bc8e0dddd 194 }
hudakz 0:e29bc8e0dddd 195
hudakz 0:e29bc8e0dddd 196 /* Disable the NVIC for CAN reception */
hudakz 0:e29bc8e0dddd 197 HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
hudakz 0:e29bc8e0dddd 198 }
hudakz 0:e29bc8e0dddd 199
hudakz 0:e29bc8e0dddd 200 /**
hudakz 0:e29bc8e0dddd 201 * @brief Handles CAN1 RX0 interrupt request.
hudakz 0:e29bc8e0dddd 202 * @param None
hudakz 0:e29bc8e0dddd 203 * @retval None
hudakz 0:e29bc8e0dddd 204 */
hudakz 0:e29bc8e0dddd 205 void USB_LP_CAN1_RX0_IRQHandler(void) {
hudakz 0:e29bc8e0dddd 206 HAL_CAN_IRQHandler(&_canHandle);
hudakz 0:e29bc8e0dddd 207 }
hudakz 0:e29bc8e0dddd 208
hudakz 0:e29bc8e0dddd 209 /**
hudakz 0:e29bc8e0dddd 210 * @brief Reception complete callback in non blocking mode
hudakz 0:e29bc8e0dddd 211 * @param _canHandle: pointer to a CAN_HandleTypeDef structure that contains
hudakz 0:e29bc8e0dddd 212 * the configuration information for the specified CAN.
hudakz 0:e29bc8e0dddd 213 * @retval None
hudakz 0:e29bc8e0dddd 214 */
hudakz 0:e29bc8e0dddd 215 void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* _canHandle) {
hudakz 0:e29bc8e0dddd 216 // if(HAL_CAN_Receive_IT(_canHandle, CAN_FIFO0) == HAL_OK) {
hudakz 0:e29bc8e0dddd 217 // if(rxCompleteCallback != NULL)
hudakz 0:e29bc8e0dddd 218 // rxCompleteCallback();
hudakz 0:e29bc8e0dddd 219 // }
hudakz 0:e29bc8e0dddd 220 // else {
hudakz 0:e29bc8e0dddd 221 // error_handler(error);
hudakz 0:e29bc8e0dddd 222 // }
hudakz 0:e29bc8e0dddd 223
hudakz 0:e29bc8e0dddd 224 // BUG: CAN race condition if HAL_CAN_Receive_IT() is used.
hudakz 0:e29bc8e0dddd 225 // See https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Java%2FBUG%20CAN%20race%20condition%20if%20HAL%5FCAN%5FReceive%5FIT%20is%20used
hudakz 0:e29bc8e0dddd 226 //
hudakz 0:e29bc8e0dddd 227 // Fixed by Mark Burton:
hudakz 0:e29bc8e0dddd 228 // ideally, we should be able to call HAL_CAN_Receive_IT() here to set up for another
hudakz 0:e29bc8e0dddd 229 // receive but the API is flawed because that function will fail if HAL_CAN_Transmit()
hudakz 0:e29bc8e0dddd 230 // had already locked the handle when the receive interrupt occurred - so we do what
hudakz 0:e29bc8e0dddd 231 // HAL_CAN_Receive_IT() would do
hudakz 0:e29bc8e0dddd 232
hudakz 0:e29bc8e0dddd 233 if (rxCompleteCallback != NULL)
hudakz 0:e29bc8e0dddd 234 rxCompleteCallback();
hudakz 0:e29bc8e0dddd 235
hudakz 0:e29bc8e0dddd 236 if (_canHandle->State == HAL_CAN_STATE_BUSY_TX)
hudakz 0:e29bc8e0dddd 237 _canHandle->State = HAL_CAN_STATE_BUSY_TX_RX;
hudakz 0:e29bc8e0dddd 238 else {
hudakz 0:e29bc8e0dddd 239 _canHandle->State = HAL_CAN_STATE_BUSY_RX;
hudakz 0:e29bc8e0dddd 240
hudakz 0:e29bc8e0dddd 241 /* Set CAN error code to none */
hudakz 0:e29bc8e0dddd 242 _canHandle->ErrorCode = HAL_CAN_ERROR_NONE;
hudakz 0:e29bc8e0dddd 243
hudakz 0:e29bc8e0dddd 244 /* Enable Error warning Interrupt */
hudakz 0:e29bc8e0dddd 245 __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_EWG);
hudakz 0:e29bc8e0dddd 246
hudakz 0:e29bc8e0dddd 247 /* Enable Error passive Interrupt */
hudakz 0:e29bc8e0dddd 248 __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_EPV);
hudakz 0:e29bc8e0dddd 249
hudakz 0:e29bc8e0dddd 250 /* Enable Bus-off Interrupt */
hudakz 0:e29bc8e0dddd 251 __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_BOF);
hudakz 0:e29bc8e0dddd 252
hudakz 0:e29bc8e0dddd 253 /* Enable Last error code Interrupt */
hudakz 0:e29bc8e0dddd 254 __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_LEC);
hudakz 0:e29bc8e0dddd 255
hudakz 0:e29bc8e0dddd 256 /* Enable Error Interrupt */
hudakz 0:e29bc8e0dddd 257 __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_ERR);
hudakz 0:e29bc8e0dddd 258 }
hudakz 0:e29bc8e0dddd 259
hudakz 0:e29bc8e0dddd 260 // Enable FIFO 0 message pending Interrupt
hudakz 0:e29bc8e0dddd 261 __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_FMP0);
hudakz 0:e29bc8e0dddd 262 }