can.h


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
35
#ifndef CAN_H
36
#define CAN_H
37
38
#if defined (__cplusplus)
39
  extern "C" {
40
#endif
41
42
// ----------------------------------------------------------------------------
43
/**
44
 * \ingroup    communication
45
 * \defgroup   can_interface Universelles CAN Interface
46
 * \brief    allgemeines CAN Interface für AT90CAN32/64/128, MCP2515 und SJA1000
47
 *
48
 * \author     Fabian Greif <fabian.greif@rwth-aachen.de>
49
 * \author      Roboterclub Aachen e.V. (http://www.roboterclub.rwth-aachen.de)
50
 *
51
 * \version    $Id: can.h 6927 2008-12-03 22:42:59Z fabian $
52
 */
53
// ----------------------------------------------------------------------------
54
55
#include <avr/pgmspace.h>
56
#include <stdint.h>
57
#include <stdbool.h>
58
59
#include "config.h"
60
61
// ----------------------------------------------------------------------------
62
/** \ingroup  can_interface
63
 *  \name    Bitdefinitionen
64
 */
65
//@{
66
#define  ONLY_NON_RTR    2
67
#define  ONLY_RTR      3
68
//@}
69
70
/** \ingroup  can_interface
71
 *  \brief    Bitraten fuer den CAN-Bus 
72
 */
73
typedef enum {
74
  BITRATE_10_KBPS  = 0,  // ungetestet
75
  BITRATE_20_KBPS  = 1,  // ungetestet
76
  BITRATE_50_KBPS  = 2,  // ungetestet
77
  BITRATE_100_KBPS = 3,  // ungetestet
78
  BITRATE_125_KBPS = 4,
79
  BITRATE_250_KBPS = 5,  // ungetestet
80
  BITRATE_500_KBPS = 6,  // ungetestet
81
  BITRATE_1_MBPS = 7,    // ungetestet
82
} can_bitrate_t;
83
84
/**
85
 * \ingroup      can_interface
86
 * \brief    Symbol um auf alle Filter zuzugreifen
87
 */
88
#define  CAN_ALL_FILTER    0xff
89
90
/**
91
 * \ingroup      can_interface
92
 * \brief    Unterstuetzung fuer Extended-IDs aktivieren
93
 */
94
#ifndef  SUPPORT_EXTENDED_CANID
95
  #define  SUPPORT_EXTENDED_CANID  1
96
#endif
97
98
/**
99
 * \ingroup     can_interface
100
 * \brief    Unterstützung für Zeitstempel aktivieren
101
 * \warning     Wird nur vom AT90CANxxx unterstützt
102
 */
103
#ifndef  SUPPORT_TIMESTAMPS
104
  #define  SUPPORT_TIMESTAMPS    0
105
#endif
106
107
/**
108
 * \ingroup      can_interface
109
 * \name    Bits des Filters fuer den MCP2515 umformatieren
110
 *
111
 * \code
112
 *  prog_uint8_t can_filter[] =
113
 *  {
114
 *    MCP2515_FILTER_EXTENDED(0),  // Filter 0
115
 *    MCP2515_FILTER_EXTENDED(0),  // Filter 1
116
 *    
117
 *    MCP2515_FILTER_EXTENDED(0),  // Filter 2
118
 *    MCP2515_FILTER_EXTENDED(0),  // Filter 3
119
 *    MCP2515_FILTER_EXTENDED(0),  // Filter 4
120
 *    MCP2515_FILTER_EXTENDED(0),  // Filter 5
121
 *    
122
 *    MCP2515_FILTER_EXTENDED(0),  // Maske 0
123
 *    MCP2515_FILTER_EXTENDED(0),  // Maske 1
124
 *  };
125
 * \endcode
126
 *
127
 * \see      can_static_filter()
128
 *
129
 * \~german
130
 * \warning    Dieses Makro sollte nur Werte verwendet die schon zur
131
 *        Compile-Zeit bekannt sind. Der Code sollte ansonsten zwar trotzdem
132
 *        funktionieren, wird danner aber sehr groß.
133
 *
134
 * \~english
135
 * \warning    Do not use this Makro for Variables, only for static values
136
 *        known at compile-time.
137
 */
138
//@{
139
#if defined(__DOXYGEN__)
140
141
  #define  MCP2515_FILTER_EXTENDED(id)
142
  #define  MCP2515_FILTER(id)
143
144
#else
145
146
  #if SUPPORT_EXTENDED_CANID  
147
    #define MCP2515_FILTER_EXTENDED(id)  \
148
        (uint8_t)  ((uint32_t) (id) >> 21), \
149
        (uint8_t)((((uint32_t) (id) >> 13) & 0xe0) | (1<<3) | \
150
          (((uint32_t) (id) >> 16) & 0x3)), \
151
        (uint8_t)  ((uint32_t) (id) >> 8), \
152
        (uint8_t)  ((uint32_t) (id))
153
  #endif
154
  
155
  #define  MCP2515_FILTER(id) \
156
      (uint8_t)((uint32_t) id >> 3), \
157
      (uint8_t)((uint32_t) id << 5), \
158
      0, \
159
      0
160
#endif
161
//@}
162
// ----------------------------------------------------------------------------
163
/**
164
 * \ingroup  can_interface
165
 * \brief  Datenstruktur zum Aufnehmen von CAN Nachrichten
166
 */
167
typedef struct
168
{
169
  #if SUPPORT_EXTENDED_CANID  
170
    uint32_t id;        //!< ID der Nachricht (11 oder 29 Bit)
171
    struct {
172
      int rtr : 1;      //!< Remote-Transmit-Request-Frame?
173
      int extended : 1;    //!< extended ID?
174
    } flags;
175
  #else
176
    uint16_t id;        //!< ID der Nachricht (11 Bit)
177
    struct {
178
      int rtr : 1;      //!< Remote-Transmit-Request-Frame?
179
    } flags;
180
  #endif
181
  
182
  uint8_t length;        //!< Anzahl der Datenbytes
183
  uint8_t data[8];      //!< Die Daten der CAN Nachricht
184
  
185
  #if SUPPORT_TIMESTAMPS
186
    uint16_t timestamp;
187
  #endif
188
} can_t;
189
190
191
192
// ----------------------------------------------------------------------------
193
/**
194
 * \ingroup  can_interface
195
 * \brief  Datenstruktur zur Aufnahme von CAN-Filtern
196
 *
197
 * \code
198
 *  rtr | Funtion
199
 * -----|------
200
 *  00  | alle Nachrichten unabhaengig vom RTR-Bit
201
 *  01  | ungültig
202
 *  10  | empfange nur nicht RTR-Nachrichten
203
 *  11  | empfange nur Nachrichten mit gesetzem RTR-Bit
204
 * \endcode
205
 *
206
 * \b ACHTUNG:
207
 * Funktioniert nur mit dem AT90CAN, beim MCP2515 wird der Parameter ignoriert. 
208
 *
209
 * \code
210
 *  ext | Funtion
211
 * -----|------
212
 *  00  | alle Nachrichten
213
 *  01  | ungueltig
214
 *  10  | empfange nur Standard-Nachrichten
215
 *  11  | empfange nur Extended-Nachrichten
216
 * \endcode
217
 *
218
 * \warning  Filter sind beim SJA1000 nur begrenzt nutzbar, man sollte ihn nur
219
 *       in Systemen mit entweder Standard- oder Extended-Frames einsetzten,
220
 *       aber nicht beidem zusammen.
221
 */
222
223
typedef struct
224
{
225
  #if  SUPPORT_EXTENDED_CANID
226
    uint32_t id;        //!< ID der Nachricht (11 oder 29 Bit)
227
    uint32_t mask;        //!< Maske
228
    struct {
229
      uint8_t rtr : 2;    //!< Remote Request Frame
230
      uint8_t extended : 2;  //!< extended ID
231
    } flags;
232
  #else
233
    uint16_t id;        //!< ID der Nachricht 11 Bits
234
    uint16_t mask;        //!< Maske
235
      struct {
236
      uint8_t rtr : 2;    //!< Remote Request Frame
237
    } flags;
238
  #endif
239
} can_filter_t;
240
241
242
// ----------------------------------------------------------------------------
243
/**
244
 * \ingroup can_interface
245
 * \brief   Inhalt der Fehler-Register
246
 */
247
typedef struct {
248
  uint8_t rx;        //!< Empfangs-Register
249
  uint8_t tx;        //!< Sende-Register
250
} can_error_register_t;
251
252
// ----------------------------------------------------------------------------
253
/**
254
 * \ingroup can_interface
255
 * \brief   Modus des CAN Interfaces
256
 */
257
typedef enum {
258
  LISTEN_ONLY_MODE,    //!< der CAN Contoller empfängt nur und verhält sich völlig passiv
259
  LOOPBACK_MODE,      //!< alle Nachrichten direkt auf die Empfangsregister umleiten ohne sie zu senden
260
  NORMAL_MODE        //!< normaler Modus, CAN Controller ist aktiv
261
} can_mode_t;
262
263
// ----------------------------------------------------------------------------
264
/**
265
 * \ingroup  can_interface
266
 * \brief  Initialisierung des CAN Interfaces
267
 *
268
 * \param  bitrate  Gewuenschte Geschwindigkeit des CAN Interfaces
269
 *
270
 * \return  false falls das CAN Interface nicht initialisiert werden konnte,
271
 *      true ansonsten.
272
 */
273
extern bool can_init(can_bitrate_t bitrate);
274
275
// ----------------------------------------------------------------------------
276
/**
277
 * \ingroup  can_interface
278
 * \brief  Setzen eines Filters
279
 * 
280
 * Für einen MCP2515 sollte die Funktion can_static_filter() bevorzugt werden.
281
 *
282
 * \param  number  Position des Filters
283
 * \param  filter  zu setzender Filter
284
 *
285
 * \return  false falls ein Fehler auftrat, true ansonsten
286
 */
287
extern bool can_set_filter(uint8_t number, const can_filter_t *filter);
288
289
// ----------------------------------------------------------------------------
290
/**
291
 * \ingroup  can_interface
292
 * \brief  Filter deaktivieren
293
 *
294
 * \param  number  Nummer des Filters der deaktiviert werden soll,
295
 *      0xff deaktiviert alle Filter.
296
 * \return  false falls ein Fehler auftrat, true ansonsten
297
 *
298
 * \warning Wird nur vom AT90CAN32/64/128 unterstuetzt.
299
 */
300
extern bool can_disable_filter(uint8_t number);
301
302
// ----------------------------------------------------------------------------
303
/**
304
 * \ingroup  can_interface
305
 * \brief  Setzt die Werte für alle Filter
306
 *
307
 * \code
308
 * // Filter und Masken-Tabelle anlegen
309
 * prog_char can_filter[] = {
310
 *   MCP2515_FILTER_EXTENDED(0),  // Filter 0
311
 *   MCP2515_FILTER_EXTENDED(0),  // Filter 1
312
 *   
313
 *   MCP2515_FILTER_EXTENDED(0),  // Filter 2
314
 *   MCP2515_FILTER_EXTENDED(0),  // Filter 3
315
 *   MCP2515_FILTER_EXTENDED(0),  // Filter 4
316
 *   MCP2515_FILTER_EXTENDED(0),  // Filter 5
317
 *   
318
 *   MCP2515_FILTER_EXTENDED(0),  // Maske 0
319
 *   MCP2515_FILTER_EXTENDED(0),  // Maske 1
320
 * };
321
 * 
322
 * ...
323
 *
324
 * // Filter und Masken-Tabelle laden
325
 * can_static_filter(can_filter);
326
 * \endcode
327
 *
328
 * \param  *filter_array  Array im Flash des AVRs mit den Initialisierungs-
329
 *              werten für die Filter des MCP2515
330
 * 
331
 * \see    MCP2515_FILTER_EXTENDED()
332
 * \see    MCP2515_FILTER()
333
 * \warning  Wird nur vom MCP2515 unterstuetzt.
334
 */
335
extern void can_static_filter(const prog_uint8_t *filter_array);
336
337
// ----------------------------------------------------------------------------
338
/**
339
 * \ingroup  can_interface
340
 * 
341
 * \~german
342
 * \brief  Filterdaten auslesen
343
 *
344
 * \param  number  Nummer des Filters dessen Daten man haben moechte
345
 * \param  *filter  Pointer in den die Filterstruktur geschrieben wird
346
 *
347
 * \return  \b 0 falls ein Fehler auftrat, \
348
 *      \b 1 falls der Filter korrekt gelesen werden konnte, \
349
 *      \b 2 falls der Filter im Moment nicht verwendet wird (nur AT90CAN), \
350
 *      \b 0xff falls gerade keine Aussage moeglich ist (nur AT90CAN).
351
 *
352
 * \warning  Da der SJA1000 nicht feststellen kann ob der ausgelesene Filter
353
 *      nun zwei 11-Bit Filter oder ein 29-Bit Filter ist werden nicht
354
 *      die Filter sondern die Registerinhalte direkt zurück gegeben.
355
 *      Der Programmierer muss dann selbst entscheiden was er mit den 
356
 *       Werten macht.
357
 *
358
 * \~english
359
 * \warning SJA1000 doesn't return the filter and id directly but the content
360
 *      of the corresponding registers because it is not possible to
361
 *      check the type of the filter.
362
 */
363
extern uint8_t can_get_filter(uint8_t number, can_filter_t *filter);
364
365
// ----------------------------------------------------------------------------
366
/**
367
 * \ingroup  can_interface
368
 * \brief  Ueberpruefen ob neue CAN Nachrichten vorhanden sind
369
 *
370
 * \return  true falls neue Nachrichten verfuegbar sind, false ansonsten.
371
 */
372
extern bool can_check_message(void);
373
374
// ----------------------------------------------------------------------------
375
/**
376
 * \ingroup  can_interface
377
 * \brief  Ueberprueft ob ein Puffer zum Versenden einer Nachricht frei ist.
378
 *
379
 * \return  true falls ein Sende-Puffer frei ist, false ansonsten.
380
 */
381
extern bool can_check_free_buffer(void);
382
383
// ----------------------------------------------------------------------------
384
/**
385
 * \ingroup  can_interface
386
 * \brief  Verschickt eine Nachricht über den CAN Bus
387
 *
388
 * \param  msg  Nachricht die verschickt werden soll
389
 * \return  FALSE falls die Nachricht nicht verschickt werden konnte, \n
390
 *      ansonsten der Code des Puffes in den die Nachricht gespeichert wurde
391
 */
392
extern uint8_t can_send_message(const can_t *msg);
393
394
// ----------------------------------------------------------------------------
395
/**
396
 * \ingroup  can_interface
397
 * \brief  Liest eine Nachricht aus den Empfangspuffern des CAN Controllers
398
 *
399
 * \param  msg  Pointer auf die Nachricht die gelesen werden soll.
400
 * \return  FALSE falls die Nachricht nicht ausgelesen konnte,
401
 *      ansonsten Filtercode welcher die Nachricht akzeptiert hat.
402
 */
403
extern uint8_t can_get_message(can_t *msg);
404
405
// ----------------------------------------------------------------------------
406
/**
407
 * \ingroup  can_interface
408
 *
409
 * \~german
410
 * \brief   Liest den Inhalt der Fehler-Register
411
 *
412
 * \~english
413
 * \brief  Reads the Contents of the CAN Error Counter
414
 */
415
extern can_error_register_t can_read_error_register(void);
416
417
// ----------------------------------------------------------------------------
418
/**
419
 * \ingroup can_interface
420
 *
421
 * \~german
422
 * \brief   Überprüft ob der CAN Controller im Bus-Off-Status
423
 *
424
 * \return  true wenn der Bus-Off-Status aktiv ist, false ansonsten
425
 *
426
 * \warning aktuell nur auf dem SJA1000
427
 */
428
extern bool can_check_bus_off(void);
429
430
// ----------------------------------------------------------------------------
431
/**
432
 * \ingroup  can_interface
433
 *
434
 * \~german
435
 * \brief  Setzt einen Bus-Off Status zurück und schaltet den CAN Controller
436
 *      wieder aktiv
437
 *
438
 * \warning  aktuell nur auf dem SJA1000
439
 */
440
extern void can_reset_bus_off(void);
441
442
// ----------------------------------------------------------------------------
443
/**
444
 * \ingroup  can_interface
445
 * \brief  Setzt den Operations-Modus
446
 *
447
 * \param  mode  Gewünschter Modus des CAN Controllers
448
 */
449
extern void can_set_mode(can_mode_t mode);
450
451
#if defined (__cplusplus)
452
}
453
#endif
454
455
#endif // CAN_H