pub
Fork of CANnucleo by
Embed:
(wiki syntax)
Show/hide line numbers
CANnucleo.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@outlook.com> 00017 * 00018 */ 00019 #include "CANnucleo.h" 00020 #include "cmsis.h" 00021 00022 /** 00023 * @brief Constructor 00024 * @note Constructs an instance of CAN class 00025 * @param rxPin: CAN Rx pin name 00026 * @param txPin: CAN Tx pin name 00027 * @param abom: Automatic recovery from bus-off state (defaults to enabled) 00028 * @retval 00029 */ 00030 CAN::CAN(PinName rxPin, PinName txPin, FunctionalState abom /* = ENABLE */) : 00031 _irq() { 00032 can_init(rxPin, txPin, abom); 00033 can_irq_init((uint32_t)this, (&CAN::_irq_handler )); 00034 } 00035 00036 /** 00037 * @brief 00038 * @note 00039 * @param 00040 * @retval 00041 */ 00042 CAN::~CAN (void) { 00043 can_irq_free(); 00044 can_free(); 00045 } 00046 00047 /** 00048 * @brief 00049 * @note 00050 * @param 00051 * @retval 00052 */ 00053 int CAN::frequency(int f) { 00054 lock(); 00055 int ret = can_frequency(f); 00056 unlock(); 00057 return ret; 00058 } 00059 00060 /** 00061 * @brief 00062 * @note 00063 * @param 00064 * @retval 00065 */ 00066 int CAN::write(CANMessage msg) { 00067 lock(); 00068 int ret = can_write(msg, 0); 00069 unlock(); 00070 return ret; 00071 } 00072 00073 /** 00074 * @brief 00075 * @note 00076 * @param 00077 * @retval 00078 */ 00079 int CAN::read(CANMessage& msg, int handle) { 00080 lock(); 00081 int ret = can_read(&msg, handle); 00082 unlock(); 00083 return ret; 00084 } 00085 00086 /** 00087 * @brief 00088 * @note 00089 * @param 00090 * @retval 00091 */ 00092 void CAN::reset(void) { 00093 lock(); 00094 can_reset(); 00095 unlock(); 00096 } 00097 00098 /** 00099 * @brief 00100 * @note 00101 * @param 00102 * @retval 00103 */ 00104 unsigned char CAN::rderror(void) { 00105 lock(); 00106 unsigned char ret = can_rderror(); 00107 unlock(); 00108 return ret; 00109 } 00110 00111 /** 00112 * @brief 00113 * @note 00114 * @param 00115 * @retval 00116 */ 00117 unsigned char CAN::tderror(void) { 00118 lock(); 00119 unsigned char ret = can_tderror(); 00120 unlock(); 00121 return ret; 00122 } 00123 00124 /** 00125 * @brief 00126 * @note 00127 * @param 00128 * @retval 00129 */ 00130 void CAN::monitor(bool silent) { 00131 lock(); 00132 can_monitor((silent) ? 1 : 0); 00133 unlock(); 00134 } 00135 00136 /** 00137 * @brief 00138 * @note 00139 * @param 00140 * @retval 00141 */ 00142 int CAN::mode(Mode mode) { 00143 lock(); 00144 int ret = can_mode((CanMode) mode); 00145 unlock(); 00146 return ret; 00147 } 00148 00149 /** 00150 * @brief Sets up a CAN filter 00151 * @note At the present, CANnucleo supports only mask mode and 32-bit filter scale. 00152 * Identifier list mode filtering and 16-bit filter scale are not supported. 00153 * There are 14 filters available (0 - 13) for the application to set up. 00154 * Each filter is a 32-bit filter defined by a filter ID and a filter mask. 00155 * If no filter is set up then no CAN message is accepted (received)! 00156 * That's why filter #0 is set up in the constructor to receive all CAN messages by default. 00157 * On reception of a message it is compared with filter #0. If there is a match, the message is stored. 00158 * If there is no match, the incoming identifier is then compared with the next filter. 00159 * If the received identifier does not match any of the identifiers configured in the filters, 00160 * the message is discarded by hardware without disturbing the software. 00161 * 00162 * @param id: 'Filter ID' defines the bit values to be compared with the corresponding received bits 00163 * 00164 * Mapping of 32-bits (4-bytes) : | STID[10:3] | STID[2:0] EXID[17:13] | EXID[12:5] | EXID[4:0] IDE RTR 0 | 00165 * 00166 * STID - Stardard Identifier bits 00167 * EXID - Extended Identifier bits 00168 * [x:y]- bit range 00169 * IDE - Identifier Extension bit (0 -> Standard Identifier, 1 -> Extended Identifier) 00170 * RTR - Remote Transmission Request bit (0 -> Remote Transmission Request, 1 -> Standard message) 00171 * 00172 * @param mask: 'Filter mask' defines which bits of the 'Filter ID' are compared with the received bits 00173 * and which bits are disregarded. 00174 00175 * Mapping of 32-bits (4-bytes) : | STID[10:3] | STID[2:0] EXID[17:13] | EXID[12:5] | EXID[4:0] IDE RTR 0 | 00176 * 00177 * STID - Stardard Identifier bits 00178 * EXID - Extended Identifier bits 00179 * [x:y]- bit range 00180 * IDE - Identifier Extension bit 00181 * RTR - Remote Transmission Request bit 00182 * 00183 * 1 -> bit is considered 00184 * 0 -> bit is disregarded 00185 * 00186 * ---------------------------------------- 00187 * Example of filter set up and filtering: 00188 * ---------------------------------------- 00189 * 00190 * Let's assume we would like to receive only messages 00191 * with standard identifier STID = 0x0207 (STID[15:0] = 00000010 00000111) 00192 * 00193 * We map the STID to filter ID by shifting the bits appropriately: 00194 * Filter id = STID << (16 + (15 - 10)) = STID << 21 = 01000000 11100000 00000000 00000000 = 0x40E00000 00195 * 00196 * To compare only the bits representing STID we set the filter mask adequately: 00197 * Filter mask = 11111111 11100000 00000000 00000100 = 0xFFE00004 00198 * |||||||| ||| | 00199 * -------- --- | 00200 * | | | 00201 * STID[10:3] STID[2:0] IDE 00202 * 00203 * Recall that filter #0 has been set up in the constructor to receive all CAN messages by default. 00204 * So we have to reconfigure it. If we were set up filter #1 here then filter #0 would receive all the messages 00205 * and no message would reach filter #1! 00206 * 00207 * To reconfigure (set up) filter #0 we call: 00208 * can.filter(0x0207 << 21, 0xFFE00004, CANAny, 0); 00209 * 00210 * Only these bits of 'Filter id' (set to 1 here in 'Filter mask') are compared with the corresponding 00211 * bits of received message (the others are disregarded) 00212 * | 00213 * --------------------------------- 00214 * |||||||| ||| | 00215 * Filter mask = 11111111 11100000 00000000 00000100 (= 0xFFE00004) 00216 * Filter id = 01000000 11100000 00000000 00000000 (= 0x40E00000) 00217 * |||||||| ||| | 00218 * --------------------------------- 00219 * | 00220 * To receive the message the values of these bits must match. 00221 * Otherwise the message is passed to the next filter or 00222 * discarded if this was the last active filter. 00223 * | 00224 * --------------------------------- 00225 * |||||||| ||| | 00226 * Received id = 01000000 11100000 00000000 00000010 (= 0x40E00002) 00227 * ||||| |||||||| ||||| || 00228 * ----------------------- 00229 * | 00230 * These bits (set to 0 in 'Filter mask') are disregarded (masked). 00231 * They can have arbitrary values. 00232 * 00233 * NOTE: For the meaning of individual bits see the mapping of 32-bits explained above. 00234 * 00235 * @param format: This parameter must be CANAny 00236 * @param handle: Selects the filter. This parameter must be a number between 0 and 13. 00237 * @retval 0 - successful 00238 * 1 - error 00239 * 2 - busy 00240 * 3 - time out 00241 */ 00242 int CAN::filter(unsigned int id, unsigned int mask, CANFormat format /* = CANAny */, int handle /* = 0 */) { 00243 lock(); 00244 int ret = can_filter(id, mask, format, handle); 00245 unlock(); 00246 return ret; 00247 } 00248 00249 /** 00250 * @brief Attaches handler funcion to CAN1 RX0 Interrupt 00251 * @note Only CAN1 RX0 Interrupt supported 00252 * @param fptr: pointer to a void (*)(void) function 00253 * @param type: not used (only CAN1 RX0 Interrupt supported) 00254 * @retval 00255 */ 00256 void CAN::attach(mbed::Callback<void()> func, IrqType type) { 00257 lock(); 00258 HAL_NVIC_DisableIRQ(CAN_IRQ); 00259 if (func) 00260 _irq[(CanIrqType)type] = func; 00261 HAL_NVIC_EnableIRQ(CAN_IRQ); 00262 unlock(); 00263 } 00264 00265 /** 00266 * @brief 00267 * @note 00268 * @param 00269 * @retval 00270 */ 00271 void CAN::_irq_handler (uint32_t id, CanIrqType type) { 00272 CAN* handler = (CAN*)id; 00273 handler->_irq[type].call(); 00274 } 00275 00276 void CAN::lock() { 00277 _mutex.lock(); 00278 } 00279 00280 void CAN::unlock() { 00281 _mutex.unlock(); 00282 } 00283 00284 00285 00286 00287 00288 00289 00290 00291 00292 00293 00294
Generated on Sat Jul 16 2022 03:43:32 by 1.7.2