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