aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms/LPC17xx/can_lld.h
blob: b265c941260ee925c941e0db5cf68760c152bdf1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
/*
    ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

/**
 * @file    LPC17xx/can_lld.h
 * @brief   LPC17xx CAN subsystem low level driver header.
 *
 * @addtogroup CAN
 * @{
 */

/*
  This file has been contributed by:
                Marcin Jokel.
*/

#ifndef _CAN_LLD_H_
#define _CAN_LLD_H_

#if HAL_USE_CAN || defined(__DOXYGEN__)
/* TODO: FullCAN mode. */
/*===========================================================================*/
/* Driver constants.                                                         */
/*===========================================================================*/

/*
 *  CAN Mode register bits.
 */
#define CANMOD_RM                   (1UL << 0)
#define CANMOD_LOM                  (1UL << 1)
#define CANMOD_STM                  (1UL << 2)
#define CANMOD_TPM                  (1UL << 3)
#define CANMOD_SM                   (1UL << 4)
#define CANMOD_RPM                  (1UL << 5)
#define CANMOD_TM                   (1UL << 7)

/*
 *  CAN Command register bits.
 */
#define CANCMR_TR                   (1UL << 0)
#define CANCMR_AT                   (1UL << 1)
#define CANCMR_RRB                  (1UL << 2)
#define CANCMR_CDO                  (1UL << 3)
#define CANCMR_SRR                  (1UL << 4)
#define CANCMR_STB1                 (1UL << 5)
#define CANCMR_STB2                 (1UL << 6)
#define CANCMR_STB3                 (1UL << 7)

/*
 *  CAN Global Status register bits.
 */
#define CANGSR_RBS                  (1UL << 0)
#define CANGSR_DOS                  (1UL << 1)
#define CANGSR_TBS                  (1UL << 2)
#define CANGSR_TCS                  (1UL << 3)
#define CANGSR_RS                   (1UL << 4)
#define CANGSR_TS                   (1UL << 5)
#define CANGSR_ES                   (1UL << 6)
#define CANGSR_BS                   (1UL << 7)
#define CANGSR_RXERR                0x00FF0000
#define CANGSR_TXERR                0xFF000000

/*
 *  CAN Interrupt and Capture register bits.
 */
#define CANICR_RI                   (1UL << 0)
#define CANICR_TI1                  (1UL << 1)
#define CANICR_EI                   (1UL << 2)
#define CANICR_DOI                  (1UL << 3)
#define CANICR_WUI                  (1UL << 4)
#define CANICR_EPI                  (1UL << 5)
#define CANICR_ALI                  (1UL << 6)
#define CANICR_BEI                  (1UL << 7)
#define CANICR_IDI                  (1UL << 8)
#define CANICR_TI2                  (1UL << 9)
#define CANICR_TI3                  (1UL << 10)
#define CANICR_ERRBIT               0x001F0000
#define CANICR_ERRBIT_SOF           0x00030000
#define CANICR_ERRBIT_ID28_ID21     0x00020000
#define CANICR_ERRBIT_ID20_ID18     0x00060000
#define CANICR_ERRBIT_SRTR          0x00040000
#define CANICR_ERRBIT_IDE           0x00050000
#define CANICR_ERRBIT_ID17_ID13     0x00070000
#define CANICR_ERRBIT_ID12_ID5      0x000F0000
#define CANICR_ERRBIT_ID4_ID0       0x000E0000
#define CANICR_ERRBIT_RTR           0x000C0000
#define CANICR_ERRBIT_RES_BIT1      0x000D0000
#define CANICR_ERRBIT_RES_BIT0      0x00090000
#define CANICR_ERRBIT_DATA_LEN_CODE 0x000B0000
#define CANICR_ERRBIT_DATA_FIELD    0x000A0000
#define CANICR_ERRBIT_CRC_SEQ       0x00080000
#define CANICR_ERRBIT_CRC_DEL       0x00180000
#define CANICR_ERRBIT_ACK_SLOT      0x00190000
#define CANICR_ERRBIT_ACK_DEL       0x001B0000
#define CANICR_ERRBIT_EOF           0x001A0000
#define CANICR_ERRBIT_INTERMISSION  0x00120000
#define CANICR_ERRBIT_ACTIVE_ERROR  0x00110000
#define CANICR_ERRBIT_PASSIVE_ERROR 0x00160000
#define CANICR_ERRBIT_TOL_DOM_BITS  0x00130000
#define CANICR_ERRBIT_ERROR_DEL     0x00170000
#define CANICR_ERRBIT_OVERLOAD      0x001C0000
#define CANICR_ERRDIR               (1UL << 21)
#define CANICR_ERRC                 (3UL << 22)
#define CANICR_ERRC_BIT_ERR         (0UL << 22)
#define CANICR_ERRC_FORM_ERR        (1UL << 22)
#define CANICR_ERRC_STUFF_ERR       (2UL << 22)
#define CANICR_ERRC_OTHER_ERR       (3UL << 22)
#define CANICR_ALCBIT               0xFF000000

