Mistake on this page?
Report an issue in GitHub or email us
CAN.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2019 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef MBED_CAN_H
18 #define MBED_CAN_H
19 
20 #include "platform/platform.h"
21 
22 #if DEVICE_CAN || defined(DOXYGEN_ONLY)
23 
24 #include "hal/can_api.h"
25 #include "platform/Callback.h"
26 #include "platform/PlatformMutex.h"
27 #include "platform/NonCopyable.h"
28 
29 namespace mbed {
30 /** \defgroup drivers-public-api-can CAN
31  * \ingroup drivers-public-api
32  */
33 
34 /**
35  * \defgroup drivers_CANMessage CANMessage class
36  * \ingroup drivers-public-api-can
37  * @{
38  */
39 
40 /** CANMessage class
41  *
42  * @note Synchronization level: Thread safe
43  */
44 class CANMessage : public CAN_Message {
45 
46 public:
47  /** Creates empty CAN message.
48  */
50  {
51  len = 8U;
52  type = CANData;
53  format = CANStandard;
54  id = 0U;
55  memset(data, 0, 8);
56  }
57 
58  /** Creates CAN message with specific content.
59  *
60  * @param _id Message ID
61  * @param _data Mesaage Data
62  * @param _len Message Data length
63  * @param _type Type of Data: Use enum CANType for valid parameter values
64  * @param _format Data Format: Use enum CANFormat for valid parameter values
65  */
66  CANMessage(unsigned int _id, const unsigned char *_data, unsigned char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard)
67  {
68  len = _len & 0xF;
69  type = _type;
70  format = _format;
71  id = _id;
72  memcpy(data, _data, _len);
73  }
74 
75 
76  /** Creates CAN message with specific content.
77  *
78  * @param _id Message ID
79  * @param _data Mesaage Data
80  * @param _len Message Data length
81  * @param _type Type of Data: Use enum CANType for valid parameter values
82  * @param _format Data Format: Use enum CANFormat for valid parameter values
83  */
84  CANMessage(unsigned int _id, const char *_data, unsigned char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard)
85  {
86  len = _len & 0xF;
87  type = _type;
88  format = _format;
89  id = _id;
90  memcpy(data, _data, _len);
91  }
92 
93  /** Creates CAN remote message.
94  *
95  * @param _id Message ID
96  * @param _format Data Format: Use enum CANType for valid parameter values
97  */
98  CANMessage(unsigned int _id, CANFormat _format = CANStandard)
99  {
100  len = 0;
101  type = CANRemote;
102  format = _format;
103  id = _id;
104  memset(data, 0, 8);
105  }
106 };
107 
108 /** @}*/
109 
110 /**
111  * \defgroup drivers_CAN CAN class
112  * \ingroup drivers-public-api-can
113  * @{
114  */
115 
116 /** A can bus client, used for communicating with can devices
117  */
118 class CAN : private NonCopyable<CAN> {
119 
120 public:
121  /** Creates a CAN interface connected to specific pins.
122  *
123  * @param rd read from transmitter
124  * @param td transmit to transmitter
125  *
126  * Example:
127  * @code
128  * #include "mbed.h"
129  *
130  *
131  * Ticker ticker;
132  * DigitalOut led1(LED1);
133  * DigitalOut led2(LED2);
134  * //The constructor takes in RX, and TX pin respectively.
135  * //These pins, for this example, are defined in mbed_app.json
136  * CAN can1(MBED_CONF_APP_CAN1_RD, MBED_CONF_APP_CAN1_TD);
137  * CAN can2(MBED_CONF_APP_CAN2_RD, MBED_CONF_APP_CAN2_TD);
138  *
139  * unsigned char counter = 0;
140  *
141  * void send() {
142  * if(can1.write(CANMessage(1337U, &counter, 1))) {
143  * printf("Message sent: %d\n", counter);
144  * counter++;
145  * }
146  * led1 = !led1;
147  * }
148  *
149  * int main() {
150  * ticker.attach(&send, 1);
151  * CANMessage msg;
152  * while(1) {
153  * if(can2.read(msg)) {
154  * printf("Message received: %d\n\n", msg.data[0]);
155  * led2 = !led2;
156  * }
157  * wait(0.2);
158  * }
159  * }
160  *
161  * @endcode
162  */
163  CAN(PinName rd, PinName td);
164 
165  /** Initialize CAN interface and set the frequency
166  *
167  * @param rd the read pin
168  * @param td the transmit pin
169  * @param hz the bus frequency in hertz
170  */
171  CAN(PinName rd, PinName td, int hz);
172 
173  virtual ~CAN();
174 
175  /** Set the frequency of the CAN interface
176  *
177  * @param hz The bus frequency in hertz
178  *
179  * @returns
180  * 1 if successful,
181  * 0 otherwise
182  */
183  int frequency(int hz);
184 
185  /** Write a CANMessage to the bus.
186  *
187  * @param msg The CANMessage to write.
188  *
189  * @returns
190  * 0 if write failed,
191  * 1 if write was successful
192  */
193  int write(CANMessage msg);
194 
195  /** Read a CANMessage from the bus.
196  *
197  * @param msg A CANMessage to read to.
198  * @param handle message filter handle (0 for any message)
199  *
200  * @returns
201  * 0 if no message arrived,
202  * 1 if message arrived
203  */
204  int read(CANMessage &msg, int handle = 0);
205 
206  /** Reset CAN interface.
207  *
208  * To use after error overflow.
209  */
210  void reset();
211 
212  /** Puts or removes the CAN interface into silent monitoring mode
213  *
214  * @param silent boolean indicating whether to go into silent mode or not
215  */
216  void monitor(bool silent);
217 
218  enum Mode {
219  Reset = 0,
220  Normal,
221  Silent,
222  LocalTest,
223  GlobalTest,
224  SilentTest
225  };
226 
227  /** Change CAN operation to the specified mode
228  *
229  * @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
230  *
231  * @returns
232  * 0 if mode change failed or unsupported,
233  * 1 if mode change was successful
234  */
235  int mode(Mode mode);
236 
237  /** Filter out incoming messages
238  *
239  * @param id the id to filter on
240  * @param mask the mask applied to the id
241  * @param format format to filter on (Default CANAny)
242  * @param handle message filter handle (Optional)
243  *
244  * @returns
245  * 0 if filter change failed or unsupported,
246  * new filter handle if successful
247  */
248  int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);
249 
250  /** Detects read errors - Used to detect read overflow errors.
251  *
252  * @returns number of read errors
253  */
254  unsigned char rderror();
255 
256  /** Detects write errors - Used to detect write overflow errors.
257  *
258  * @returns number of write errors
259  */
260  unsigned char tderror();
261 
262  enum IrqType {
263  RxIrq = 0,
264  TxIrq,
265  EwIrq,
266  DoIrq,
267  WuIrq,
268  EpIrq,
269  AlIrq,
270  BeIrq,
271  IdIrq,
272 
273  IrqCnt
274  };
275 
276  /** Attach a function to call whenever a CAN frame received interrupt is
277  * generated.
278  *
279  * This function locks the deep sleep while a callback is attached
280  *
281  * @param func A pointer to a void function, or 0 to set as none
282  * @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)
283  */
284  void attach(Callback<void()> func, IrqType type = RxIrq);
285 
286  /** Attach a member function to call whenever a CAN frame received interrupt
287  * is generated.
288  *
289  * @param obj pointer to the object to call the member function on
290  * @param method pointer to the member function to be called
291  * @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)
292  * @deprecated
293  * The attach function does not support cv-qualifiers. Replaced by
294  * attach(callback(obj, method), type).
295  */
296  template<typename T>
297  MBED_DEPRECATED_SINCE("mbed-os-5.1",
298  "The attach function does not support cv-qualifiers. Replaced by "
299  "attach(callback(obj, method), type).")
300  void attach(T *obj, void (T::*method)(), IrqType type = RxIrq)
301  {
302  // Underlying call thread safe
303  attach(callback(obj, method), type);
304  }
305 
306  /** Attach a member function to call whenever a CAN frame received interrupt
307  * is generated.
308  *
309  * @param obj pointer to the object to call the member function on
310  * @param method pointer to the member function to be called
311  * @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)
312  * @deprecated
313  * The attach function does not support cv-qualifiers. Replaced by
314  * attach(callback(obj, method), type).
315  */
316  template<typename T>
317  MBED_DEPRECATED_SINCE("mbed-os-5.1",
318  "The attach function does not support cv-qualifiers. Replaced by "
319  "attach(callback(obj, method), type).")
320  void attach(T *obj, void (*method)(T *), IrqType type = RxIrq)
321  {
322  // Underlying call thread safe
323  attach(callback(obj, method), type);
324  }
325 
326  static void _irq_handler(uint32_t id, CanIrqType type);
327 
328 #if !defined(DOXYGEN_ONLY)
329 protected:
330  virtual void lock();
331  virtual void unlock();
332 
333  can_t _can;
334  Callback<void()> _irq[IrqCnt];
335  PlatformMutex _mutex;
336 #endif
337 };
338 
339 /** @}*/
340 
341 } // namespace mbed
342 
343 #endif
344 
345 #endif // MBED_CAN_H
346 
CANType
Values that represent CAN Type.
Definition: can_helper.h:48
CANMessage class.
Definition: CAN.h:44
CANMessage()
Creates empty CAN message.
Definition: CAN.h:49
Transmit Data Register Empty.
Definition: serial_api.h:77
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:169
The PlatformMutex class is used to synchronize the execution of threads.
Definition: PlatformMutex.h:47
Receive Data Register Full.
Definition: serial_api.h:76
CANFormat
Values that represent CAN Format.
Definition: can_helper.h:35
Callback< R(ArgTs...)> callback(R(*func)(ArgTs...)=0)
Create a callback class with type inferred from the arguments.
Definition: Callback.h:709
CANMessage(unsigned int _id, CANFormat _format=CANStandard)
Creates CAN remote message.
Definition: CAN.h:98
CANMessage(unsigned int _id, const unsigned char *_data, unsigned char _len=8, CANType _type=CANData, CANFormat _format=CANStandard)
Creates CAN message with specific content.
Definition: CAN.h:66
CANMessage(unsigned int _id, const char *_data, unsigned char _len=8, CANType _type=CANData, CANFormat _format=CANStandard)
Creates CAN message with specific content.
Definition: CAN.h:84
Callback class based on template specialization.
Definition: Callback.h:39
A can bus client, used for communicating with can devices.
Definition: CAN.h:118
Holder for single CAN message.
Definition: can_helper.h:61
#define MBED_DEPRECATED_SINCE(D, M)
MBED_DEPRECATED("message string") Mark a function declaration as deprecated, if it used then a warnin...
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.