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