/*
 *  CAN Interrupt Enable register bits.
 */
#define CANIER_RIE                  (1UL << 0)
#define CANIER_TIE1                 (1UL << 1)
#define CANIER_EIE                  (1UL << 2)
#define CANIER_DOIE                 (1UL << 3)
#define CANIER_WUIE                 (1UL << 4)
#define CANIER_EPIE                 (1UL << 5)
#define CANIER_ALIE                 (1UL << 6)
#define CANIER_BEIE                 (1UL << 7)
#define CANIER_IDIE                 (1UL << 8)
#define CANIER_TIE2                 (1UL << 9)
#define CANIER_TIE3                 (1UL << 10)

/*
 *   CAN Bus Timing register bits.
 */
#define CANBTR_BRP(t)               ((t) << 0)
#define CANBTR_SJW(t)               ((t) << 14)
#define CANBTR_TESG1(t)             ((t) << 16)
#define CANBTR_TESG2(t)             ((t) << 20)
#define CANBTR_SAM                  (1UL << 23)

/*
 *    CAN Status register bits.
 */
#define CANSR_RBS                   (1UL << 0)
#define CANSR_DOS                   (1UL << 1)
#define CANSR_TBS1                  (1UL << 2)
#define CANSR_TCS1                  (1UL << 3)
#define CANSR_RS                    (1UL << 4)
#define CANSR_TS1                   (1UL << 5)
#define CANSR_ES                    (1UL << 6)
#define CANSR_BS                    (1UL << 7)
#define CANSR_TBS2                  (1UL << 10)
#define CANSR_TCS2                  (1UL << 11)
#define CANSR_TS2                   (1UL << 13)
#define CANSR_TBS3                  (1UL << 18)
#define CANSR_TCS3                  (1UL << 19)
#define CANSR_TS3                   (1UL << 21)

/*
 *    CAN Receive Frame Status register bits.
 */
#define CANRFS_ID                   0x000001FF
#define CANRFS_BP                   (1UL << 10)
#define CANRFS_DLC                  0x000F0000
#define CANRFS_RTR                  (1UL << 30)
#define CANRFS_FF                   (1UL << 31)

/*
 *    CAN Transmit Frame Information register bits.
 */
#define CANTFI_PRIO(p)              ((p) << 0)
#define CANTFI_DLC(l)               ((l) << 16)
#define CANTFI_RTR                  (1UL << 30)
#define CANTFI_FF                   (1UL << 31)

/*
 *    CAN Sleep Clear register bits.
 */
#define CANSLEEPCLR_CAN1SLEEP       (1UL << 1)
#define CANSLEEPCLR_CAN2SLEEP       (1UL << 2)

/*
 *    CAN Wake-up Flags register bits.
 */
#define CANWAKEFLAGS_CAN1WAKE       (1UL << 1)
#define CANWAKEFLAGS_CAN2WAKE       (1UL << 2)

/*
 *    Central Transmit Status register bits.
 */
#define CANTSR_TS1                  (1UL << 0)
#define CANTSR_TS2                  (1UL << 1)
#define CANTSR_TBS1                 (1UL << 8)
#define CANTSR_TBS2                 (1UL << 9)
#define CANTSR_TCS1                 (1UL << 16)
#define CANTSR_TCS2                 (1UL << 17)

/*
 *     Central Receive Status register bits.
 */
#define CANRSR_RS1                  (1UL << 0)
#define CANRSR_RS2                  (1UL << 1)
#define CANRSR_RB1                  (1UL << 8)
#define CANRSR_RB2                  (1UL << 9)
#define CANRSR_DOS1                 (1UL << 16)
#define CANRSR_DOS2                 (1UL << 17)

/*
 *     Central Miscellaneous Status register bits.
 */
#define CANMSR_E1                   (1UL << 0)
#define CANMSR_E2                   (1UL << 1)
#define CANMSR_BS1                  (1UL << 8)
#define CANMSR_BS2                  (1UL << 9)

/*
 *     Acceptance Filter Mode register bits.
 */
