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 > 8) ? 8 : _len;
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 > 8) ? 8 : _len;
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  * ThisThread::sleep_for(200);
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  /** Initialize CAN interface
174  *
175  * @param pinmap reference to structure which holds static pinmap
176  * @param td the transmit pin
177  * @param hz the bus frequency in hertz
178  */
179  CAN(const can_pinmap_t &pinmap);
180  CAN(const can_pinmap_t &&) = delete; // prevent passing of temporary objects
181 
182  /** Initialize CAN interface and set the frequency
183  *
184  * @param pinmap reference to structure which holds static pinmap
185  * @param td the transmit pin
186  * @param hz the bus frequency in hertz
187  */
188  CAN(const can_pinmap_t &pinmap, int hz);
189  CAN(const can_pinmap_t &&, int) = delete; // prevent passing of temporary objects
190 
191  virtual ~CAN();
192 
193  /** Set the frequency of the CAN interface
194  *
195  * @param hz The bus frequency in hertz
196  *
197  * @returns
198  * 1 if successful,
199  * 0 otherwise
200  */
201  int frequency(int hz);
202 
203  /** Write a CANMessage to the bus.
204  *
205  * @param msg The CANMessage to write.
206  *
207  * @returns
208  * 0 if write failed,
209  * 1 if write was successful
210  */
211  int write(CANMessage msg);
212 
213  /** Read a CANMessage from the bus.
214  *
215  * @param msg A CANMessage to read to.
216  * @param handle message filter handle (0 for any message)
217  *
218  * @returns
219  * 0 if no message arrived,
220  * 1 if message arrived
221  */
222  int read(CANMessage &msg, int handle = 0);
223 
224  /** Reset CAN interface.
225  *
226  * To use after error overflow.
227  */
228  void reset();
229 
230  /** Puts or removes the CAN interface into silent monitoring mode
231  *
232  * @param silent boolean indicating whether to go into silent mode or not
233  */
234  void monitor(bool silent);
235 
236  enum Mode {
237  Reset = 0,
238  Normal,
239  Silent,
240  LocalTest,
241  GlobalTest,
242  SilentTest
243  };
244 
245  /** Change CAN operation to the specified mode
246  *
247  * @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
248  *
249  * @returns
250  * 0 if mode change failed or unsupported,
251  * 1 if mode change was successful
252  */
253  int mode(Mode mode);
254 
255  /** Filter out incoming messages
256  *
257  * @param id the id to filter on
258  * @param mask the mask applied to the id
259  * @param format format to filter on (Default CANAny)
260  * @param handle message filter handle (Optional)
261  *
262  * @returns
263  * 0 if filter change failed or unsupported,
264  * new filter handle if successful
265  */
266  int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);
267 
268  /** Detects read errors - Used to detect read overflow errors.
269  *
270  * @returns number of read errors
271  */
272  unsigned char rderror();
273 
274  /** Detects write errors - Used to detect write overflow errors.
275  *
276  * @returns number of write errors
277  */
278  unsigned char tderror();
279 
280  enum IrqType {
281  RxIrq = 0,
282  TxIrq,
283  EwIrq,
284  DoIrq,
285  WuIrq,
286  EpIrq,
287  AlIrq,
288  BeIrq,
289  IdIrq,
290 
291  IrqCnt
292  };
293 
294  /** Attach a function to call whenever a CAN frame received interrupt is
295  * generated.
296  *
297  * This function locks the deep sleep while a callback is attached
298  *
299  * @param func A pointer to a void function, or 0 to set as none
300  * @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)
301  */
302  void attach(Callback<void()> func, IrqType type = RxIrq);
303 
304  static void _irq_handler(uint32_t id, CanIrqType type);
305 
306 #if !defined(DOXYGEN_ONLY)
307 protected:
308  virtual void lock();
309  virtual void unlock();
310 
311  can_t _can;
312  Callback<void()> _irq[IrqCnt];
313  PlatformMutex _mutex;
314 #endif
315 };
316 
317 /** @}*/
318 
319 } // namespace mbed
320 
321 #endif
322 
323 #endif // MBED_CAN_H
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:162
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
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:53
Definition: ATHandler.h:46
A can bus client, used for communicating with can devices.
Definition: CAN.h:118
Holder for single CAN message.
Definition: can_helper.h:61
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.