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:
Tue Dec 22 20:46:47 2015 +0000
Revision:
12:c45310ff2233
Parent:
11:439f3a34c42e
Child:
13:a3e2be3d49a2
Support for NUCLEO-F302R8, NUCLEO-F303K8, NUCLEO-F334R8 and DISCO-F334C8 added.

Who changed what in which revision?

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