#define AFMR_ACC_OFF                (1UL << 0)
#define AFMR_ACC_BP                 (1UL << 1)
#define AFMR_E_FCAN                 (1UL << 2)

/**
 * @brief   This switch defines whether the driver implementation supports
 *          a low power switch mode with automatic an wakeup feature.
 */
#define CAN_SUPPORTS_SLEEP          TRUE

/**
 * @brief   This implementation supports three transmit mailboxes.
 */
#define CAN_TX_MAILBOXES            3

/**
 * @brief   This implementation supports two receive mailboxes.
 */
#define CAN_RX_MAILBOXES            1

/** @} */

/**
 * @name    CAN registers helper macros
 * @{
 */
#define CAN_IDE_STD                 0           /**< @brief Standard id.    */
#define CAN_IDE_EXT                 1           /**< @brief Extended id.    */

#define CAN_RTR_DATA                0           /**< @brief Data frame.     */
#define CAN_RTR_REMOTE              1           /**< @brief Remote frame.   */

#undef CAN_LIMIT_WARNING
#undef CAN_LIMIT_ERROR
#undef CAN_BUS_OFF_ERROR
#undef CAN_FRAMING_ERROR

#define CAN_WARNING_ERROR           1
#define CAN_PASSIVE_ERROR           2
#define CAN_BUS_ERROR               4

/**
 * @brief   CAN filter fullCAN (standard identifier) type entry.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
#define CANFilterFCEntry(ctrl_i1, dis_i1, id_i1, ctrl_i2, dis_i2, id_i2)                       \
  ((((uint32_t)ctrl_i1) << 29) | (((uint32_t)dis_i1) << 28) | (((uint32_t)id_i1) << 16)   |     \
   (((uint32_t)ctrl_i2) << 13)  | (((uint32_t)dis_i2) << 12)  | ((uint32_t)(id_i2)))

/**
 * @brief   CAN filter standard identifier type entry.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
#define CANFilterStdEntry(ctrl_i1, dis_i1, id_i1, ctrl_i2, dis_i2, id_i2)                       \
  ((((uint32_t)ctrl_i1) << 29) | (((uint32_t)dis_i1) << 28) | (((uint32_t)id_i1) << 16)   |     \
   (((uint32_t)ctrl_i2) << 13)  | (((uint32_t)dis_i2) << 12)  | ((uint32_t)(id_i2)))
/**
 * @brief   CAN filter extended identifier range type entry.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
#define CANFilterStdRangeEntry(ctrl_low, dis_low, id_low, ctrl_high, dis_high, id_high)         \
  ((((uint32_t)ctrl_low) << 29) | (((uint32_t)dis_low) << 28) | (((uint32_t)id_low) << 16)   |  \
   (((uint32_t)ctrl_up) << 13)  | (((uint32_t)dis_up) << 12)  | ((uint32_t)(id_up)))

/**
 * @brief   CAN filter extended identifier type entry.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
#define CANFilterExtEntry(ctrl, id) \
  ((((uint32_t)ctrl) << 29) | ((uint32_t)(id)))

/**
 * @brief   CAN filter extended range identifier type entry.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
#define CANFilterExtRangeEntry(ctrl, id) \
  ((((uint32_t)ctrl) << 29) | ((uint32_t)(id)))
/** @} */

/*===========================================================================*/
/* Driver pre-compile time settings.                                         */
/*===========================================================================*/

/**
 * @name    Configuration options
 * @{
 */
/**
 * @brief   CAN1 driver enable switch.
 * @details If set to @p TRUE the support for CAN1 is included.
 */
#if !defined(LPC17xx_CAN_USE_CAN1) || defined(__DOXYGEN__)
#define LPC17xx_CAN_USE_CAN1                  FALSE
#endif

/**
 * @brief   CAN2 driver enable switch.
 * @details If set to @p TRUE the support for CAN2 is included.
 */
#if !defined(LPC17xx_CAN_USE_CAN2) || defined(__DOXYGEN__)
#define LPC17xx_CAN_USE_CAN2                  FALSE
#endif

/**
 * @brief   CAN1 and CAN2 interrupt priority level setting.
 */
#if !defined(LPC17xx_CAN_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define LPC17xx_CAN_IRQ_PRIORITY              11
#endif
/** @} */

/**
 * @brief   CAN1 and CAN2 local self test enable.
 */
#if !defined(LPC17xx_CAN_USE_LOCAL_SELF_TEST) || defined(__DOXYGEN__)
#define LPC17xx_CAN_USE_LOCAL_SELF_TEST       FALSE
#endif
/** @} */

