hsk-libs-dev  270
High Speed Karlsruhe XC878 library collection
hsk_can.h
Go to the documentation of this file.
1 /** \file
2  * HSK Controller Area Network headers
3  *
4  * This file contains the function prototypes to initialize and engage in
5  * CAN communication over the builtin CAN nodes 0 and 1.
6  *
7  * @author kami
8  *
9  * \section tuples CAN Message/Signal Tuples
10  *
11  * The recommended way to use messages and signals is not to specify them
12  * inline, but to provide defines with a set of parameters.
13  *
14  * These tupples should follow the following pattern:
15  * \code
16  * #define MSG_<MSGNAME> <id>, <extended>, <dlc>
17  * #define SIG_<SIGNAME> <motorola>, <signed>, <bitPos>, <bitCount>
18  * \endcode
19  *
20  * The symbols have the following meaning:
21  * - MSGNAME: The name of the message in capitals, e.g. AFB_CHANNELS
22  * - id: The CAN id of the message, e.g. 0x403
23  * - extended: Whether the CAN ID is extended or not, e.g. 0 for a
24  * regular ID
25  * - dlc: The data length count of the message, e.g. 3
26  * - SIGNAME: The name of the signal in capitals, e.g.
27  * AFB_CHANNEL0_CURRENT
28  * - motorola: Whether the signal is in big endian (Motorola) format
29  * - signed: Whether the signal is signed
30  * - bitPos: The starting bit of the signal, e.g. 0
31  * - bitCount: The length of the signal in bits, e.g. 10
32  *
33  * Tuples using the specified format can directly be used as parameters
34  * for several functions in the library.
35  */
36 
37 #ifndef _HSK_CAN_H_
38 #define _HSK_CAN_H_
39 
40 /**
41  * Value returned by functions in case of an error.
42  */
43 #define CAN_ERROR 0xff
44 
45 /**
46  * CAN node 0.
47  */
48 #define CAN0 0
49 
50 /**
51  * CAN node 1.
52  */
53 #define CAN1 1
54 
55 /**
56  * CAN node 0 IO RX on P1.0, TX on P1.1.
57  */
58 #define CAN0_IO_P10_P11 0
59 
60 /**
61  * CAN node 0 IO RX on P1.6, TX on P1.7.
62  */
63 #define CAN0_IO_P16_P17 1
64 
65 /**
66  * CAN node 0 IO RX on P3.4, TX on P3.5.
67  */
68 #define CAN0_IO_P34_P35 2
69 
70 /**
71  * CAN node 0 IO RX on P4.0, TX on P4.1.
72  */
73 #define CAN0_IO_P40_P41 3
74 
75 /**
76  * CAN node 1 IO RX on P0.1, TX on P0.2.
77  */
78 #define CAN1_IO_P01_P02 4
79 
80 /**
81  * CAN node 1 IO RX on P1.4, TX on P1.3.
82  */
83 #define CAN1_IO_P14_P13 5
84 
85 /**
86  * CAN node 1 IO RX on P3.2, TX on P3.3.
87  */
88 #define CAN1_IO_P32_P33 6
89 
90 /**
91  * Little endian signal encoding.
92  *
93  * @deprecated
94  * In favour of shorter and cleaner code the hsk_can_data_getSignal()
95  * and hsk_can_data_setSignal() functions were switched to using
96  * boolean (motorola positive) logic
97  */
98 #define CAN_ENDIAN_INTEL 0
99 
100 /**
101  * Big endian signal encoding.
102  *
103  * @deprecated
104  * In favour of shorter and cleaner code the hsk_can_data_getSignal()
105  * and hsk_can_data_setSignal() functions were switched to using
106  * boolean (motorola positive) logic
107  */
108 #define CAN_ENDIAN_MOTOROLA 1
109 
110 /**
111  * CAN node identifiers.
112  */
113 typedef ubyte hsk_can_node;
114 
115 /**
116  * CAN message object identifiers.
117  */
118 typedef ubyte hsk_can_msg;
119 
120 /**
121  * CAN message FIFO identifiers.
122  */
123 typedef ubyte hsk_can_fifo;
124 
125 /** \file
126  * \section nodes CAN Node Management
127  *
128  * There are 7 port pairs available for CAN communication, check the CANn_IO_*
129  * defines. Four for the node CAN0 and three for CAN1.
130  */
131 
132 /**
133  * Setup CAN communication with the desired baud rate.
134  *
135  * The CAN node is chosen with the pin configuration.
136  *
137  * The bus still needs to be enabled after being setup.
138  *
139  * @param pins
140  * Choose one of 7 CANn_IO_* configurations
141  * @param baud
142  * The target baud rate to use
143  */
144 void hsk_can_init(const ubyte pins, const ulong __xdata baud);
145 
146 /**
147  * Go live on the CAN bus.
148  *
149  * To be called when everything is set up.
150  *
151  * @param node
152  * The CAN node to enable
153  */
154 void hsk_can_enable(const hsk_can_node node);
155 
156 /**
157  * Disable a CAN node.
158  *
159  * This completely shuts down a CAN node, cutting it off from the
160  * internal clock, to reduce energy consumption.
161  *
162  * @param node
163  * The CAN node to disable
164  */
165 void hsk_can_disable(const hsk_can_node node);
166 
167 /**
168  * \defgroup CAN_STATUS CAN Node Status Fields
169  *
170  * This group of defines specifies status fields that can be queried from
171  * hsk_can_status().
172  *
173  * @{
174  */
175 
176 /**
177  * The Last Error Code field provides the error triggered by the last message
178  * on the bus.
179  *
180  * For details check table 16-8 from the User Manual 1.1.
181  *
182  * @retval 0
183  * No Error
184  * @retval 1
185  * Stuff Error, 5 consecutive bits of the same value are stuffed, this
186  * error is triggered when the stuff bit is missing
187  * @retval 2
188  * Form Error, the frame format was violated
189  * @retval 3
190  * Ack Error, the message was not acknowledged, maybe nobody else
191  * is on the bus
192  * @retval 4
193  * Bit1 Error, a recessive (1) bit was sent out of sync
194  * @retval 5
195  * Bit0 Error, a recessive (1) bit won against a dominant (0) bit
196  * @retval 6
197  * CRC Error, wrong checksum for a received message
198  */
199 #define CAN_STATUS_LEC 0
200 
201 /**
202  * Message Transmitted Successfully.
203  *
204  * @retval 0
205  * No successful transmission since TXOK was queried last time
206  * @retval 1
207  * A message was transmitted and acknowledged successfully
208  */
209 #define CAN_STATUS_TXOK 1
210 
211 /**
212  * Message Received Successfully.
213  *
214  * @retval 0
215  * No successful receptions since the last time this field was queried
216  * @retval 1
217  * A message was received successfully
218  */
219 #define CAN_STATUS_RXOK 2
220 
221 /**
222  * Alert Warning.
223  *
224  * @retval 0
225  * No warnings
226  * @retval 1
227  * One of the following error conditions applies: \ref CAN_STATUS_EWRN;
228  * \ref CAN_STATUS_BOFF
229  */
230 #define CAN_STATUS_ALERT 3
231 
232 /**
233  * Error Warning Status.
234  *
235  * @retval 0
236  * No error warnings exceeded
237  * @retval 1
238  * An error counter has exceeded the warning level of 96
239  */
240 #define CAN_STATUS_EWRN 4
241 
242 /**
243  * Bus-off Status
244  *
245  * @retval 0
246  * The bus is not off
247  * @retval 1
248  * The bus is turned off due to an error counter exceeding 256
249  */
250 #define CAN_STATUS_BOFF 5
251 
252 /**
253  * @}
254  */
255 
256 /**
257  * Returns a status field of a CAN node.
258  *
259  * @param node
260  * The CAN node to return the status of
261  * @param field
262  * The status field to select
263  * @return
264  * The status field state
265  * @see \ref CAN_STATUS
266  */
267 ubyte hsk_can_status(const hsk_can_node node, const ubyte field);
268 
269 /** \file
270  * \section CAN Message Object Management
271  *
272  * The MultiCAN module offers up to 32 message objects. New messages are set
273  * up for receiving messages. Message object can be switched from RX to TX
274  * mode and back with the hsk_can_msg_send() and hsk_can_msg_receive()
275  * functions.
276  */
277 
278 /**
279  * Creates a new CAN message.
280  *
281  * Note that only up to 32 messages can exist at any given time.
282  *
283  * Extended messages have 29 bit IDs and non-extended 11 bit IDs.
284  *
285  * @param id
286  * The message ID.
287  * @param extended
288  * Set this to 1 for an extended CAN message.
289  * @param dlc
290  * The data length code, # of bytes in the message, valid values
291  * range from 0 to 8.
292  * @retval CAN_ERROR
293  * Creating the message failed
294  * @retval [0;32[
295  * A message identifier
296  */
297 hsk_can_msg hsk_can_msg_create(const ulong id, const bool extended,
298  const ubyte dlc);
299 
300 /**
301  * Connect a message object to a CAN node.
302  *
303  * @param msg
304  * The identifier of the message object
305  * @param node
306  * The CAN node to connect to
307  * @retval CAN_ERROR
308  * The given message is not valid
309  * @retval 0
310  * Success
311  */
312 ubyte hsk_can_msg_connect(const hsk_can_msg msg,
313  const hsk_can_node __xdata node);
314 
315 /**
316  * Disconnect a CAN message object from its CAN node.
317  *
318  * This takes a CAN message out of active communication, without deleting
319  * it.
320  *
321  * @param msg
322  * The identifier of the message object
323  * @retval CAN_ERROR
324  * The given message is not valid
325  * @retval 0
326  * Success
327  */
328 ubyte hsk_can_msg_disconnect(const hsk_can_msg msg);
329 
330 /**
331  * Delete a CAN message object.
332  *
333  * @param msg
334  * The identifier of the message object
335  * @retval CAN_ERROR
336  * The given message is not valid
337  * @retval 0
338  * Success
339  */
340 ubyte hsk_can_msg_delete(const hsk_can_msg msg);
341 
342 /**
343  * Gets the current data in the CAN message.
344  *
345  * This writes DLC bytes from the CAN message object into msgdata.
346  *
347  * @param msg
348  * The identifier of the message object
349  * @param msgdata
350  * The character array to store the message data in
351  */
352 void hsk_can_msg_getData(const hsk_can_msg msg,
353  ubyte * const msgdata);
354 
355 /**
356  * Sets the current data in the CAN message.
357  *
358  * This writes DLC bytes from msgdata to the CAN message object.
359  *
360  * @param msg
361  * The identifier of the message object
362  * @param msgdata
363  * The character array to get the message data from
364  */
365 void hsk_can_msg_setData(const hsk_can_msg msg,
366  const ubyte * const msgdata);
367 
368 /**
369  * Request transmission of a message.
370  *
371  * @param msg
372  * The identifier of the message to send
373  */
374 void hsk_can_msg_send(const hsk_can_msg msg);
375 
376 
377 /**
378  * Return whether the message was successfully sent between this and the
379  * previous call of this method.
380  *
381  * @param msg
382  * The identifier of the message to check
383  * @retval 1
384  * The message was sent since the last call of this function
385  * @retval 0
386  * The message has not been sent since the last call of this function
387  */
388 bool hsk_can_msg_sent(const hsk_can_msg msg);
389 
390 /**
391  * Return the message into RX mode after sending a message.
392  *
393  * After sending a message the messages with the same ID from other
394  * bus participants are ignored. This restores the original setting to receive
395  * messages.
396  *
397  * @param msg
398  * The identifier of the message to receive
399  */
400 void hsk_can_msg_receive(const hsk_can_msg msg);
401 
402 /**
403  * Return whether the message was updated via CAN bus between this call and
404  * the previous call of this method.
405  *
406  * An update does not entail a change of message data. It just means the
407  * message was received on the CAN bus.
408  *
409  * This is useful for cyclic message occurance checks.
410  *
411  * @param msg
412  * The identifier of the message to check
413  * @retval 1
414  * The message was updated since the last call of this function
415  * @retval 0
416  * The message has not been updated since the last call of this function
417  */
418 bool hsk_can_msg_updated(const hsk_can_msg msg);
419 
420 /** \file
421  * \section fifos FIFOs
422  *
423  * FIFOs are the weapon of choice when dealing with large numbers of
424  * individual messages or when receving multiplexed data. In most use cases
425  * only the latest version of a message is relevant and FIFOs are not
426  * required. But messages containing multiplexed signals may contain critical
427  * signals that would be overwritten by a message with the same ID, but a
428  * different multiplexor.
429  *
430  * If more message IDs than available message objects are used to send and/or
431  * receive data, there is no choice but to use a FIFO.
432  *
433  * Currently only RX FIFOs are supported.
434  *
435  * A FIFO can act as a buffer the CAN module can store message data in until
436  * it can be dealt with. The following example illustrates how to read from
437  * a FIFO:
438  * \code
439  * if (hsk_can_fifo_updated(fifo0)) {
440  * hsk_can_fifo_getData(fifo0, data0);
441  * hsk_can_fifo_next(fifo0);
442  * select = hsk_can_data_getSignal(data0, SIG_MULTIPLEXOR);
443  * [...]
444  * }
445  * \endcode
446  *
447  * When using a mask to accept several messages checking the ID becomes
448  * necessary:
449  * \code
450  * if (hsk_can_fifo_updated(fifo0)) {
451  * switch (hsk_can_fifo_getId()) {
452  * case MSG_0_ID:
453  * hsk_can_fifo_getData(fifo0, data0);
454  * [...]
455  * break;
456  * case MSG_1_ID:
457  * hsk_can_fifo_getData(fifo0, data1);
458  * [...]
459  * break;
460  * [...]
461  * }
462  * hsk_can_fifo_next(fifo0);
463  * }
464  * \endcode
465  *
466  *
467  * FIFOs draw from the same message object pool regular message objects do.
468  */
469 
470 /**
471  * Creates a message FIFO.
472  *
473  * FIFOs can be used to ensure that multiplexed signals are not lost.
474  *
475  * For receiving multiplexed signals it is recommended to use a FIFO as large
476  * as the number of multiplexed messages that might occur in a single burst.
477  *
478  * If the multiplexor is large, e.g. 8 bits, it's obviously not possible to
479  * carve a 256 messages FIFO out of 32 message objects. Make an educated
480  * guess and hope that the signal provider is not hostile.
481  *
482  * If the number of available message objects is at least one, but less than
483  * the requested length this function succeeds, but the FIFO is only created
484  * as long as possible.
485  *
486  * @param size
487  * The desired FIFO size
488  * @retval CAN_ERROR
489  * Creating the FIFO failed
490  * @retval [0;32[
491  * The created FIFO id
492  */
494 
495 /**
496  * Set the FIFO up for receiving messages.
497  *
498  * @param fifo
499  * The FIFO to setup
500  * @param id
501  * The message ID.
502  * @param extended
503  * Set this to 1 for an extended CAN message
504  * @param dlc
505  * The data length code, # of bytes in the message, valid values
506  * range from 0 to 8
507  */
508 void hsk_can_fifo_setupRx(hsk_can_fifo fifo, const ulong id,
509  const bool extended, const ubyte dlc);
510 
511 /**
512  * Changes the ID matching mask of an RX FIFO.
513  *
514  * Every RX FIFO is setup to receive only on complete ID matches. This
515  * function allows updating the mask.
516  *
517  * To generate a mask from a list of IDs use the following formula:
518  * \f[ msk = \sim(id_0 | id_1 | ... | id_n) | (id_0 \& id_1 \& ... \& id_n) \f]
519  *
520  * @pre hsk_can_fifo_setupRx()
521  * @param fifo
522  * The FIFO to change the RX mask for
523  * @param msk
524  * The bit mask to set for the FIFO
525  */
526 void hsk_can_fifo_setRxMask(const hsk_can_fifo fifo, ulong msk);
527 
528 /**
529  * Connect a FIFO to a CAN node.
530  *
531  * @param fifo
532  * The identifier of the FIFO
533  * @param node
534  * The CAN node to connect to
535  * @retval CAN_ERROR
536  * The given FIFO is not valid
537  * @retval 0
538  * Success
539  */
540 ubyte hsk_can_fifo_connect(const hsk_can_fifo fifo,
541  const hsk_can_node __xdata node);
542 
543 /**
544  * Disconnect a FIFO from its CAN node.
545  *
546  * This takes the FIFO out of active communication, without deleting
547  * it.
548  *
549  * @param fifo
550  * The identifier of the FIFO
551  * @retval CAN_ERROR
552  * The given FIFO is not valid
553  * @retval 0
554  * Success
555  */
556 ubyte hsk_can_fifo_disconnect(const hsk_can_fifo fifo);
557 
558 /**
559  * Delete a FIFO.
560  *
561  * @param fifo
562  * The identifier of the FIFO
563  * @retval CAN_ERROR
564  * The given FIFO is not valid
565  * @retval 0
566  * Success
567  */
568 ubyte hsk_can_fifo_delete(const hsk_can_fifo fifo);
569 
570 /**
571  * Select the next FIFO entry.
572  *
573  * The hsk_can_fifo_updated() and hsk_can_fifo_getData() functions always
574  * refer to a certain message within the FIFO. This function selects the
575  * next entry.
576  *
577  * @param fifo
578  * The ID of the FIFO to select the next entry from
579  */
580 void hsk_can_fifo_next(const hsk_can_fifo fifo);
581 
582 /**
583  * Returns the CAN ID of the selected FIFO entry.
584  *
585  * @param fifo
586  * The ID of the FIFO
587  * @return
588  * The ID of the currently selected message object
589  */
590 ulong hsk_can_fifo_getId(const hsk_can_fifo fifo);
591 
592 /**
593  * Return whether the currently selected FIFO entry was updated via CAN bus
594  * between this call and the previous call of this method.
595  *
596  * It can be used to decide when to call hsk_can_fifo_getData() and
597  * hsk_can_fifo_next().
598  *
599  * @param fifo
600  * The identifier of the FIFO to check
601  * @retval 1
602  * The FIFO entry was updated since the last call of this function
603  * @retval 0
604  * The FIFO entry has not been updated since the last call of this function
605  */
606 bool hsk_can_fifo_updated(const hsk_can_fifo fifo);
607 
608 /**
609  * Gets the data from the currently selected FIFO entry.
610  *
611  * This writes DLC bytes from the FIFO entry into msgdata.
612  *
613  * @param fifo
614  * The identifier of the FIFO
615  * @param msgdata
616  * The character array to store the message data in
617  */
618 void hsk_can_fifo_getData(const hsk_can_fifo fifo,
619  ubyte * const msgdata);
620 
621 /** \file
622  * \section data Message Data
623  *
624  * The hsk_can_data_setSignal() and hsk_can_data_getSignal() functions allow
625  * writing and reading signals across byte boundaries to and from a buffer.
626  *
627  * For big endian signals the bit position of the most significant bit must
628  * be supplied (highest bit in the first byte). For little endian signals
629  * the least significant bit must be supplied (lowest bit in the first byte).
630  *
631  * This conforms to the way signal positions are stored in Vector CANdb++
632  * DBC files.
633  */
634 
635 /**
636  * Sets a signal value in a data field.
637  *
638  * @param msg
639  * The message data field to write into
640  * @param motorola
641  * Indicates big endian (Motorola) encoding
642  * @param sign
643  * Indicates whether the value has a signed type
644  * @param bitPos
645  * The bit position of the signal
646  * @param bitCount
647  * The length of the signal
648  * @param value
649  * The signal value to write into the data field
650  */
651 void hsk_can_data_setSignal(ubyte * const msg, const bool motorola,
652  const bool sign, const ubyte bitPos,
653  const char bitCount, const ulong idata value);
654 
655 /**
656  * Get a signal value from a data field.
657  *
658  * @param msg
659  * The message data field to read from
660  * @param motorola
661  * Indicates big endian (Motorola) encoding
662  * @param sign
663  * Indicates whether the value has a signed type
664  * @param bitPos
665  * The bit position of the signal
666  * @param bitCount
667  * The length of the signal
668  * @return
669  * The signal from the data field msg
670  */
671 ulong hsk_can_data_getSignal(const ubyte * const msg, const bool motorola,
672  const bool sign, const ubyte bitPos,
673  const char bitCount);
674 
675 #endif /* _HSK_CAN_H_ */
uword size
The size of the data structure to persist.
Definition: hsk_flash.c:430
ulong hsk_can_fifo_getId(const hsk_can_fifo fifo)
Returns the CAN ID of the selected FIFO entry.
Definition: hsk_can.c:1429
ubyte hsk_can_msg_connect(const hsk_can_msg msg, const hsk_can_node node)
Connect a message object to a CAN node.
Definition: hsk_can.c:992
bool hsk_can_msg_updated(const hsk_can_msg msg)
Return whether the message was updated via CAN bus between this call and the previous call of this me...
Definition: hsk_can.c:1114
void hsk_can_fifo_setupRx(hsk_can_fifo fifo, const ulong id, const bool extended, const ubyte dlc)
Set the FIFO up for receiving messages.
Definition: hsk_can.c:1227
hsk_can_msg hsk_can_msg_create(const ulong id, const bool extended, const ubyte dlc)
Creates a new CAN message.
Definition: hsk_can.c:869
void hsk_can_data_setSignal(ubyte *const msg, const bool motorola, const bool sign, const ubyte bitPos, const char bitCount, const ulong value)
Sets a signal value in a data field.
Definition: hsk_can.c:1538
void hsk_can_msg_send(const hsk_can_msg msg)
Request transmission of a message.
Definition: hsk_can.c:1082
ubyte hsk_can_fifo
CAN message FIFO identifiers.
Definition: hsk_can.h:123
void hsk_can_msg_receive(const hsk_can_msg msg)
Return the message into RX mode after sending a message.
Definition: hsk_can.c:1106
void hsk_can_enable(const hsk_can_node node)
Go live on the CAN bus.
Definition: hsk_can.c:575
void hsk_can_fifo_getData(const hsk_can_fifo fifo, ubyte *const msgdata)
Gets the data from the currently selected FIFO entry.
Definition: hsk_can.c:1421
bool hsk_can_msg_sent(const hsk_can_msg msg)
Return whether the message was successfully sent between this and the previous call of this method...
Definition: hsk_can.c:1090
void hsk_can_disable(const hsk_can_node node)
Disable a CAN node.
Definition: hsk_can.c:584
void hsk_can_fifo_setRxMask(const hsk_can_fifo fifo, ulong msk)
Changes the ID matching mask of an RX FIFO.
Definition: hsk_can.c:1280
void hsk_can_fifo_next(const hsk_can_fifo fifo)
Select the next FIFO entry.
Definition: hsk_can.c:1392
void hsk_can_msg_setData(const hsk_can_msg msg, const ubyte *const msgdata)
Sets the current data in the CAN message.
Definition: hsk_can.c:1050
ubyte hsk_can_msg_delete(const hsk_can_msg msg)
Delete a CAN message object.
Definition: hsk_can.c:1002
ubyte hsk_can_node
CAN node identifiers.
Definition: hsk_can.h:113
ubyte hsk_can_fifo_connect(const hsk_can_fifo fifo, const hsk_can_node node)
Connect a FIFO to a CAN node.
Definition: hsk_can.c:1376
ubyte hsk_can_msg
CAN message object identifiers.
Definition: hsk_can.h:118
void hsk_can_msg_getData(const hsk_can_msg msg, ubyte *const msgdata)
Gets the current data in the CAN message.
Definition: hsk_can.c:1007
ulong hsk_can_data_getSignal(const ubyte *const msg, const bool motorola, const bool sign, const ubyte bitPos, const char bitCount)
Get a signal value from a data field.
Definition: hsk_can.c:1630
ubyte hsk_can_status(const hsk_can_node node, const ubyte field)
Returns a status field of a CAN node.
Definition: hsk_can.c:593
ubyte hsk_can_fifo_delete(const hsk_can_fifo fifo)
Delete a FIFO.
Definition: hsk_can.c:1387
void hsk_can_init(const ubyte pins, const ulong baud)
Setup CAN communication with the desired baud rate.
Definition: hsk_can.c:397
hsk_can_fifo hsk_can_fifo_create(ubyte size)
Creates a message FIFO.
Definition: hsk_can.c:1130
bool hsk_can_fifo_updated(const hsk_can_fifo fifo)
Return whether the currently selected FIFO entry was updated via CAN bus between this call and the pr...
Definition: hsk_can.c:1414
ubyte hsk_can_msg_disconnect(const hsk_can_msg msg)
Disconnect a CAN message object from its CAN node.
Definition: hsk_can.c:997
ubyte hsk_can_fifo_disconnect(const hsk_can_fifo fifo)
Disconnect a FIFO from its CAN node.
Definition: hsk_can.c:1382