can.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. // coding: utf-8
  2. // ----------------------------------------------------------------------------
  3. /*
  4. * Copyright (c) 2007 Fabian Greif, Roboterclub Aachen e.V.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. // ----------------------------------------------------------------------------
  29. /**
  30. * \file can.h
  31. * \brief Header-Datei für das allgemeine CAN Interface
  32. */
  33. // ----------------------------------------------------------------------------
  34. #ifndef CAN_H
  35. #define CAN_H
  36. #if defined (__cplusplus)
  37. extern "C" {
  38. #endif
  39. // ----------------------------------------------------------------------------
  40. /**
  41. * \ingroup communication
  42. * \defgroup can_interface Universelles CAN Interface
  43. * \brief allgemeines CAN Interface für AT90CAN32/64/128, MCP2515 und SJA1000
  44. *
  45. * \author Fabian Greif <fabian.greif@rwth-aachen.de>
  46. * \author Roboterclub Aachen e.V. (http://www.roboterclub.rwth-aachen.de)
  47. *
  48. * can_sleep() and can_wakeup() functions by Frédéric Lamorce.
  49. *
  50. * \version $Id: can.h 8086 2009-07-14 14:08:25Z fabian $
  51. */
  52. // ----------------------------------------------------------------------------
  53. #include <avr/pgmspace.h>
  54. #include <stdint.h>
  55. #include <stdbool.h>
  56. #include "config.h"
  57. // ----------------------------------------------------------------------------
  58. /** \ingroup can_interface
  59. * \name Bitdefinitionen
  60. */
  61. //@{
  62. #define ONLY_NON_RTR 2
  63. #define ONLY_RTR 3
  64. //@}
  65. /** \ingroup can_interface
  66. * \brief Bitraten fuer den CAN-Bus
  67. */
  68. typedef enum {
  69. BITRATE_10_KBPS = 0, // ungetestet
  70. BITRATE_20_KBPS = 1, // ungetestet
  71. BITRATE_50_KBPS = 2, // ungetestet
  72. BITRATE_100_KBPS = 3, // ungetestet
  73. BITRATE_125_KBPS = 4,
  74. BITRATE_250_KBPS = 5, // ungetestet
  75. BITRATE_500_KBPS = 6, // ungetestet
  76. BITRATE_1_MBPS = 7, // ungetestet
  77. } can_bitrate_t;
  78. /**
  79. * \ingroup can_interface
  80. * \brief Symbol um auf alle Filter zuzugreifen
  81. */
  82. #define CAN_ALL_FILTER 0xff
  83. /**
  84. * \ingroup can_interface
  85. * \brief Unterstuetzung fuer Extended-IDs aktivieren
  86. */
  87. #ifndef SUPPORT_EXTENDED_CANID
  88. #define SUPPORT_EXTENDED_CANID 1
  89. #endif
  90. /**
  91. * \ingroup can_interface
  92. * \brief Unterstützung für Zeitstempel aktivieren
  93. * \warning Wird nur vom AT90CANxxx unterstützt
  94. */
  95. #ifndef SUPPORT_TIMESTAMPS
  96. #define SUPPORT_TIMESTAMPS 0
  97. #endif
  98. /**
  99. * \ingroup can_interface
  100. * \name Bits des Filters fuer den MCP2515 umformatieren
  101. *
  102. * \code
  103. * uint8_t can_filter[] PROGMEM =
  104. * {
  105. * MCP2515_FILTER_EXTENDED(0), // Filter 0
  106. * MCP2515_FILTER_EXTENDED(0), // Filter 1
  107. *
  108. * MCP2515_FILTER_EXTENDED(0), // Filter 2
  109. * MCP2515_FILTER_EXTENDED(0), // Filter 3
  110. * MCP2515_FILTER_EXTENDED(0), // Filter 4
  111. * MCP2515_FILTER_EXTENDED(0), // Filter 5
  112. *
  113. * MCP2515_FILTER_EXTENDED(0), // Maske 0
  114. * MCP2515_FILTER_EXTENDED(0), // Maske 1
  115. * };
  116. * \endcode
  117. *
  118. * \see can_static_filter()
  119. *
  120. * \~german
  121. * \warning Dieses Makro sollte nur Werte verwendet die schon zur
  122. * Compile-Zeit bekannt sind. Der Code sollte ansonsten zwar trotzdem
  123. * funktionieren, wird danner aber sehr groß.
  124. *
  125. * \~english
  126. * \warning Do not use this Makro for Variables, only for static values
  127. * known at compile-time.
  128. */
  129. //@{
  130. #if defined(__DOXYGEN__)
  131. #define MCP2515_FILTER_EXTENDED(id)
  132. #define MCP2515_FILTER(id)
  133. #else
  134. #if SUPPORT_EXTENDED_CANID
  135. #define MCP2515_FILTER_EXTENDED(id) \
  136. (uint8_t) ((uint32_t) (id) >> 21), \
  137. (uint8_t)((((uint32_t) (id) >> 13) & 0xe0) | (1<<3) | \
  138. (((uint32_t) (id) >> 16) & 0x3)), \
  139. (uint8_t) ((uint32_t) (id) >> 8), \
  140. (uint8_t) ((uint32_t) (id))
  141. #endif
  142. #define MCP2515_FILTER(id) \
  143. (uint8_t)((uint32_t) id >> 3), \
  144. (uint8_t)((uint32_t) id << 5), \
  145. 0, \
  146. 0
  147. #endif
  148. //@}
  149. // ----------------------------------------------------------------------------
  150. /**
  151. * \ingroup can_interface
  152. * \brief Datenstruktur zum Aufnehmen von CAN Nachrichten
  153. */
  154. typedef struct
  155. {
  156. #if SUPPORT_EXTENDED_CANID
  157. uint32_t id; //!< ID der Nachricht (11 oder 29 Bit)
  158. struct {
  159. int rtr : 1; //!< Remote-Transmit-Request-Frame?
  160. int extended : 1; //!< extended ID?
  161. } flags;
  162. #else
  163. uint16_t id; //!< ID der Nachricht (11 Bit)
  164. struct {
  165. int rtr : 1; //!< Remote-Transmit-Request-Frame?
  166. } flags;
  167. #endif
  168. uint8_t length; //!< Anzahl der Datenbytes
  169. uint8_t data[8]; //!< Die Daten der CAN Nachricht
  170. #if SUPPORT_TIMESTAMPS
  171. uint16_t timestamp;
  172. #endif
  173. } can_t;
  174. // ----------------------------------------------------------------------------
  175. /**
  176. * \ingroup can_interface
  177. * \brief Datenstruktur zur Aufnahme von CAN-Filtern
  178. *
  179. * \code
  180. * rtr | Funtion
  181. * -----|------
  182. * 00 | alle Nachrichten unabhaengig vom RTR-Bit
  183. * 01 | ungültig
  184. * 10 | empfange nur nicht RTR-Nachrichten
  185. * 11 | empfange nur Nachrichten mit gesetzem RTR-Bit
  186. * \endcode
  187. *
  188. * \b ACHTUNG:
  189. * Funktioniert nur mit dem AT90CAN, beim MCP2515 wird der Parameter ignoriert.
  190. *
  191. * \code
  192. * ext | Funtion
  193. * -----|------
  194. * 00 | alle Nachrichten
  195. * 01 | ungueltig
  196. * 10 | empfange nur Standard-Nachrichten
  197. * 11 | empfange nur Extended-Nachrichten
  198. * \endcode
  199. *
  200. * \warning Filter sind beim SJA1000 nur begrenzt nutzbar, man sollte ihn nur
  201. * in Systemen mit entweder Standard- oder Extended-Frames einsetzten,
  202. * aber nicht beidem zusammen.
  203. */
  204. typedef struct
  205. {
  206. #if SUPPORT_EXTENDED_CANID
  207. uint32_t id; //!< ID der Nachricht (11 oder 29 Bit)
  208. uint32_t mask; //!< Maske
  209. struct {
  210. uint8_t rtr : 2; //!< Remote Request Frame
  211. uint8_t extended : 2; //!< extended ID
  212. } flags;
  213. #else
  214. uint16_t id; //!< ID der Nachricht 11 Bits
  215. uint16_t mask; //!< Maske
  216. struct {
  217. uint8_t rtr : 2; //!< Remote Request Frame
  218. } flags;
  219. #endif
  220. } can_filter_t;
  221. // ----------------------------------------------------------------------------
  222. /**
  223. * \ingroup can_interface
  224. * \brief Inhalt der Fehler-Register
  225. */
  226. typedef struct {
  227. uint8_t rx; //!< Empfangs-Register
  228. uint8_t tx; //!< Sende-Register
  229. } can_error_register_t;
  230. // ----------------------------------------------------------------------------
  231. /**
  232. * \ingroup can_interface
  233. * \brief Modus des CAN Interfaces
  234. */
  235. typedef enum {
  236. LISTEN_ONLY_MODE, //!< der CAN Contoller empfängt nur und verhält sich völlig passiv
  237. LOOPBACK_MODE, //!< alle Nachrichten direkt auf die Empfangsregister umleiten ohne sie zu senden
  238. NORMAL_MODE, //!< normaler Modus, CAN Controller ist aktiv
  239. SLEEP_MODE // sleep mode
  240. } can_mode_t;
  241. // ----------------------------------------------------------------------------
  242. /**
  243. * \ingroup can_interface
  244. * \brief Initialisierung des CAN Interfaces
  245. *
  246. * \param bitrate Gewuenschte Geschwindigkeit des CAN Interfaces
  247. *
  248. * \return false falls das CAN Interface nicht initialisiert werden konnte,
  249. * true ansonsten.
  250. */
  251. extern bool
  252. can_init(can_bitrate_t bitrate);
  253. // ----------------------------------------------------------------------------
  254. /**
  255. * \ingroup can_interface
  256. *
  257. * \~english
  258. * \brief Put CAN interface to sleep and wake up
  259. *
  260. * MCP2515 active : 5mA
  261. * MCP2515 sleep : 1µA
  262. *
  263. * MCP2551 active : 10mA+
  264. * MCP2551 sleep : 400µA
  265. *
  266. * \code
  267. * // before we are going to sleep, enable the interrupt that will wake us up
  268. // attach interrupt 1 to the routine
  269. EICRA = 0; // int on low level
  270. // Enable the interrupt1
  271. EIMSK = _BV(INT1);
  272. // put the MCP2515 to sleep
  273. can_sleep();
  274. // enable atmega sleep mode
  275. cli();
  276. sleep_enable();
  277. // turn off BOD
  278. sleep_bod_disable();
  279. // and we go to sleep
  280. sei();
  281. sleep_cpu();
  282. // here int1 has been executed and we are woken up
  283. sleep_disable();
  284. // disable int1
  285. EIMSK = 0;
  286. // re-enable 2515 and 2551
  287. can_wake();
  288. * \endcode
  289. *
  290. * \warning Only implemented for the MCP2515
  291. */
  292. extern void
  293. can_sleep(void);
  294. extern void
  295. can_wakeup(void);
  296. // ----------------------------------------------------------------------------
  297. /**
  298. * \ingroup can_interface
  299. * \brief Setzen eines Filters
  300. *
  301. * Für einen MCP2515 sollte die Funktion can_static_filter() bevorzugt werden.
  302. *
  303. * \param number Position des Filters
  304. * \param filter zu setzender Filter
  305. *
  306. * \return false falls ein Fehler auftrat, true ansonsten
  307. */
  308. extern bool
  309. can_set_filter(uint8_t number, const can_filter_t *filter);
  310. // ----------------------------------------------------------------------------
  311. /**
  312. * \ingroup can_interface
  313. * \brief Filter deaktivieren
  314. *
  315. * \param number Nummer des Filters der deaktiviert werden soll,
  316. * 0xff deaktiviert alle Filter.
  317. * \return false falls ein Fehler auftrat, true ansonsten
  318. *
  319. * \warning Wird nur vom AT90CAN32/64/128 unterstuetzt.
  320. */
  321. extern bool
  322. can_disable_filter(uint8_t number);
  323. // ----------------------------------------------------------------------------
  324. /**
  325. * \ingroup can_interface
  326. * \brief Setzt die Werte für alle Filter
  327. *
  328. * \code
  329. * // Filter und Masken-Tabelle anlegen
  330. * uint8_t can_filter[] PROGMEM = {
  331. * MCP2515_FILTER_EXTENDED(0), // Filter 0
  332. * MCP2515_FILTER_EXTENDED(0), // Filter 1
  333. *
  334. * MCP2515_FILTER_EXTENDED(0), // Filter 2
  335. * MCP2515_FILTER_EXTENDED(0), // Filter 3
  336. * MCP2515_FILTER_EXTENDED(0), // Filter 4
  337. * MCP2515_FILTER_EXTENDED(0), // Filter 5
  338. *
  339. * MCP2515_FILTER_EXTENDED(0), // Maske 0
  340. * MCP2515_FILTER_EXTENDED(0), // Maske 1
  341. * };
  342. *
  343. * ...
  344. *
  345. * // Filter und Masken-Tabelle laden
  346. * can_static_filter(can_filter);
  347. * \endcode
  348. *
  349. * \param *filter_array Array im Flash des AVRs mit den Initialisierungs-
  350. * werten für die Filter des MCP2515
  351. *
  352. * \see MCP2515_FILTER_EXTENDED()
  353. * \see MCP2515_FILTER()
  354. * \warning Wird nur vom MCP2515 unterstuetzt.
  355. */
  356. extern void
  357. can_static_filter(const uint8_t *filter_array);
  358. // ----------------------------------------------------------------------------
  359. /**
  360. * \ingroup can_interface
  361. *
  362. * \~german
  363. * \brief Filterdaten auslesen
  364. *
  365. * \param number Nummer des Filters dessen Daten man haben moechte
  366. * \param *filter Pointer in den die Filterstruktur geschrieben wird
  367. *
  368. * \return \b 0 falls ein Fehler auftrat, \
  369. * \b 1 falls der Filter korrekt gelesen werden konnte, \
  370. * \b 2 falls der Filter im Moment nicht verwendet wird (nur AT90CAN), \
  371. * \b 0xff falls gerade keine Aussage moeglich ist (nur AT90CAN).
  372. *
  373. * \warning Da der SJA1000 nicht feststellen kann ob der ausgelesene Filter
  374. * nun zwei 11-Bit Filter oder ein 29-Bit Filter ist werden nicht
  375. * die Filter sondern die Registerinhalte direkt zurück gegeben.
  376. * Der Programmierer muss dann selbst entscheiden was er mit den
  377. * Werten macht.
  378. *
  379. * \~english
  380. * \warning SJA1000 doesn't return the filter and id directly but the content
  381. * of the corresponding registers because it is not possible to
  382. * check the type of the filter.
  383. */
  384. extern uint8_t
  385. can_get_filter(uint8_t number, can_filter_t *filter);
  386. // ----------------------------------------------------------------------------
  387. /**
  388. * \ingroup can_interface
  389. * \brief Ueberpruefen ob neue CAN Nachrichten vorhanden sind
  390. *
  391. * \return true falls neue Nachrichten verfuegbar sind, false ansonsten.
  392. */
  393. extern bool
  394. can_check_message(void);
  395. // ----------------------------------------------------------------------------
  396. /**
  397. * \ingroup can_interface
  398. * \brief Ueberprueft ob ein Puffer zum Versenden einer Nachricht frei ist.
  399. *
  400. * \return true falls ein Sende-Puffer frei ist, false ansonsten.
  401. */
  402. extern bool
  403. can_check_free_buffer(void);
  404. // ----------------------------------------------------------------------------
  405. /**
  406. * \ingroup can_interface
  407. * \brief Verschickt eine Nachricht über den CAN Bus
  408. *
  409. * \param msg Nachricht die verschickt werden soll
  410. * \return FALSE falls die Nachricht nicht verschickt werden konnte, \n
  411. * ansonsten der Code des Puffes in den die Nachricht gespeichert wurde
  412. */
  413. extern uint8_t
  414. can_send_message(const can_t *msg);
  415. // ----------------------------------------------------------------------------
  416. /**
  417. * \ingroup can_interface
  418. * \brief Liest eine Nachricht aus den Empfangspuffern des CAN Controllers
  419. *
  420. * \param msg Pointer auf die Nachricht die gelesen werden soll.
  421. * \return FALSE falls die Nachricht nicht ausgelesen konnte,
  422. * ansonsten Filtercode welcher die Nachricht akzeptiert hat.
  423. */
  424. extern uint8_t
  425. can_get_message(can_t *msg);
  426. // ----------------------------------------------------------------------------
  427. /**
  428. * \ingroup can_interface
  429. *
  430. * \~german
  431. * \brief Liest den Inhalt der Fehler-Register
  432. *
  433. * \~english
  434. * \brief Reads the Contents of the CAN Error Counter
  435. */
  436. extern can_error_register_t
  437. can_read_error_register(void);
  438. // ----------------------------------------------------------------------------
  439. /**
  440. * \ingroup can_interface
  441. *
  442. * \~german
  443. * \brief Überprüft ob der CAN Controller im Bus-Off-Status
  444. *
  445. * \return true wenn der Bus-Off-Status aktiv ist, false ansonsten
  446. *
  447. * \warning aktuell nur auf dem SJA1000
  448. */
  449. extern bool
  450. can_check_bus_off(void);
  451. // ----------------------------------------------------------------------------
  452. /**
  453. * \ingroup can_interface
  454. *
  455. * \~german
  456. * \brief Setzt einen Bus-Off Status zurück und schaltet den CAN Controller
  457. * wieder aktiv
  458. *
  459. * \warning aktuell nur auf dem SJA1000
  460. */
  461. extern void
  462. can_reset_bus_off(void);
  463. // ----------------------------------------------------------------------------
  464. /**
  465. * \ingroup can_interface
  466. * \brief Setzt den Operations-Modus
  467. *
  468. * \param mode Gewünschter Modus des CAN Controllers
  469. */
  470. extern void
  471. can_set_mode(can_mode_t mode);
  472. #if defined (__cplusplus)
  473. }
  474. #endif
  475. #endif // CAN_H