Working fork to test F0 application
Fork of CANnucleo by
Embed:
(wiki syntax)
Show/hide line numbers
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 * @returns 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 if((mptr != NULL) && (tptr != NULL)) { 00298 _irq[type].attach(tptr, mptr); 00299 // can_irq_set(&_can, (CanIrqType)type, 1); 00300 } 00301 // else { 00302 // can_irq_set(&_can, (CanIrqType)type, 0); 00303 // } 00304 } 00305 00306 static void _irq_handler (uint32_t id, CanIrqType type); 00307 00308 protected: 00309 can_t _can; 00310 FunctionPointer _irq[9]; 00311 }; 00312 00313 } // namespace mbed 00314 00315 #endif 00316 00317 #endif // MBED_CAN_H 00318 00319 00320 00321 00322 00323
Generated on Tue Jul 12 2022 20:03:31 by 1.7.2