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 May 28 09:18:54 2017 +0000
Revision:
29:cebc6f21046e
Parent:
28:5a6ce4dc88c6
Updated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:e29bc8e0dddd 1 /* mbed Microcontroller Library
hudakz 0:e29bc8e0dddd 2 * Copyright (c) 2006-2013 ARM Limited
hudakz 0:e29bc8e0dddd 3 *
hudakz 0:e29bc8e0dddd 4 * Licensed under the Apache License, Version 2.0 (the "License");
hudakz 0:e29bc8e0dddd 5 * you may not use this file except in compliance with the License.
hudakz 0:e29bc8e0dddd 6 * You may obtain a copy of the License at
hudakz 0:e29bc8e0dddd 7 *
hudakz 0:e29bc8e0dddd 8 * http://www.apache.org/licenses/LICENSE-2.0
hudakz 0:e29bc8e0dddd 9 *
hudakz 0:e29bc8e0dddd 10 * Unless required by applicable law or agreed to in writing, software
hudakz 0:e29bc8e0dddd 11 * distributed under the License is distributed on an "AS IS" BASIS,
hudakz 0:e29bc8e0dddd 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
hudakz 0:e29bc8e0dddd 13 * See the License for the specific language governing permissions and
hudakz 0:e29bc8e0dddd 14 * limitations under the License.
hudakz 0:e29bc8e0dddd 15 *
hudakz 27:eed6929956ea 16 * Modified by Zoltan Hudak <hudakz@outlook.com>
hudakz 0:e29bc8e0dddd 17 *
hudakz 0:e29bc8e0dddd 18 */
hudakz 21:d51e1617975f 19 #include "CANnucleo.h"
hudakz 0:e29bc8e0dddd 20 #include "cmsis.h"
hudakz 0:e29bc8e0dddd 21
hudakz 0:e29bc8e0dddd 22 /**
hudakz 6:c5a40d5fd9f1 23 * @brief Constructor
hudakz 6:c5a40d5fd9f1 24 * @note Constructs an instance of CAN class
hudakz 6:c5a40d5fd9f1 25 * @param rxPin: CAN Rx pin name
hudakz 6:c5a40d5fd9f1 26 * @param txPin: CAN Tx pin name
hudakz 6:c5a40d5fd9f1 27 * @param abom: Automatic recovery from bus-off state (defaults to enabled)
hudakz 0:e29bc8e0dddd 28 * @retval
hudakz 0:e29bc8e0dddd 29 */
hudakz 6:c5a40d5fd9f1 30 CAN::CAN(PinName rxPin, PinName txPin, FunctionalState abom /* = ENABLE */) :
hudakz 0:e29bc8e0dddd 31 _irq() {
hudakz 20:bcd8161f8f6c 32 can_init(rxPin, txPin, abom);
hudakz 20:bcd8161f8f6c 33 can_irq_init((uint32_t)this, (&CAN::_irq_handler));
hudakz 0:e29bc8e0dddd 34 }
hudakz 0:e29bc8e0dddd 35
hudakz 0:e29bc8e0dddd 36 /**
hudakz 0:e29bc8e0dddd 37 * @brief
hudakz 0:e29bc8e0dddd 38 * @note
hudakz 0:e29bc8e0dddd 39 * @param
hudakz 0:e29bc8e0dddd 40 * @retval
hudakz 0:e29bc8e0dddd 41 */
hudakz 0:e29bc8e0dddd 42 CAN::~CAN(void) {
hudakz 20:bcd8161f8f6c 43 can_irq_free();
hudakz 20:bcd8161f8f6c 44 can_free();
hudakz 0:e29bc8e0dddd 45 }
hudakz 0:e29bc8e0dddd 46
hudakz 0:e29bc8e0dddd 47 /**
hudakz 0:e29bc8e0dddd 48 * @brief
hudakz 0:e29bc8e0dddd 49 * @note
hudakz 0:e29bc8e0dddd 50 * @param
hudakz 0:e29bc8e0dddd 51 * @retval
hudakz 0:e29bc8e0dddd 52 */
hudakz 0:e29bc8e0dddd 53 int CAN::frequency(int f) {
hudakz 24:353237492903 54 lock();
hudakz 24:353237492903 55 int ret = can_frequency(f);
hudakz 24:353237492903 56 unlock();
hudakz 24:353237492903 57 return ret;
hudakz 0:e29bc8e0dddd 58 }
hudakz 0:e29bc8e0dddd 59
hudakz 0:e29bc8e0dddd 60 /**
hudakz 0:e29bc8e0dddd 61 * @brief
hudakz 0:e29bc8e0dddd 62 * @note
hudakz 0:e29bc8e0dddd 63 * @param
hudakz 0:e29bc8e0dddd 64 * @retval
hudakz 0:e29bc8e0dddd 65 */
hudakz 0:e29bc8e0dddd 66 int CAN::write(CANMessage msg) {
hudakz 24:353237492903 67 lock();
hudakz 24:353237492903 68 int ret = can_write(msg, 0);
hudakz 24:353237492903 69 unlock();
hudakz 24:353237492903 70 return ret;
hudakz 0:e29bc8e0dddd 71 }
hudakz 0:e29bc8e0dddd 72
hudakz 0:e29bc8e0dddd 73 /**
hudakz 0:e29bc8e0dddd 74 * @brief
hudakz 0:e29bc8e0dddd 75 * @note
hudakz 0:e29bc8e0dddd 76 * @param
hudakz 0:e29bc8e0dddd 77 * @retval
hudakz 0:e29bc8e0dddd 78 */
hudakz 0:e29bc8e0dddd 79 int CAN::read(CANMessage& msg, int handle) {
hudakz 24:353237492903 80 lock();
hudakz 24:353237492903 81 int ret = can_read(&msg, handle);
hudakz 24:353237492903 82 unlock();
hudakz 24:353237492903 83 return ret;
hudakz 0:e29bc8e0dddd 84 }
hudakz 0:e29bc8e0dddd 85
hudakz 0:e29bc8e0dddd 86 /**
hudakz 0:e29bc8e0dddd 87 * @brief
hudakz 0:e29bc8e0dddd 88 * @note
hudakz 0:e29bc8e0dddd 89 * @param
hudakz 0:e29bc8e0dddd 90 * @retval
hudakz 0:e29bc8e0dddd 91 */
hudakz 0:e29bc8e0dddd 92 void CAN::reset(void) {
hudakz 24:353237492903 93 lock();
hudakz 20:bcd8161f8f6c 94 can_reset();
hudakz 24:353237492903 95 unlock();
hudakz 0:e29bc8e0dddd 96 }
hudakz 0:e29bc8e0dddd 97
hudakz 0:e29bc8e0dddd 98 /**
hudakz 0:e29bc8e0dddd 99 * @brief
hudakz 0:e29bc8e0dddd 100 * @note
hudakz 0:e29bc8e0dddd 101 * @param
hudakz 0:e29bc8e0dddd 102 * @retval
hudakz 0:e29bc8e0dddd 103 */
hudakz 0:e29bc8e0dddd 104 unsigned char CAN::rderror(void) {
hudakz 24:353237492903 105 lock();
hudakz 24:353237492903 106 unsigned char ret = can_rderror();
hudakz 24:353237492903 107 unlock();
hudakz 24:353237492903 108 return ret;
hudakz 0:e29bc8e0dddd 109 }
hudakz 0:e29bc8e0dddd 110
hudakz 0:e29bc8e0dddd 111 /**
hudakz 0:e29bc8e0dddd 112 * @brief
hudakz 0:e29bc8e0dddd 113 * @note
hudakz 0:e29bc8e0dddd 114 * @param
hudakz 0:e29bc8e0dddd 115 * @retval
hudakz 0:e29bc8e0dddd 116 */
hudakz 0:e29bc8e0dddd 117 unsigned char CAN::tderror(void) {
hudakz 24:353237492903 118 lock();
hudakz 24:353237492903 119 unsigned char ret = can_tderror();
hudakz 24:353237492903 120 unlock();
hudakz 24:353237492903 121 return ret;
hudakz 0:e29bc8e0dddd 122 }
hudakz 0:e29bc8e0dddd 123
hudakz 0:e29bc8e0dddd 124 /**
hudakz 0:e29bc8e0dddd 125 * @brief
hudakz 0:e29bc8e0dddd 126 * @note
hudakz 0:e29bc8e0dddd 127 * @param
hudakz 0:e29bc8e0dddd 128 * @retval
hudakz 0:e29bc8e0dddd 129 */
hudakz 0:e29bc8e0dddd 130 void CAN::monitor(bool silent) {
hudakz 24:353237492903 131 lock();
hudakz 20:bcd8161f8f6c 132 can_monitor((silent) ? 1 : 0);
hudakz 24:353237492903 133 unlock();
hudakz 0:e29bc8e0dddd 134 }
hudakz 0:e29bc8e0dddd 135
hudakz 0:e29bc8e0dddd 136 /**
hudakz 0:e29bc8e0dddd 137 * @brief
hudakz 0:e29bc8e0dddd 138 * @note
hudakz 0:e29bc8e0dddd 139 * @param
hudakz 0:e29bc8e0dddd 140 * @retval
hudakz 0:e29bc8e0dddd 141 */
hudakz 0:e29bc8e0dddd 142 int CAN::mode(Mode mode) {
hudakz 24:353237492903 143 lock();
hudakz 24:353237492903 144 int ret = can_mode((CanMode) mode);
hudakz 24:353237492903 145 unlock();
hudakz 24:353237492903 146 return ret;
hudakz 0:e29bc8e0dddd 147 }
hudakz 0:e29bc8e0dddd 148
hudakz 0:e29bc8e0dddd 149 /**
hudakz 9:e9224f2c6d37 150 * @brief Sets up a CAN filter
hudakz 8:5c90d6b9a382 151 * @note At the present, CANnucleo supports only mask mode and 32-bit filter scale.
hudakz 8:5c90d6b9a382 152 * Identifier list mode filtering and 16-bit filter scale are not supported.
hudakz 9:e9224f2c6d37 153 * There are 14 filters available (0 - 13) for the application to set up.
hudakz 8:5c90d6b9a382 154 * Each filter is a 32-bit filter defined by a filter ID and a filter mask.
hudakz 9:e9224f2c6d37 155 * If no filter is set up then no CAN message is accepted (received)!
hudakz 9:e9224f2c6d37 156 * That's why filter #0 is set up in the constructor to receive all CAN messages by default.
hudakz 8:5c90d6b9a382 157 * On reception of a message it is compared with filter #0. If there is a match, the message is stored.
hudakz 8:5c90d6b9a382 158 * If there is no match, the incoming identifier is then compared with the next filter.
hudakz 8:5c90d6b9a382 159 * If the received identifier does not match any of the identifiers configured in the filters,
hudakz 8:5c90d6b9a382 160 * the message is discarded by hardware without disturbing the software.
hudakz 8:5c90d6b9a382 161 *
hudakz 8:5c90d6b9a382 162 * @param id: 'Filter ID' defines the bit values to be compared with the corresponding received bits
hudakz 8:5c90d6b9a382 163 *
hudakz 8:5c90d6b9a382 164 * Mapping of 32-bits (4-bytes) : | STID[10:3] | STID[2:0] EXID[17:13] | EXID[12:5] | EXID[4:0] IDE RTR 0 |
hudakz 8:5c90d6b9a382 165 *
hudakz 8:5c90d6b9a382 166 * STID - Stardard Identifier bits
hudakz 8:5c90d6b9a382 167 * EXID - Extended Identifier bits
hudakz 8:5c90d6b9a382 168 * [x:y]- bit range
hudakz 8:5c90d6b9a382 169 * IDE - Identifier Extension bit (0 -> Standard Identifier, 1 -> Extended Identifier)
hudakz 9:e9224f2c6d37 170 * RTR - Remote Transmission Request bit (0 -> Remote Transmission Request, 1 -> Standard message)
hudakz 8:5c90d6b9a382 171 *
hudakz 8:5c90d6b9a382 172 * @param mask: 'Filter mask' defines which bits of the 'Filter ID' are compared with the received bits
hudakz 8:5c90d6b9a382 173 * and which bits are disregarded.
hudakz 8:5c90d6b9a382 174
hudakz 8:5c90d6b9a382 175 * Mapping of 32-bits (4-bytes) : | STID[10:3] | STID[2:0] EXID[17:13] | EXID[12:5] | EXID[4:0] IDE RTR 0 |
hudakz 8:5c90d6b9a382 176 *
hudakz 8:5c90d6b9a382 177 * STID - Stardard Identifier bits
hudakz 8:5c90d6b9a382 178 * EXID - Extended Identifier bits
hudakz 8:5c90d6b9a382 179 * [x:y]- bit range
hudakz 8:5c90d6b9a382 180 * IDE - Identifier Extension bit
hudakz 8:5c90d6b9a382 181 * RTR - Remote Transmission Request bit
hudakz 8:5c90d6b9a382 182 *
hudakz 10:227a455d0f9f 183 * 1 -> bit is considered
hudakz 10:227a455d0f9f 184 * 0 -> bit is disregarded
hudakz 8:5c90d6b9a382 185 *
hudakz 10:227a455d0f9f 186 * ----------------------------------------
hudakz 10:227a455d0f9f 187 * Example of filter set up and filtering:
hudakz 10:227a455d0f9f 188 * ----------------------------------------
hudakz 10:227a455d0f9f 189 *
hudakz 10:227a455d0f9f 190 * Let's assume we would like to receive only messages
hudakz 10:227a455d0f9f 191 * with standard identifier STID = 0x0207 (STID[15:0] = 00000010 00000111)
hudakz 8:5c90d6b9a382 192 *
hudakz 8:5c90d6b9a382 193 * We map the STID to filter ID by shifting the bits appropriately:
hudakz 8:5c90d6b9a382 194 * Filter id = STID << (16 + (15 - 10)) = STID << 21 = 01000000 11100000 00000000 00000000 = 0x40E00000
hudakz 8:5c90d6b9a382 195 *
hudakz 8:5c90d6b9a382 196 * To compare only the bits representing STID we set the filter mask adequately:
hudakz 9:e9224f2c6d37 197 * Filter mask = 11111111 11100000 00000000 00000100 = 0xFFE00004
hudakz 14:0344705e6fb8 198 * |||||||| ||| |
hudakz 14:0344705e6fb8 199 * -------- --- |
hudakz 14:0344705e6fb8 200 * | | |
hudakz 14:0344705e6fb8 201 * STID[10:3] STID[2:0] IDE
hudakz 8:5c90d6b9a382 202 *
hudakz 20:bcd8161f8f6c 203 * Recall that filter #0 has been set up in the constructor to receive all CAN messages by default.
hudakz 9:e9224f2c6d37 204 * So we have to reconfigure it. If we were set up filter #1 here then filter #0 would receive all the messages
hudakz 8:5c90d6b9a382 205 * and no message would reach filter #1!
hudakz 9:e9224f2c6d37 206 *
hudakz 20:bcd8161f8f6c 207 * To reconfigure (set up) filter #0 we call:
hudakz 9:e9224f2c6d37 208 * can.filter(0x0207 << 21, 0xFFE00004, CANAny, 0);
hudakz 8:5c90d6b9a382 209 *
hudakz 20:bcd8161f8f6c 210 * Only these bits of 'Filter id' (set to 1 here in 'Filter mask') are compared with the corresponding
hudakz 9:e9224f2c6d37 211 * bits of received message (the others are disregarded)
hudakz 11:439f3a34c42e 212 * |
hudakz 11:439f3a34c42e 213 * ---------------------------------
hudakz 11:439f3a34c42e 214 * |||||||| ||| |
hudakz 9:e9224f2c6d37 215 * Filter mask = 11111111 11100000 00000000 00000100 (= 0xFFE00004)
hudakz 9:e9224f2c6d37 216 * Filter id = 01000000 11100000 00000000 00000000 (= 0x40E00000)
hudakz 11:439f3a34c42e 217 * |||||||| ||| |
hudakz 11:439f3a34c42e 218 * ---------------------------------
hudakz 11:439f3a34c42e 219 * |
hudakz 11:439f3a34c42e 220 * To receive the message the values of these bits must match.
hudakz 11:439f3a34c42e 221 * Otherwise the message is passed to the next filter or
hudakz 9:e9224f2c6d37 222 * discarded if this was the last active filter.
hudakz 11:439f3a34c42e 223 * |
hudakz 11:439f3a34c42e 224 * ---------------------------------
hudakz 11:439f3a34c42e 225 * |||||||| ||| |
hudakz 9:e9224f2c6d37 226 * Received id = 01000000 11100000 00000000 00000010 (= 0x40E00002)
hudakz 11:439f3a34c42e 227 * ||||| |||||||| ||||| ||
hudakz 11:439f3a34c42e 228 * -----------------------
hudakz 11:439f3a34c42e 229 * |
hudakz 20:bcd8161f8f6c 230 * These bits (set to 0 in 'Filter mask') are disregarded (masked).
hudakz 9:e9224f2c6d37 231 * They can have arbitrary values.
hudakz 8:5c90d6b9a382 232 *
hudakz 8:5c90d6b9a382 233 * NOTE: For the meaning of individual bits see the mapping of 32-bits explained above.
hudakz 8:5c90d6b9a382 234 *
hudakz 9:e9224f2c6d37 235 * @param format: This parameter must be CANAny
hudakz 9:e9224f2c6d37 236 * @param handle: Selects the filter. This parameter must be a number between 0 and 13.
hudakz 20:bcd8161f8f6c 237 * @retval 0 - successful
hudakz 20:bcd8161f8f6c 238 * 1 - error
hudakz 20:bcd8161f8f6c 239 * 2 - busy
hudakz 20:bcd8161f8f6c 240 * 3 - time out
hudakz 0:e29bc8e0dddd 241 */
hudakz 8:5c90d6b9a382 242 int CAN::filter(unsigned int id, unsigned int mask, CANFormat format /* = CANAny */, int handle /* = 0 */) {
hudakz 24:353237492903 243 lock();
hudakz 24:353237492903 244 int ret = can_filter(id, mask, format, handle);
hudakz 24:353237492903 245 unlock();
hudakz 24:353237492903 246 return ret;
hudakz 0:e29bc8e0dddd 247 }
hudakz 0:e29bc8e0dddd 248
hudakz 0:e29bc8e0dddd 249 /**
hudakz 0:e29bc8e0dddd 250 * @brief Attaches handler funcion to CAN1 RX0 Interrupt
hudakz 0:e29bc8e0dddd 251 * @note Only CAN1 RX0 Interrupt supported
hudakz 0:e29bc8e0dddd 252 * @param fptr: pointer to a void (*)(void) function
hudakz 0:e29bc8e0dddd 253 * @param type: not used (only CAN1 RX0 Interrupt supported)
hudakz 0:e29bc8e0dddd 254 * @retval
hudakz 0:e29bc8e0dddd 255 */
hudakz 24:353237492903 256 void CAN::attach(mbed::Callback<void()> func, IrqType type) {
hudakz 24:353237492903 257 lock();
hudakz 14:0344705e6fb8 258 HAL_NVIC_DisableIRQ(CAN_IRQ);
hudakz 24:353237492903 259 if (func)
hudakz 29:cebc6f21046e 260 _irq[(CanIrqType)type] = func;
hudakz 14:0344705e6fb8 261 HAL_NVIC_EnableIRQ(CAN_IRQ);
hudakz 24:353237492903 262 unlock();
hudakz 0:e29bc8e0dddd 263 }
hudakz 0:e29bc8e0dddd 264
hudakz 0:e29bc8e0dddd 265 /**
hudakz 0:e29bc8e0dddd 266 * @brief
hudakz 0:e29bc8e0dddd 267 * @note
hudakz 0:e29bc8e0dddd 268 * @param
hudakz 0:e29bc8e0dddd 269 * @retval
hudakz 0:e29bc8e0dddd 270 */
hudakz 0:e29bc8e0dddd 271 void CAN::_irq_handler(uint32_t id, CanIrqType type) {
hudakz 0:e29bc8e0dddd 272 CAN* handler = (CAN*)id;
hudakz 0:e29bc8e0dddd 273 handler->_irq[type].call();
hudakz 0:e29bc8e0dddd 274 }
hudakz 0:e29bc8e0dddd 275
hudakz 24:353237492903 276 void CAN::lock() {
hudakz 24:353237492903 277 _mutex.lock();
hudakz 24:353237492903 278 }
hudakz 24:353237492903 279
hudakz 24:353237492903 280 void CAN::unlock() {
hudakz 24:353237492903 281 _mutex.unlock();
hudakz 24:353237492903 282 }
hudakz 24:353237492903 283
hudakz 0:e29bc8e0dddd 284
hudakz 0:e29bc8e0dddd 285
hudakz 0:e29bc8e0dddd 286
hudakz 5:b53e5ee15315 287
hudakz 6:c5a40d5fd9f1 288
hudakz 11:439f3a34c42e 289
hudakz 20:bcd8161f8f6c 290
hudakz 20:bcd8161f8f6c 291
hudakz 24:353237492903 292
hudakz 24:353237492903 293
hudakz 27:eed6929956ea 294