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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
CAN.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2019 ARM Limited 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #ifndef MBED_CAN_H 00018 #define MBED_CAN_H 00019 00020 #include "platform/platform.h" 00021 00022 #if DEVICE_CAN || defined(DOXYGEN_ONLY) 00023 00024 #include "hal/can_api.h" 00025 #include "platform/Callback.h" 00026 #include "platform/PlatformMutex.h" 00027 #include "platform/NonCopyable.h" 00028 00029 namespace mbed { 00030 /** \defgroup drivers-public-api-can CAN 00031 * \ingroup drivers-public-api 00032 */ 00033 00034 /** 00035 * \defgroup drivers_CANMessage CANMessage class 00036 * \ingroup drivers-public-api-can 00037 * @{ 00038 */ 00039 00040 /** CANMessage class 00041 * 00042 * @note Synchronization level: Thread safe 00043 */ 00044 class CANMessage : public CAN_Message { 00045 00046 public: 00047 /** Creates empty CAN message. 00048 */ 00049 CANMessage() : CAN_Message() 00050 { 00051 len = 8U; 00052 type = CANData; 00053 format = CANStandard; 00054 id = 0U; 00055 memset(data, 0, 8); 00056 } 00057 00058 /** Creates CAN message with specific content. 00059 * 00060 * @param _id Message ID 00061 * @param _data Mesaage Data 00062 * @param _len Message Data length 00063 * @param _type Type of Data: Use enum CANType for valid parameter values 00064 * @param _format Data Format: Use enum CANFormat for valid parameter values 00065 */ 00066 CANMessage(unsigned int _id, const unsigned char *_data, unsigned char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) 00067 { 00068 len = _len & 0xF; 00069 type = _type; 00070 format = _format; 00071 id = _id; 00072 memcpy(data, _data, _len); 00073 } 00074 00075 00076 /** Creates CAN message with specific content. 00077 * 00078 * @param _id Message ID 00079 * @param _data Mesaage Data 00080 * @param _len Message Data length 00081 * @param _type Type of Data: Use enum CANType for valid parameter values 00082 * @param _format Data Format: Use enum CANFormat for valid parameter values 00083 */ 00084 CANMessage(unsigned int _id, const char *_data, unsigned char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) 00085 { 00086 len = _len & 0xF; 00087 type = _type; 00088 format = _format; 00089 id = _id; 00090 memcpy(data, _data, _len); 00091 } 00092 00093 /** Creates CAN remote message. 00094 * 00095 * @param _id Message ID 00096 * @param _format Data Format: Use enum CANType for valid parameter values 00097 */ 00098 CANMessage(unsigned int _id, CANFormat _format = CANStandard) 00099 { 00100 len = 0; 00101 type = CANRemote; 00102 format = _format; 00103 id = _id; 00104 memset(data, 0, 8); 00105 } 00106 }; 00107 00108 /** @}*/ 00109 00110 /** 00111 * \defgroup drivers_CAN CAN class 00112 * \ingroup drivers-public-api-can 00113 * @{ 00114 */ 00115 00116 /** A can bus client, used for communicating with can devices 00117 */ 00118 class CAN : private NonCopyable<CAN> { 00119 00120 public: 00121 /** Creates a CAN interface connected to specific pins. 00122 * 00123 * @param rd read from transmitter 00124 * @param td transmit to transmitter 00125 * 00126 * Example: 00127 * @code 00128 * #include "mbed.h" 00129 * 00130 * 00131 * Ticker ticker; 00132 * DigitalOut led1(LED1); 00133 * DigitalOut led2(LED2); 00134 * //The constructor takes in RX, and TX pin respectively. 00135 * //These pins, for this example, are defined in mbed_app.json 00136 * CAN can1(MBED_CONF_APP_CAN1_RD, MBED_CONF_APP_CAN1_TD); 00137 * CAN can2(MBED_CONF_APP_CAN2_RD, MBED_CONF_APP_CAN2_TD); 00138 * 00139 * unsigned char counter = 0; 00140 * 00141 * void send() { 00142 * if(can1.write(CANMessage(1337U, &counter, 1))) { 00143 * printf("Message sent: %d\n", counter); 00144 * counter++; 00145 * } 00146 * led1 = !led1; 00147 * } 00148 * 00149 * int main() { 00150 * ticker.attach(&send, 1); 00151 * CANMessage msg; 00152 * while(1) { 00153 * if(can2.read(msg)) { 00154 * printf("Message received: %d\n\n", msg.data[0]); 00155 * led2 = !led2; 00156 * } 00157 * wait(0.2); 00158 * } 00159 * } 00160 * 00161 * @endcode 00162 */ 00163 CAN(PinName rd, PinName td); 00164 00165 /** Initialize CAN interface and set the frequency 00166 * 00167 * @param rd the read pin 00168 * @param td the transmit pin 00169 * @param hz the bus frequency in hertz 00170 */ 00171 CAN(PinName rd, PinName td, int hz); 00172 00173 /** Initialize CAN interface 00174 * 00175 * @param pinmap reference to structure which holds static pinmap 00176 * @param td the transmit pin 00177 * @param hz the bus frequency in hertz 00178 */ 00179 CAN(const can_pinmap_t &pinmap); 00180 CAN(const can_pinmap_t &&) = delete; // prevent passing of temporary objects 00181 00182 /** Initialize CAN interface and set the frequency 00183 * 00184 * @param pinmap reference to structure which holds static pinmap 00185 * @param td the transmit pin 00186 * @param hz the bus frequency in hertz 00187 */ 00188 CAN(const can_pinmap_t &pinmap, int hz); 00189 CAN(const can_pinmap_t &&, int) = delete; // prevent passing of temporary objects 00190 00191 virtual ~CAN(); 00192 00193 /** Set the frequency of the CAN interface 00194 * 00195 * @param hz The bus frequency in hertz 00196 * 00197 * @returns 00198 * 1 if successful, 00199 * 0 otherwise 00200 */ 00201 int frequency(int hz); 00202 00203 /** Write a CANMessage to the bus. 00204 * 00205 * @param msg The CANMessage to write. 00206 * 00207 * @returns 00208 * 0 if write failed, 00209 * 1 if write was successful 00210 */ 00211 int write(CANMessage msg); 00212 00213 /** Read a CANMessage from the bus. 00214 * 00215 * @param msg A CANMessage to read to. 00216 * @param handle message filter handle (0 for any message) 00217 * 00218 * @returns 00219 * 0 if no message arrived, 00220 * 1 if message arrived 00221 */ 00222 int read(CANMessage &msg, int handle = 0); 00223 00224 /** Reset CAN interface. 00225 * 00226 * To use after error overflow. 00227 */ 00228 void reset(); 00229 00230 /** Puts or removes the CAN interface into silent monitoring mode 00231 * 00232 * @param silent boolean indicating whether to go into silent mode or not 00233 */ 00234 void monitor(bool silent); 00235 00236 enum Mode { 00237 Reset = 0, 00238 Normal, 00239 Silent, 00240 LocalTest, 00241 GlobalTest, 00242 SilentTest 00243 }; 00244 00245 /** Change CAN operation to the specified mode 00246 * 00247 * @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest) 00248 * 00249 * @returns 00250 * 0 if mode change failed or unsupported, 00251 * 1 if mode change was successful 00252 */ 00253 int mode(Mode mode); 00254 00255 /** Filter out incoming messages 00256 * 00257 * @param id the id to filter on 00258 * @param mask the mask applied to the id 00259 * @param format format to filter on (Default CANAny) 00260 * @param handle message filter handle (Optional) 00261 * 00262 * @returns 00263 * 0 if filter change failed or unsupported, 00264 * new filter handle if successful 00265 */ 00266 int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0); 00267 00268 /** Detects read errors - Used to detect read overflow errors. 00269 * 00270 * @returns number of read errors 00271 */ 00272 unsigned char rderror(); 00273 00274 /** Detects write errors - Used to detect write overflow errors. 00275 * 00276 * @returns number of write errors 00277 */ 00278 unsigned char tderror(); 00279 00280 enum IrqType { 00281 RxIrq = 0, 00282 TxIrq, 00283 EwIrq, 00284 DoIrq, 00285 WuIrq, 00286 EpIrq, 00287 AlIrq, 00288 BeIrq, 00289 IdIrq, 00290 00291 IrqCnt 00292 }; 00293 00294 /** Attach a function to call whenever a CAN frame received interrupt is 00295 * generated. 00296 * 00297 * This function locks the deep sleep while a callback is attached 00298 * 00299 * @param func A pointer to a void function, or 0 to set as none 00300 * @param type Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, CAN::TxIrq for transmitted or aborted, CAN::EwIrq for error warning, CAN::DoIrq for data overrun, CAN::WuIrq for wake-up, CAN::EpIrq for error passive, CAN::AlIrq for arbitration lost, CAN::BeIrq for bus error) 00301 */ 00302 void attach(Callback<void()> func, IrqType type = RxIrq); 00303 00304 /** Attach a member function to call whenever a CAN frame received interrupt 00305 * is generated. 00306 * 00307 * @param obj pointer to the object to call the member function on 00308 * @param method pointer to the member function to be called 00309 * @param type Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, TxIrq for transmitted or aborted, EwIrq for error warning, DoIrq for data overrun, WuIrq for wake-up, EpIrq for error passive, AlIrq for arbitration lost, BeIrq for bus error) 00310 * @deprecated 00311 * The attach function does not support cv-qualifiers. Replaced by 00312 * attach(callback(obj, method), type). 00313 */ 00314 template<typename T> 00315 MBED_DEPRECATED_SINCE("mbed-os-5.1", 00316 "The attach function does not support cv-qualifiers. Replaced by " 00317 "attach(callback(obj, method), type).") 00318 void attach(T *obj, void (T::*method)(), IrqType type = RxIrq) 00319 { 00320 // Underlying call thread safe 00321 attach(callback(obj, method), type); 00322 } 00323 00324 /** Attach a member function to call whenever a CAN frame received interrupt 00325 * is generated. 00326 * 00327 * @param obj pointer to the object to call the member function on 00328 * @param method pointer to the member function to be called 00329 * @param type Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, TxIrq for transmitted or aborted, EwIrq for error warning, DoIrq for data overrun, WuIrq for wake-up, EpIrq for error passive, AlIrq for arbitration lost, BeIrq for bus error) 00330 * @deprecated 00331 * The attach function does not support cv-qualifiers. Replaced by 00332 * attach(callback(obj, method), type). 00333 */ 00334 template<typename T> 00335 MBED_DEPRECATED_SINCE("mbed-os-5.1", 00336 "The attach function does not support cv-qualifiers. Replaced by " 00337 "attach(callback(obj, method), type).") 00338 void attach(T *obj, void (*method)(T *), IrqType type = RxIrq) 00339 { 00340 // Underlying call thread safe 00341 attach(callback(obj, method), type); 00342 } 00343 00344 static void _irq_handler(uint32_t id, CanIrqType type); 00345 00346 #if !defined(DOXYGEN_ONLY) 00347 protected: 00348 virtual void lock(); 00349 virtual void unlock(); 00350 00351 can_t _can; 00352 Callback<void()> _irq[IrqCnt]; 00353 PlatformMutex _mutex; 00354 #endif 00355 }; 00356 00357 /** @}*/ 00358 00359 } // namespace mbed 00360 00361 #endif 00362 00363 #endif // MBED_CAN_H
Generated on Tue Jul 12 2022 13:54:04 by
