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
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 * 00016 * Modified by Zoltan Hudak <hudakz@inbox.com> 00017 * 00018 */ 00019 #include "CAN.h" 00020 #include "cmsis.h" 00021 00022 namespace mbed 00023 { 00024 00025 /** 00026 * @brief Constructor 00027 * @note Constructs an instance of CAN class 00028 * @param rxPin: CAN Rx pin name 00029 * @param txPin: CAN Tx pin name 00030 * @param abom: Automatic recovery from bus-off state (defaults to enabled) 00031 * @retval 00032 */ 00033 CAN::CAN(PinName rxPin, PinName txPin, FunctionalState abom /* = ENABLE */) : 00034 _can(), 00035 _irq() { 00036 can_init(&_can, rxPin, txPin, abom); 00037 can_irq_init(&_can, (&CAN::_irq_handler ), (uint32_t)this); 00038 } 00039 00040 /** 00041 * @brief 00042 * @note 00043 * @param 00044 * @retval 00045 */ 00046 CAN::~CAN (void) { 00047 can_irq_free(&_can); 00048 can_free(&_can); 00049 } 00050 00051 /** 00052 * @brief 00053 * @note 00054 * @param 00055 * @retval 00056 */ 00057 int CAN::frequency(int f) { 00058 return can_frequency(&_can, f); 00059 } 00060 00061 /** 00062 * @brief 00063 * @note 00064 * @param 00065 * @retval 00066 */ 00067 int CAN::write(CANMessage msg) { 00068 return can_write(&_can, msg, 0); 00069 } 00070 00071 /** 00072 * @brief 00073 * @note 00074 * @param 00075 * @retval 00076 */ 00077 int CAN::read(CANMessage& msg, int handle) { 00078 return can_read(&_can, &msg, handle); 00079 } 00080 00081 /** 00082 * @brief 00083 * @note 00084 * @param 00085 * @retval 00086 */ 00087 void CAN::reset(void) { 00088 can_reset(&_can); 00089 } 00090 00091 /** 00092 * @brief 00093 * @note 00094 * @param 00095 * @retval 00096 */ 00097 unsigned char CAN::rderror(void) { 00098 return can_rderror(&_can); 00099 } 00100 00101 /** 00102 * @brief 00103 * @note 00104 * @param 00105 * @retval 00106 */ 00107 unsigned char CAN::tderror(void) { 00108 return can_tderror(&_can); 00109 } 00110 00111 /** 00112 * @brief 00113 * @note 00114 * @param 00115 * @retval 00116 */ 00117 void CAN::monitor(bool silent) { 00118 can_monitor(&_can, (silent) ? 1 : 0); 00119 } 00120 00121 /** 00122 * @brief 00123 * @note 00124 * @param 00125 * @retval 00126 */ 00127 int CAN::mode(Mode mode) { 00128 return can_mode(&_can, (CanMode) mode); 00129 } 00130 00131 /** 00132 * @brief Sets up a CAN filter 00133 * @note At the present, CANnucleo supports only mask mode and 32-bit filter scale. 00134 * Identifier list mode filtering and 16-bit filter scale are not supported. 00135 * There are 14 filters available (0 - 13) for the application to set up. 00136 * Each filter is a 32-bit filter defined by a filter ID and a filter mask. 00137 * If no filter is set up then no CAN message is accepted (received)! 00138 * That's why filter #0 is set up in the constructor to receive all CAN messages by default. 00139 * On reception of a message it is compared with filter #0. If there is a match, the message is stored. 00140 * If there is no match, the incoming identifier is then compared with the next filter. 00141 * If the received identifier does not match any of the identifiers configured in the filters, 00142 * the message is discarded by hardware without disturbing the software. 00143 * 00144 * @param id: 'Filter ID' defines the bit values to be compared with the corresponding received bits 00145 * 00146 * Mapping of 32-bits (4-bytes) : | STID[10:3] | STID[2:0] EXID[17:13] | EXID[12:5] | EXID[4:0] IDE RTR 0 | 00147 * 00148 * STID - Stardard Identifier bits 00149 * EXID - Extended Identifier bits 00150 * [x:y]- bit range 00151 * IDE - Identifier Extension bit (0 -> Standard Identifier, 1 -> Extended Identifier) 00152 * RTR - Remote Transmission Request bit (0 -> Remote Transmission Request, 1 -> Standard message) 00153 * 00154 * @param mask: 'Filter mask' defines which bits of the 'Filter ID' are compared with the received bits 00155 * and which bits are disregarded. 00156 00157 * Mapping of 32-bits (4-bytes) : | STID[10:3] | STID[2:0] EXID[17:13] | EXID[12:5] | EXID[4:0] IDE RTR 0 | 00158 * 00159 * STID - Stardard Identifier bits 00160 * EXID - Extended Identifier bits 00161 * [x:y]- bit range 00162 * IDE - Identifier Extension bit 00163 * RTR - Remote Transmission Request bit 00164 * 00165 * 1 -> bit is considered 00166 * 0 -> bit is disregarded 00167 * 00168 * ---------------------------------------- 00169 * Example of filter set up and filtering: 00170 * ---------------------------------------- 00171 * 00172 * Let's assume we would like to receive only messages 00173 * with standard identifier STID = 0x0207 (STID[15:0] = 00000010 00000111) 00174 * 00175 * We map the STID to filter ID by shifting the bits appropriately: 00176 * Filter id = STID << (16 + (15 - 10)) = STID << 21 = 01000000 11100000 00000000 00000000 = 0x40E00000 00177 * 00178 * To compare only the bits representing STID we set the filter mask adequately: 00179 * Filter mask = 11111111 11100000 00000000 00000100 = 0xFFE00004 00180 * |||||||| ||| | 00181 * -------- --- | 00182 * | | | 00183 * STID[10:3] STID[2:0] IDE 00184 * 00185 * Keep in mind that filter #0 was already set up in the constructor to receive all CAN messages by default. 00186 * So we have to reconfigure it. If we were set up filter #1 here then filter #0 would receive all the messages 00187 * and no message would reach filter #1! 00188 * 00189 * To set up filter #0 we call: 00190 * can.filter(0x0207 << 21, 0xFFE00004, CANAny, 0); 00191 * 00192 * Only these bits (set to 1) of filter id are compared with the corresponding 00193 * bits of received message (the others are disregarded) 00194 * | 00195 * --------------------------------- 00196 * |||||||| ||| | 00197 * Filter mask = 11111111 11100000 00000000 00000100 (= 0xFFE00004) 00198 * Filter id = 01000000 11100000 00000000 00000000 (= 0x40E00000) 00199 * |||||||| ||| | 00200 * --------------------------------- 00201 * | 00202 * To receive the message the values of these bits must match. 00203 * Otherwise the message is passed to the next filter or 00204 * discarded if this was the last active filter. 00205 * | 00206 * --------------------------------- 00207 * |||||||| ||| | 00208 * Received id = 01000000 11100000 00000000 00000010 (= 0x40E00002) 00209 * ||||| |||||||| ||||| || 00210 * ----------------------- 00211 * | 00212 * These bits (set to 0 in filter mask) are disregarded (masked). 00213 * They can have arbitrary values. 00214 * 00215 * NOTE: For the meaning of individual bits see the mapping of 32-bits explained above. 00216 * 00217 * @param format: This parameter must be CANAny 00218 * @param handle: Selects the filter. This parameter must be a number between 0 and 13. 00219 * @param retval: 0 - successful 00220 * 1 - error 00221 * 2 - busy 00222 * 3 - time out 00223 */ 00224 int CAN::filter(unsigned int id, unsigned int mask, CANFormat format /* = CANAny */, int handle /* = 0 */) { 00225 return can_filter(&_can, id, mask, format, handle); 00226 } 00227 00228 /** 00229 * @brief Attaches handler funcion to CAN1 RX0 Interrupt 00230 * @note Only CAN1 RX0 Interrupt supported 00231 * @param fptr: pointer to a void (*)(void) function 00232 * @param type: not used (only CAN1 RX0 Interrupt supported) 00233 * @retval 00234 */ 00235 void CAN::attach(void (*fptr) (void), IrqType type) { 00236 HAL_NVIC_DisableIRQ(CAN_IRQ); 00237 if(fptr) { 00238 can_irq_set(fptr); 00239 } 00240 can_irq_init(&_can, &CAN::_irq_handler , (uint32_t) this); 00241 HAL_NVIC_EnableIRQ(CAN_IRQ); 00242 } 00243 00244 /** 00245 * @brief 00246 * @note 00247 * @param 00248 * @retval 00249 */ 00250 void CAN::_irq_handler (uint32_t id, CanIrqType type) { 00251 CAN* handler = (CAN*)id; 00252 handler->_irq[type].call(); 00253 } 00254 00255 } // namespace mbed 00256 00257 00258 00259 00260 00261
Generated on Tue Jul 12 2022 20:03:31 by
1.7.2
