Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of CANnucleo by
CAN.cpp@18:cdab1fd4ff26, 2016-01-07 (annotated)
- Committer:
- ptpaterson
- Date:
- Thu Jan 07 04:23:51 2016 +0000
- Revision:
- 18:cdab1fd4ff26
- Parent:
- 14:0344705e6fb8
Corrected interrupts for F0 chip
Who changed what in which revision?
| User | Revision | Line number | New 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 | 0:e29bc8e0dddd | 16 | * Modified by Zoltan Hudak <hudakz@inbox.com> |
| hudakz | 0:e29bc8e0dddd | 17 | * |
| hudakz | 0:e29bc8e0dddd | 18 | */ |
| hudakz | 0:e29bc8e0dddd | 19 | #include "CAN.h" |
| hudakz | 0:e29bc8e0dddd | 20 | #include "cmsis.h" |
| hudakz | 0:e29bc8e0dddd | 21 | |
| hudakz | 0:e29bc8e0dddd | 22 | namespace mbed |
| hudakz | 0:e29bc8e0dddd | 23 | { |
| hudakz | 0:e29bc8e0dddd | 24 | |
| hudakz | 0:e29bc8e0dddd | 25 | /** |
| hudakz | 6:c5a40d5fd9f1 | 26 | * @brief Constructor |
| hudakz | 6:c5a40d5fd9f1 | 27 | * @note Constructs an instance of CAN class |
| hudakz | 6:c5a40d5fd9f1 | 28 | * @param rxPin: CAN Rx pin name |
| hudakz | 6:c5a40d5fd9f1 | 29 | * @param txPin: CAN Tx pin name |
| hudakz | 6:c5a40d5fd9f1 | 30 | * @param abom: Automatic recovery from bus-off state (defaults to enabled) |
| hudakz | 0:e29bc8e0dddd | 31 | * @retval |
| hudakz | 0:e29bc8e0dddd | 32 | */ |
| hudakz | 6:c5a40d5fd9f1 | 33 | CAN::CAN(PinName rxPin, PinName txPin, FunctionalState abom /* = ENABLE */) : |
| hudakz | 0:e29bc8e0dddd | 34 | _can(), |
| hudakz | 0:e29bc8e0dddd | 35 | _irq() { |
| hudakz | 6:c5a40d5fd9f1 | 36 | can_init(&_can, rxPin, txPin, abom); |
| hudakz | 0:e29bc8e0dddd | 37 | can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this); |
| hudakz | 0:e29bc8e0dddd | 38 | } |
| hudakz | 0:e29bc8e0dddd | 39 | |
| hudakz | 0:e29bc8e0dddd | 40 | /** |
| hudakz | 0:e29bc8e0dddd | 41 | * @brief |
| hudakz | 0:e29bc8e0dddd | 42 | * @note |
| hudakz | 0:e29bc8e0dddd | 43 | * @param |
| hudakz | 0:e29bc8e0dddd | 44 | * @retval |
| hudakz | 0:e29bc8e0dddd | 45 | */ |
| hudakz | 0:e29bc8e0dddd | 46 | CAN::~CAN(void) { |
| hudakz | 0:e29bc8e0dddd | 47 | can_irq_free(&_can); |
| hudakz | 0:e29bc8e0dddd | 48 | can_free(&_can); |
| hudakz | 0:e29bc8e0dddd | 49 | } |
| hudakz | 0:e29bc8e0dddd | 50 | |
| hudakz | 0:e29bc8e0dddd | 51 | /** |
| hudakz | 0:e29bc8e0dddd | 52 | * @brief |
| hudakz | 0:e29bc8e0dddd | 53 | * @note |
| hudakz | 0:e29bc8e0dddd | 54 | * @param |
| hudakz | 0:e29bc8e0dddd | 55 | * @retval |
| hudakz | 0:e29bc8e0dddd | 56 | */ |
| hudakz | 0:e29bc8e0dddd | 57 | int CAN::frequency(int f) { |
| hudakz | 0:e29bc8e0dddd | 58 | return can_frequency(&_can, f); |
| hudakz | 0:e29bc8e0dddd | 59 | } |
| hudakz | 0:e29bc8e0dddd | 60 | |
| hudakz | 0:e29bc8e0dddd | 61 | /** |
| hudakz | 0:e29bc8e0dddd | 62 | * @brief |
| hudakz | 0:e29bc8e0dddd | 63 | * @note |
| hudakz | 0:e29bc8e0dddd | 64 | * @param |
| hudakz | 0:e29bc8e0dddd | 65 | * @retval |
| hudakz | 0:e29bc8e0dddd | 66 | */ |
| hudakz | 0:e29bc8e0dddd | 67 | int CAN::write(CANMessage msg) { |
| hudakz | 0:e29bc8e0dddd | 68 | return can_write(&_can, msg, 0); |
| hudakz | 0:e29bc8e0dddd | 69 | } |
| hudakz | 0:e29bc8e0dddd | 70 | |
| hudakz | 0:e29bc8e0dddd | 71 | /** |
| hudakz | 0:e29bc8e0dddd | 72 | * @brief |
| hudakz | 0:e29bc8e0dddd | 73 | * @note |
| hudakz | 0:e29bc8e0dddd | 74 | * @param |
| hudakz | 0:e29bc8e0dddd | 75 | * @retval |
| hudakz | 0:e29bc8e0dddd | 76 | */ |
| hudakz | 0:e29bc8e0dddd | 77 | int CAN::read(CANMessage& msg, int handle) { |
| hudakz | 0:e29bc8e0dddd | 78 | return can_read(&_can, &msg, handle); |
| hudakz | 0:e29bc8e0dddd | 79 | } |
| hudakz | 0:e29bc8e0dddd | 80 | |
| hudakz | 0:e29bc8e0dddd | 81 | /** |
| hudakz | 0:e29bc8e0dddd | 82 | * @brief |
| hudakz | 0:e29bc8e0dddd | 83 | * @note |
| hudakz | 0:e29bc8e0dddd | 84 | * @param |
| hudakz | 0:e29bc8e0dddd | 85 | * @retval |
| hudakz | 0:e29bc8e0dddd | 86 | */ |
| hudakz | 0:e29bc8e0dddd | 87 | void CAN::reset(void) { |
| hudakz | 0:e29bc8e0dddd | 88 | can_reset(&_can); |
| hudakz | 0:e29bc8e0dddd | 89 | } |
| hudakz | 0:e29bc8e0dddd | 90 | |
| hudakz | 0:e29bc8e0dddd | 91 | /** |
| hudakz | 0:e29bc8e0dddd | 92 | * @brief |
| hudakz | 0:e29bc8e0dddd | 93 | * @note |
| hudakz | 0:e29bc8e0dddd | 94 | * @param |
| hudakz | 0:e29bc8e0dddd | 95 | * @retval |
| hudakz | 0:e29bc8e0dddd | 96 | */ |
| hudakz | 0:e29bc8e0dddd | 97 | unsigned char CAN::rderror(void) { |
| hudakz | 0:e29bc8e0dddd | 98 | return can_rderror(&_can); |
| hudakz | 0:e29bc8e0dddd | 99 | } |
| hudakz | 0:e29bc8e0dddd | 100 | |
| hudakz | 0:e29bc8e0dddd | 101 | /** |
| hudakz | 0:e29bc8e0dddd | 102 | * @brief |
| hudakz | 0:e29bc8e0dddd | 103 | * @note |
| hudakz | 0:e29bc8e0dddd | 104 | * @param |
| hudakz | 0:e29bc8e0dddd | 105 | * @retval |
| hudakz | 0:e29bc8e0dddd | 106 | */ |
| hudakz | 0:e29bc8e0dddd | 107 | unsigned char CAN::tderror(void) { |
| hudakz | 0:e29bc8e0dddd | 108 | return can_tderror(&_can); |
| 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 | void CAN::monitor(bool silent) { |
| hudakz | 0:e29bc8e0dddd | 118 | can_monitor(&_can, (silent) ? 1 : 0); |
| hudakz | 0:e29bc8e0dddd | 119 | } |
| hudakz | 0:e29bc8e0dddd | 120 | |
| hudakz | 0:e29bc8e0dddd | 121 | /** |
| hudakz | 0:e29bc8e0dddd | 122 | * @brief |
| hudakz | 0:e29bc8e0dddd | 123 | * @note |
| hudakz | 0:e29bc8e0dddd | 124 | * @param |
| hudakz | 0:e29bc8e0dddd | 125 | * @retval |
| hudakz | 0:e29bc8e0dddd | 126 | */ |
| hudakz | 0:e29bc8e0dddd | 127 | int CAN::mode(Mode mode) { |
| hudakz | 0:e29bc8e0dddd | 128 | return can_mode(&_can, (CanMode) mode); |
| hudakz | 0:e29bc8e0dddd | 129 | } |
| hudakz | 0:e29bc8e0dddd | 130 | |
| hudakz | 0:e29bc8e0dddd | 131 | /** |
| hudakz | 9:e9224f2c6d37 | 132 | * @brief Sets up a CAN filter |
| hudakz | 8:5c90d6b9a382 | 133 | * @note At the present, CANnucleo supports only mask mode and 32-bit filter scale. |
| hudakz | 8:5c90d6b9a382 | 134 | * Identifier list mode filtering and 16-bit filter scale are not supported. |
| hudakz | 9:e9224f2c6d37 | 135 | * There are 14 filters available (0 - 13) for the application to set up. |
| hudakz | 8:5c90d6b9a382 | 136 | * Each filter is a 32-bit filter defined by a filter ID and a filter mask. |
| hudakz | 9:e9224f2c6d37 | 137 | * If no filter is set up then no CAN message is accepted (received)! |
| hudakz | 9:e9224f2c6d37 | 138 | * That's why filter #0 is set up in the constructor to receive all CAN messages by default. |
| hudakz | 8:5c90d6b9a382 | 139 | * On reception of a message it is compared with filter #0. If there is a match, the message is stored. |
| hudakz | 8:5c90d6b9a382 | 140 | * If there is no match, the incoming identifier is then compared with the next filter. |
| hudakz | 8:5c90d6b9a382 | 141 | * If the received identifier does not match any of the identifiers configured in the filters, |
| hudakz | 8:5c90d6b9a382 | 142 | * the message is discarded by hardware without disturbing the software. |
| hudakz | 8:5c90d6b9a382 | 143 | * |
| hudakz | 8:5c90d6b9a382 | 144 | * @param id: 'Filter ID' defines the bit values to be compared with the corresponding received bits |
| hudakz | 8:5c90d6b9a382 | 145 | * |
| hudakz | 8:5c90d6b9a382 | 146 | * 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 | 147 | * |
| hudakz | 8:5c90d6b9a382 | 148 | * STID - Stardard Identifier bits |
| hudakz | 8:5c90d6b9a382 | 149 | * EXID - Extended Identifier bits |
| hudakz | 8:5c90d6b9a382 | 150 | * [x:y]- bit range |
| hudakz | 8:5c90d6b9a382 | 151 | * IDE - Identifier Extension bit (0 -> Standard Identifier, 1 -> Extended Identifier) |
| hudakz | 9:e9224f2c6d37 | 152 | * RTR - Remote Transmission Request bit (0 -> Remote Transmission Request, 1 -> Standard message) |
| hudakz | 8:5c90d6b9a382 | 153 | * |
| hudakz | 8:5c90d6b9a382 | 154 | * @param mask: 'Filter mask' defines which bits of the 'Filter ID' are compared with the received bits |
| hudakz | 8:5c90d6b9a382 | 155 | * and which bits are disregarded. |
| hudakz | 8:5c90d6b9a382 | 156 | |
| hudakz | 8:5c90d6b9a382 | 157 | * 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 | 158 | * |
| hudakz | 8:5c90d6b9a382 | 159 | * STID - Stardard Identifier bits |
| hudakz | 8:5c90d6b9a382 | 160 | * EXID - Extended Identifier bits |
| hudakz | 8:5c90d6b9a382 | 161 | * [x:y]- bit range |
| hudakz | 8:5c90d6b9a382 | 162 | * IDE - Identifier Extension bit |
| hudakz | 8:5c90d6b9a382 | 163 | * RTR - Remote Transmission Request bit |
| hudakz | 8:5c90d6b9a382 | 164 | * |
| hudakz | 10:227a455d0f9f | 165 | * 1 -> bit is considered |
| hudakz | 10:227a455d0f9f | 166 | * 0 -> bit is disregarded |
| hudakz | 8:5c90d6b9a382 | 167 | * |
| hudakz | 10:227a455d0f9f | 168 | * ---------------------------------------- |
| hudakz | 10:227a455d0f9f | 169 | * Example of filter set up and filtering: |
| hudakz | 10:227a455d0f9f | 170 | * ---------------------------------------- |
| hudakz | 10:227a455d0f9f | 171 | * |
| hudakz | 10:227a455d0f9f | 172 | * Let's assume we would like to receive only messages |
| hudakz | 10:227a455d0f9f | 173 | * with standard identifier STID = 0x0207 (STID[15:0] = 00000010 00000111) |
| hudakz | 8:5c90d6b9a382 | 174 | * |
| hudakz | 8:5c90d6b9a382 | 175 | * We map the STID to filter ID by shifting the bits appropriately: |
| hudakz | 8:5c90d6b9a382 | 176 | * Filter id = STID << (16 + (15 - 10)) = STID << 21 = 01000000 11100000 00000000 00000000 = 0x40E00000 |
| hudakz | 8:5c90d6b9a382 | 177 | * |
| hudakz | 8:5c90d6b9a382 | 178 | * To compare only the bits representing STID we set the filter mask adequately: |
| hudakz | 9:e9224f2c6d37 | 179 | * Filter mask = 11111111 11100000 00000000 00000100 = 0xFFE00004 |
| hudakz | 14:0344705e6fb8 | 180 | * |||||||| ||| | |
| hudakz | 14:0344705e6fb8 | 181 | * -------- --- | |
| hudakz | 14:0344705e6fb8 | 182 | * | | | |
| hudakz | 14:0344705e6fb8 | 183 | * STID[10:3] STID[2:0] IDE |
| hudakz | 8:5c90d6b9a382 | 184 | * |
| hudakz | 9:e9224f2c6d37 | 185 | * Keep in mind that filter #0 was already set up in the constructor to receive all CAN messages by default. |
| hudakz | 9:e9224f2c6d37 | 186 | * 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 | 187 | * and no message would reach filter #1! |
| hudakz | 9:e9224f2c6d37 | 188 | * |
| hudakz | 9:e9224f2c6d37 | 189 | * To set up filter #0 we call: |
| hudakz | 9:e9224f2c6d37 | 190 | * can.filter(0x0207 << 21, 0xFFE00004, CANAny, 0); |
| hudakz | 8:5c90d6b9a382 | 191 | * |
| hudakz | 14:0344705e6fb8 | 192 | * Only these bits (set to 1) of filter id are compared with the corresponding |
| hudakz | 9:e9224f2c6d37 | 193 | * bits of received message (the others are disregarded) |
| hudakz | 11:439f3a34c42e | 194 | * | |
| hudakz | 11:439f3a34c42e | 195 | * --------------------------------- |
| hudakz | 11:439f3a34c42e | 196 | * |||||||| ||| | |
| hudakz | 9:e9224f2c6d37 | 197 | * Filter mask = 11111111 11100000 00000000 00000100 (= 0xFFE00004) |
| hudakz | 9:e9224f2c6d37 | 198 | * Filter id = 01000000 11100000 00000000 00000000 (= 0x40E00000) |
| hudakz | 11:439f3a34c42e | 199 | * |||||||| ||| | |
| hudakz | 11:439f3a34c42e | 200 | * --------------------------------- |
| hudakz | 11:439f3a34c42e | 201 | * | |
| hudakz | 11:439f3a34c42e | 202 | * To receive the message the values of these bits must match. |
| hudakz | 11:439f3a34c42e | 203 | * Otherwise the message is passed to the next filter or |
| hudakz | 9:e9224f2c6d37 | 204 | * discarded if this was the last active filter. |
| hudakz | 11:439f3a34c42e | 205 | * | |
| hudakz | 11:439f3a34c42e | 206 | * --------------------------------- |
| hudakz | 11:439f3a34c42e | 207 | * |||||||| ||| | |
| hudakz | 9:e9224f2c6d37 | 208 | * Received id = 01000000 11100000 00000000 00000010 (= 0x40E00002) |
| hudakz | 11:439f3a34c42e | 209 | * ||||| |||||||| ||||| || |
| hudakz | 11:439f3a34c42e | 210 | * ----------------------- |
| hudakz | 11:439f3a34c42e | 211 | * | |
| hudakz | 14:0344705e6fb8 | 212 | * These bits (set to 0 in filter mask) are disregarded (masked). |
| hudakz | 9:e9224f2c6d37 | 213 | * They can have arbitrary values. |
| hudakz | 8:5c90d6b9a382 | 214 | * |
| hudakz | 8:5c90d6b9a382 | 215 | * NOTE: For the meaning of individual bits see the mapping of 32-bits explained above. |
| hudakz | 8:5c90d6b9a382 | 216 | * |
| hudakz | 9:e9224f2c6d37 | 217 | * @param format: This parameter must be CANAny |
| hudakz | 9:e9224f2c6d37 | 218 | * @param handle: Selects the filter. This parameter must be a number between 0 and 13. |
| hudakz | 9:e9224f2c6d37 | 219 | * @param retval: 0 - successful |
| hudakz | 9:e9224f2c6d37 | 220 | * 1 - error |
| hudakz | 9:e9224f2c6d37 | 221 | * 2 - busy |
| hudakz | 9:e9224f2c6d37 | 222 | * 3 - time out |
| hudakz | 0:e29bc8e0dddd | 223 | */ |
| hudakz | 8:5c90d6b9a382 | 224 | int CAN::filter(unsigned int id, unsigned int mask, CANFormat format /* = CANAny */, int handle /* = 0 */) { |
| hudakz | 0:e29bc8e0dddd | 225 | return can_filter(&_can, id, mask, format, handle); |
| hudakz | 0:e29bc8e0dddd | 226 | } |
| hudakz | 0:e29bc8e0dddd | 227 | |
| hudakz | 0:e29bc8e0dddd | 228 | /** |
| hudakz | 0:e29bc8e0dddd | 229 | * @brief Attaches handler funcion to CAN1 RX0 Interrupt |
| hudakz | 0:e29bc8e0dddd | 230 | * @note Only CAN1 RX0 Interrupt supported |
| hudakz | 0:e29bc8e0dddd | 231 | * @param fptr: pointer to a void (*)(void) function |
| hudakz | 0:e29bc8e0dddd | 232 | * @param type: not used (only CAN1 RX0 Interrupt supported) |
| hudakz | 0:e29bc8e0dddd | 233 | * @retval |
| hudakz | 0:e29bc8e0dddd | 234 | */ |
| hudakz | 0:e29bc8e0dddd | 235 | void CAN::attach(void (*fptr) (void), IrqType type) { |
| hudakz | 14:0344705e6fb8 | 236 | HAL_NVIC_DisableIRQ(CAN_IRQ); |
| hudakz | 0:e29bc8e0dddd | 237 | if(fptr) { |
| hudakz | 0:e29bc8e0dddd | 238 | can_irq_set(fptr); |
| hudakz | 0:e29bc8e0dddd | 239 | } |
| hudakz | 0:e29bc8e0dddd | 240 | can_irq_init(&_can, &CAN::_irq_handler, (uint32_t) this); |
| hudakz | 14:0344705e6fb8 | 241 | HAL_NVIC_EnableIRQ(CAN_IRQ); |
| hudakz | 0:e29bc8e0dddd | 242 | } |
| hudakz | 0:e29bc8e0dddd | 243 | |
| hudakz | 0:e29bc8e0dddd | 244 | /** |
| hudakz | 0:e29bc8e0dddd | 245 | * @brief |
| hudakz | 0:e29bc8e0dddd | 246 | * @note |
| hudakz | 0:e29bc8e0dddd | 247 | * @param |
| hudakz | 0:e29bc8e0dddd | 248 | * @retval |
| hudakz | 0:e29bc8e0dddd | 249 | */ |
| hudakz | 0:e29bc8e0dddd | 250 | void CAN::_irq_handler(uint32_t id, CanIrqType type) { |
| hudakz | 0:e29bc8e0dddd | 251 | CAN* handler = (CAN*)id; |
| hudakz | 0:e29bc8e0dddd | 252 | handler->_irq[type].call(); |
| hudakz | 0:e29bc8e0dddd | 253 | } |
| hudakz | 0:e29bc8e0dddd | 254 | |
| hudakz | 0:e29bc8e0dddd | 255 | } // namespace mbed |
| hudakz | 0:e29bc8e0dddd | 256 | |
| hudakz | 0:e29bc8e0dddd | 257 | |
| hudakz | 0:e29bc8e0dddd | 258 | |
| hudakz | 5:b53e5ee15315 | 259 | |
| hudakz | 6:c5a40d5fd9f1 | 260 | |
| hudakz | 11:439f3a34c42e | 261 |