/**
 * @brief   CAN1 and CAN2 acceptance filter enable.
 */
#if !defined(LPC17xx_CAN_USE_FILTER) || defined(__DOXYGEN__)
#define LPC17xx_CAN_USE_FILTER              FALSE
#endif
/** @} */

/** @} */

/*===========================================================================*/
/* Derived constants and error checks.                                       */
/*===========================================================================*/

#if LPC17xx_CAN_USE_CAN1 && !LPC17xx_HAS_CAN1
#error "CAN1 not present in the selected device"
#endif

#if LPC17xx_CAN_USE_CAN2 && !LPC17xx_HAS_CAN2
#error "CAN2 not present in the selected device"
#endif

#if !LPC17xx_CAN_USE_CAN1 && !LPC17xx_CAN_USE_CAN2
#error "CAN driver activated but no CAN peripheral assigned"
#endif

#if !LPC17xx_CAN_USE_CAN1 && LPC17xx_CAN_USE_CAN2
#error "CAN2 requires CAN1, it cannot operate independently"
#endif

#if CAN_USE_SLEEP_MODE && !CAN_SUPPORTS_SLEEP
#error "CAN sleep mode not supported in this architecture"
#endif

/*===========================================================================*/
/* Driver data structures and types.                                         */
/*===========================================================================*/

/**
 * @brief   Type of a transmission mailbox index.
 */
typedef uint32_t canmbx_t;

/**
 * @brief   CAN transmission frame.
 * @note    Accessing the frame data as word16 or word32 is not portable because
 *          machine data endianness, it can be still useful for a quick filling.
 */
typedef struct {
  struct {
    uint8_t                 DLC:4;          /**< @brief Data length.        */
    uint8_t                 RTR:1;          /**< @brief Frame type.         */
    uint8_t                 IDE:1;          /**< @brief Identifier type.    */
  };
  union {
    struct {
      uint32_t              SID:11;         /**< @brief Standard identifier.*/
    };
    struct {
      uint32_t              EID:29;         /**< @brief Extended identifier.*/
    };
  };
  union {
    uint8_t                 data8[8];       /**< @brief Frame data.         */
    uint16_t                data16[4];      /**< @brief Frame data.         */
    uint32_t                data32[2];      /**< @brief Frame data.         */
  };
} CANTxFrame;

/**
 * @brief   CAN received frame.
 * @note    Accessing the frame data as word16 or word32 is not portable because
 *          machine data endianness, it can be still useful for a quick filling.
 */
typedef struct {
  struct {
    uint16_t                IDF:10;          /**< @brief Filter id.          */
  };
  struct {
    uint8_t                 DLC:4;          /**< @brief Data length.        */
    uint8_t                 RTR:1;          /**< @brief Frame type.         */
    uint8_t                 IDE:1;          /**< @brief Identifier type.    */
  };
  union {
    struct {
      uint32_t              SID:11;         /**< @brief Standard identifier.*/
    };
    struct {
      uint32_t              EID:29;         /**< @brief Extended identifier.*/
    };
  };
  union {
    uint8_t                 data8[8];       /**< @brief Frame data.         */
    uint16_t                data16[4];      /**< @brief Frame data.         */
    uint32_t                data32[2];      /**< @brief Frame data.         */
  };
} CANRxFrame;

/**
 * @brief   CAN filter standard identifier type.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
typedef const uint32_t CANFilterStd;

/**
 * @brief   CAN filter standard identifier range type.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
typedef const uint32_t CANFilterStdRange;

/**
 * @brief   CAN filter extended identifier range type.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
typedef  const uint32_t CANFilterExt;

/**
 * @brief   CAN filter extended range identifier type.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
typedef  const uint32_t CANFilterExtRange;

/**
 * @brief   CAN filter configuration structure.
 * @note    Refer to the LPC17xx reference manual for info about filters.
 */
