Controller Area Network library for NUCLEO boards equipped with CAN peripheral.
Dependents: Nucleo-Courtois CANBLE CANnucleo_Hello3 Nucleo_Serialprintf ... more
CANnucleo.h
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 #ifndef CANNUCLEO_H 00020 #define CANNUCLEO_H 00021 00022 #include "platform.h" 00023 #include "cannucleo_api.h" 00024 #include "can_helper.h" 00025 #include "Callback.h" 00026 #include "PlatformMutex.h" 00027 00028 /** CANMessage class 00029 */ 00030 class CANMessage : public CAN_Message 00031 { 00032 00033 public: 00034 /** Creates empty CAN message. 00035 */ 00036 CANMessage() : CAN_Message() { 00037 len = 8; 00038 type = CANData; 00039 format = CANStandard; 00040 id = 0; 00041 memset(data, 0, 8); 00042 } 00043 00044 /** Creates CAN message with specific content. 00045 */ 00046 CANMessage(int _id, const char *_data, char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) { 00047 len = _len & 0xF; 00048 type = _type; 00049 format = _format; 00050 id = _id; 00051 memcpy(data, _data, _len); 00052 } 00053 00054 /** Creates CAN remote message. 00055 */ 00056 CANMessage(int _id, CANFormat _format = CANStandard) { 00057 len = 0; 00058 type = CANRemote; 00059 format = _format; 00060 id = _id; 00061 memset(data, 0, 8); 00062 } 00063 00064 /*********************************************************************/ 00065 /*********************************************************************/ 00066 /*********************************************************************/ 00067 /** Copy constructor. 00068 */ 00069 CANMessage(const CANMessage& canMessage) { 00070 len = canMessage.len; 00071 type = canMessage.type; 00072 format = canMessage.format; 00073 id = canMessage.id; 00074 memcpy(data, canMessage.data, canMessage.len); 00075 } 00076 00077 /** Clears CAN message content 00078 */ 00079 void clear(void) { 00080 len = 0; 00081 type = CANData; 00082 format = CANStandard; 00083 id = 0; 00084 memset(data, 0, 8); 00085 }; 00086 00087 /** Inserter operator: Appends data (value) to CAN message 00088 */ 00089 template<class T> 00090 CANMessage &operator<<(const T val) { 00091 if(len + sizeof(T) <= 8) { 00092 *reinterpret_cast < T * > (&data[len]) = val; 00093 len += sizeof(T); 00094 } 00095 #if DEBUG 00096 else { 00097 printf("Error: Cannot append data. Exceeding CAN data length!\r\n"); 00098 } 00099 #endif 00100 return *this; 00101 } 00102 00103 /** Extractor operator: Extracts data (value) from CAN message 00104 */ 00105 template<class T> 00106 CANMessage &operator>>(T& val) { 00107 if(sizeof(T) <= len) { 00108 val = *reinterpret_cast < T * > (&data[0]); 00109 len -= sizeof(T); 00110 memcpy(data, data + sizeof(T), len); 00111 } 00112 #if DEBUG 00113 else { 00114 printf("Error: Cannot extract data. Exceeding CAN data length!\r\n"); 00115 } 00116 #endif 00117 return *this; 00118 } 00119 00120 }; 00121 00122 /** A can bus client, used for communicating with can devices 00123 */ 00124 class CAN 00125 { 00126 00127 public: 00128 /** Creates an CAN interface connected to specific pins. 00129 * 00130 * @param rd read from transmitter 00131 * @param td transmit to transmitter 00132 * 00133 * Example: 00134 * @code 00135 * #include "mbed.h" 00136 * #include "CAN.h" 00137 * 00138 * Ticker ticker; 00139 * DigitalOut led1(LED1); 00140 * CAN can(PA_11, PA_12); 00141 * 00142 * char counter = 0; 00143 * 00144 * void send() { 00145 * if(can.write(CANMessage(1337, &counter, 1))) { 00146 * printf("Message sent: %d\n", counter); 00147 * counter++; 00148 * } 00149 * led1 = !led1; 00150 * } 00151 * 00152 * int main() { 00153 * ticker.attach(&send, 1); 00154 * CANMessage msg; 00155 * while(1) { 00156 * if(can.read(msg)) { 00157 * printf("Message received: %d\n\n", msg.data[0]); 00158 * led1 = !led1; 00159 * } 00160 * wait(0.2); 00161 * } 00162 * } 00163 * @endcode 00164 */ 00165 00166 /** Constructor 00167 * 00168 * @param rd CAN receiver pin name 00169 * @param td CAN transmitter pin name 00170 * @param abom Automatic recovery from bus-off state (default value set to enabled) 00171 * 00172 */ 00173 CAN(PinName rd, PinName td, FunctionalState abom = ENABLE); 00174 00175 virtual ~CAN (); 00176 00177 /** Set the frequency of the CAN interface 00178 * 00179 * @param hz The bus frequency in hertz 00180 * 00181 * @returns 00182 * 1 if successful, 00183 * 0 otherwise 00184 */ 00185 int frequency(int hz); 00186 00187 /** Write a CANMessage to the bus. 00188 * 00189 * @param msg The CANMessage to write. 00190 * 00191 * @returns 00192 * 0 if write failed, 00193 * 1 if write was successful 00194 */ 00195 int write(CANMessage msg); 00196 00197 /** Read a CANMessage from the bus. 00198 * 00199 * @param msg A CANMessage to read to. 00200 * @param handle message filter handle (0 for any message) 00201 * 00202 * @returns 00203 * 0 if no message arrived, 00204 * 1 if message arrived 00205 */ 00206 int read(CANMessage &msg, int handle = 0); 00207 00208 /** Reset CAN interface. 00209 * 00210 * To use after error overflow. 00211 */ 00212 void reset(); 00213 00214 /** Puts or removes the CAN interface into silent monitoring mode 00215 * 00216 * @param silent boolean indicating whether to go into silent mode or not 00217 */ 00218 void monitor(bool silent); 00219 00220 enum Mode { 00221 Reset = 0, 00222 Normal, 00223 Silent, 00224 LocalTest, 00225 GlobalTest, 00226 SilentTest 00227 }; 00228 00229 /** Change CAN operation to the specified mode 00230 * 00231 * @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest) 00232 * 00233 * @returns 00234 * 0 if mode change failed or unsupported, 00235 * 1 if mode change was successful 00236 */ 00237 int mode(Mode mode); 00238 00239 /** Filter out incomming messages 00240 * 00241 * @param id the id to filter on 00242 * @param mask the mask applied to the id 00243 * @param format format to filter on (Default CANAny) 00244 * @param handle message filter handle (Optional) 00245 * 00246 * @retval 0 - successful 00247 * 1 - error 00248 * 2 - busy 00249 * 3 - time out 00250 */ 00251 int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0); 00252 00253 /** Returns number of read errors to detect read overflow errors. 00254 */ 00255 unsigned char rderror(); 00256 00257 /** Returns number of write errors to detect write overflow errors. 00258 */ 00259 unsigned char tderror(); 00260 00261 enum IrqType { 00262 RxIrq = 0, 00263 TxIrq, 00264 EwIrq, 00265 DoIrq, 00266 WuIrq, 00267 EpIrq, 00268 AlIrq, 00269 BeIrq, 00270 IdIrq 00271 }; 00272 00273 /** Attach a function to call whenever a CAN frame received interrupt is 00274 * generated. 00275 * 00276 * @param func A pointer to a void function, or 0 to set as none 00277 * @param event Which CAN interrupt to attach the member function to (only CAN::RxIrq for message received is supported) 00278 */ 00279 void attach(mbed::Callback<void()> func, IrqType type=RxIrq); 00280 00281 /** Attach a member function to call whenever a CAN frame received interrupt 00282 * is generated. 00283 * 00284 * @param obj pointer to the object to call the member function on 00285 * @param method pointer to the member function to be called 00286 * @param event Which CAN interrupt to attach the member function to (only CAN::RxIrq for message received is supported) 00287 */ 00288 template<typename T> 00289 void attach(T* obj, void (T::*method)(), IrqType type=RxIrq) { 00290 // Underlying call thread safe 00291 attach(Callback<void()>(obj, method), type); 00292 } 00293 00294 /** Attach a member function to call whenever a CAN frame received interrupt 00295 * is generated. 00296 * 00297 * @param obj pointer to the object to call the member function on 00298 * @param method pointer to the member function to be called 00299 * @param event Which CAN interrupt to attach the member function to (only CAN::RxIrq for message received is supported) 00300 */ 00301 template<typename T> 00302 void attach(T* obj, void (*method)(T*), IrqType type=RxIrq) { 00303 // Underlying call thread safe 00304 attach(Callback<void()>(obj, method), type); 00305 } 00306 00307 00308 static void _irq_handler (uint32_t id, CanIrqType type); 00309 00310 protected: 00311 virtual void lock(); 00312 virtual void unlock(); 00313 mbed::Callback<void()> _irq[9]; 00314 PlatformMutex _mutex; 00315 }; 00316 00317 #endif // CAN_NUCLEO_H 00318 00319 00320 00321 00322 00323 00324 00325
Generated on Wed Jul 13 2022 09:11:28 by 1.7.2