typedef struct {
  /**
   * @brief   Acceptance filter mode register.
   */
  uint32_t                  afmr;
  /**
   * @brief   FullCAN (standard identifier) table.
   */
  CANFilterStd              *fc_id_table;
  /**
     * @brief  Number of positions in fullCAN (standard identifier) table.
     */
  uint32_t                  fc_id_table_n;
  /**
   * @brief   Standard identifier table.
   */
  CANFilterStd              *std_id_table;
  /**
     * @brief  Number of positions in standard identifier table.
     */
  uint32_t                  std_id_table_n;
  /**
   * @brief   Standard range identifier table.
   */
  CANFilterStdRange         *std_range_id_table;
  /**
   * @brief   Number of positions in standard range identifier table.
   */
  uint32_t                  std_range_id_table_n;
  /**
   * @brief   Extended identifier table.
   */
  CANFilterExt              *ext_id_table;
  /**
   * @brief   Number of positions in extended identifier table.
   */
  uint32_t                  ext_id_table_n;
  /**
   * @brief   Extended range identifier table.
   */
  CANFilterExtRange         *ext_range_id_table;
  /**
   * @brief   Number of positions in extended range identifier table.
   */
  uint32_t                  ext_range_id_table_n;
} CANFilterConfig;

/**
 * @brief   Driver configuration structure.
 */
typedef struct {
  /**
   * @brief   CAN MOD register initialization data.
   * @note    Some bits in this register are enforced by the driver regardless
   *          their status in this field.
   */
  uint32_t                  mod;
  /**
   * @brief   CAN BTR register initialization data.
   * @note    Some bits in this register are enforced by the driver regardless
   *          their status in this field.
   */
  uint32_t                  btr;
} CANConfig;

/**
 * @brief   Structure representing an CAN driver.
 */
typedef struct {
  /**
   * @brief   Driver state.
   */
  canstate_t                state;
  /**
   * @brief   Current configuration data.
   */
  const CANConfig           *config;
  /**
   * @brief   Transmission queue semaphore.
   */
  Semaphore                 txsem;
  /**
   * @brief   Receive queue semaphore.
   */
  Semaphore                 rxsem;
  /**
   * @brief   One or more frames become available.
   * @note    After broadcasting this event it will not be broadcasted again
   *          until the received frames queue has been completely emptied. It
   *          is <b>not</b> broadcasted for each received frame. It is
   *          responsibility of the application to empty the queue by
   *          repeatedly invoking @p chReceive() when listening to this event.
   *          This behavior minimizes the interrupt served by the system
   *          because CAN traffic.
   * @note    The flags associated to the listeners will indicate which
   *          receive mailboxes become non-empty.
   */
  EventSource               rxfull_event;
  /**
   * @brief   One or more transmission mailbox become available.
   * @note    The flags associated to the listeners will indicate which
   *          transmit mailboxes become empty.
   *
   */
  EventSource               txempty_event;
  /**
   * @brief   A CAN bus error happened.
   * @note    The flags associated to the listeners will indicate the
   *          error(s) that have occurred.
   */
  EventSource               error_event;
#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
  /**
   * @brief   Entering sleep state event.
   */
  EventSource               sleep_event;
  /**
   * @brief   Exiting sleep state event.
   */
  EventSource               wakeup_event;
#endif /* CAN_USE_SLEEP_MODE */
  /* End of the mandatory fields.*/
  /**
   * @brief   Pointer to the CAN registers.
   */
  LPC_CAN_TypeDef               *can;
} CANDriver;

/*===========================================================================*/
/* Driver macros.                                                            */
/*===========================================================================*/

/*===========================================================================*/
/* External declarations.                                                    */
/*===========================================================================*/

#if LPC17xx_CAN_USE_CAN1 && !defined(__DOXYGEN__)
extern CANDriver CAND1;
#endif

#if LPC17xx_CAN_USE_CAN2 && !defined(__DOXYGEN__)
extern CANDriver CAND2;
#endif

#ifdef __cplusplus
extern "C" {
#endif
  void can_lld_init(void);
  void can_lld_start(CANDriver *canp);
  void can_lld_stop(CANDriver *canp);
  bool_t can_lld_is_tx_empty(CANDriver *canp,
                             canmbx_t mailbox);
  void can_lld_transmit(CANDriver *canp,
                        canmbx_t mailbox,
                        const CANTxFrame *crfp);
  bool_t can_lld_is_rx_nonempty(CANDriver *canp,
                                canmbx_t mailbox);
  void can_lld_receive(CANDriver *canp,
                       canmbx_t mailbox,
                       CANRxFrame *ctfp);
#if CAN_USE_SLEEP_MODE
  void can_lld_sleep(CANDriver *canp);
  void can_lld_wakeup(CANDriver *canp);
#endif /* CAN_USE_SLEEP_MODE */
#if LPC17xx_CAN_USE_FILTER
  void canSetFilter(const CANFilterConfig *cfc);
#endif  /* LPC17xx_CAN_USE_FILTER */
#ifdef __cplusplus
}
#endif

#endif /* HAL_USE_CAN */

#endif /* _CAN_LLD_H_ */

/** @} */