]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/can/arm/lpc2xxx/v2_0/src/can_lpc2xxx.c
Merge branch 'master' of git+ssh://git.kernelconcepts.de/karo-tx-redboot
[karo-tx-redboot.git] / packages / devs / can / arm / lpc2xxx / v2_0 / src / can_lpc2xxx.c
1 //==========================================================================
2 //
3 //      devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c
4 //
5 //      CAN driver for LPC2xxx microcontrollers
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2003 Gary Thomas
13 //
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
17 //
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 //
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
33 //
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 //
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):    Uwe Kindler
45 // Contributors: Uwe Kindler
46 // Date:         2007-04-09
47 // Purpose:      Support LPC2xxx on-chip CAN moduls
48 // Description: 
49 //
50 //####DESCRIPTIONEND####
51 //
52 //==========================================================================
53
54
55 //==========================================================================
56 //                              INCLUDES
57 //==========================================================================
58 #include <pkgconf/system.h>
59 #include <pkgconf/io_can.h>
60 #include <pkgconf/io.h>
61 #include <pkgconf/devs_can_lpc2xxx.h>
62
63 #include <cyg/infra/diag.h>
64
65 #include <cyg/hal/hal_arch.h>
66 #include <cyg/hal/hal_intr.h>
67 #include <cyg/hal/hal_io.h>
68
69 #include <cyg/hal/hal_diag.h>
70 #include <cyg/infra/cyg_ass.h>
71
72 #include <cyg/io/io.h>
73 #include <cyg/io/devtab.h>
74 #include <cyg/io/can.h>
75 #include <cyg/io/can_lpc2xxx.h>
76 #include <cyg/io/can_lpc2xxx_baudrates.h>
77
78
79
80
81 //===========================================================================
82 //                                DEFINES  
83 //===========================================================================
84 //
85 // Check if the macro HAL_LPC2XXX_GET_CAN_BR is provided
86 //
87 #ifndef HAL_LPC2XXX_GET_CAN_BR
88 #error "Macro HAL_LPC2XXX_GET_CAN_BR() missing"
89 #endif
90
91 //
92 // Support debug output if this option is enabled in CDL file
93 //
94 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
95 #define LPC2XXX_DBG_PRINT diag_printf
96 #else
97 #define LPC2XXX_DBG_PRINT( fmt, ... )
98 #endif
99
100
101 //---------------------------------------------------------------------------
102 // we define our own set of register bits in order to be independent from
103 // platform specific names
104 //
105
106 //---------------------------------------------------------------------------
107 // Memory map of CAN block
108 //
109 #define CAN_ACCFILT_RAM_BASE  0xE0038000
110 #define CAN_ACCFILT_REG_BASE  0xE003C000
111 #define CAN_CENTRAL_REG_BASE  0xE0040000
112 #define CAN_CTRL_1_REG_BASE   0xE0044000
113 #define CAN_CTRL_2_REG_BASE   0xE0048000
114 #define CAN_CTRL_3_REG_BASE   0xE004C000
115 #define CAN_CTRL_4_REG_BASE   0xE0050000
116
117
118 //---------------------------------------------------------------------------
119 // CAN Acceptance Filter register layout
120 //
121 #define CAN_ACCFILT_AFMR            (CAN_ACCFILT_REG_BASE  + 0x0000)
122 #define CAN_ACCFILT_SFF_SA          (CAN_ACCFILT_REG_BASE  + 0x0004)
123 #define CAN_ACCFILT_SFF_GRP_SA      (CAN_ACCFILT_REG_BASE  + 0x0008)
124 #define CAN_ACCFILT_EFF_SA          (CAN_ACCFILT_REG_BASE  + 0x000C)
125 #define CAN_ACCFILT_EFF_GRP_SA      (CAN_ACCFILT_REG_BASE  + 0x0010)
126 #define CAN_ACCFILT_ENDOFTABLE      (CAN_ACCFILT_REG_BASE  + 0x0014)
127 #define CAN_ACCFILT_LUT_ERR_ADDR    (CAN_ACCFILT_REG_BASE  + 0x0018)
128 #define CAN_ACCFILT_LUT_ERR         (CAN_ACCFILT_REG_BASE  + 0x001C)
129
130 //---------------------------------------------------------------------------
131 // CAN_ACCFILT_AFMR Bits
132 //
133 #define AFMR_OFF       0x00000001 // 1 = Acceptance filter is not operational
134 #define AFMR_BYPASS    0x00000002 // 1 = all Rx messages are accepted on enabled CAN controllers.
135 #define AFMR_FULLCAN   0x00000004 // 1 = FullCAN mode
136 #define AFMR_ON        0x00000000 // Acceptance filter on
137 #define ACCFILT_RAM_SIZE 2048     // size of acceptance filter ram
138
139
140 //---------------------------------------------------------------------------
141 // Acceptance filter tool macros
142 //
143 #define ACCFILT_STD_ID_MASK                    0x7FF
144 #define ACCFILT_EXT_ID_MASK                    0x1FFFFFFF
145 #define ACCFILT_STD_DIS                        0x1000
146 #define ACCFILT_STD_CTRL_MASK                  0xE000
147 #define ACCFILT_EXT_CTRL_MASK                  0xE0000000
148 #define ACCFILT_STD_GET_CTRL(_entry_)          (((_entry_) >> 13) & 0x7)
149 #define ACCFILT_STD_GET_CTRL_LOWER(_entry_)    (((_entry_) >> 29) & 0x7)
150 #define ACCFILT_STD_GET_CTRL_UPPER(_entry_)    (((_entry_) >> 13) & 0x7)
151 #define ACCFILT_STD_GET_ID(_entry_)            ((_entry_) & ACCFILT_STD_ID_MASK)
152 #define ACCFILT_EXT_GET_ID(_entry_)            ((_entry_) & ACCFILT_EXT_ID_MASK)
153 #define ACCFILT_EXT_GET_CTRL(_entry_)          (((_entry_) >> 29) & 0x7)
154 #define ACCFILT_EXT_SET_CTRL(_entry_, _ctrl_)  ((_entry_ & 0xE0000000) | ((_ctrl_) << 29)) 
155
156
157 //---------------------------------------------------------------------------
158 // CAN Central CAN Registers register layout
159 //
160 #define CAN_CENTRAL_TXSR            (CAN_CENTRAL_REG_BASE  + 0x0000)
161 #define CAN_CENTRAL_RXSR            (CAN_CENTRAL_REG_BASE  + 0x0004)
162 #define CAN_CENTRAL_MSR             (CAN_CENTRAL_REG_BASE  + 0x0008)
163
164
165 //---------------------------------------------------------------------------
166 // CAN Controller register offsets
167 // Registers are offsets from base CAN module control register
168 //
169 #define CANREG_MOD   0x0000
170 #define CANREG_CMR   0x0004
171 #define CANREG_GSR   0x0008
172 #define CANREG_ICR   0x000C
173 #define CANREG_IER   0x0010
174 #define CANREG_BTR   0x0014
175 #define CANREG_EWL   0x0018
176 #define CANREG_SR    0x001C
177 #define CANREG_RFS   0x0020
178 #define CANREG_RID   0x0024
179 #define CANREG_RDA   0x0028
180 #define CANREG_RDB   0x002C
181 #define CANREG_TFI1  0x0030
182 #define CANREG_TID1  0x0034
183 #define CANREG_TDA1  0x0038
184 #define CANREG_TDB1  0x003C
185 #define CANREG_TFI2  0x0040
186 #define CANREG_TID2  0x0044
187 #define CANREG_TDA2  0x0048
188 #define CANREG_TDB2  0x004C
189 #define CANREG_TFI3  0x0050
190 #define CANREG_TID3  0x0054
191 #define CANREG_TDA3  0x0058
192 #define CANREG_TDB3  0x005C
193
194
195 //---------------------------------------------------------------------------
196 // CAN Controller register layout
197 //
198 #define CAN_CTRL_MOD(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_MOD)
199 #define CAN_CTRL_CMR(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_CMR)
200 #define CAN_CTRL_GSR(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_GSR)
201 #define CAN_CTRL_ICR(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_ICR)
202 #define CAN_CTRL_IER(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_IER)
203 #define CAN_CTRL_BTR(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_BTR)
204 #define CAN_CTRL_EWL(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_EWL)
205 #define CAN_CTRL_SR(_extra_)    (CAN_CTRL_BASE(_extra_) + CANREG_SR)
206 #define CAN_CTRL_RFS(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_RFS)
207 #define CAN_CTRL_RID(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_RID)
208 #define CAN_CTRL_RDA(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_RDA)
209 #define CAN_CTRL_RDB(_extra_)   (CAN_CTRL_BASE(_extra_) + CANREG_RDB)
210 #define CAN_CTRL_TFI1(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TFI1)
211 #define CAN_CTRL_TID1(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TID1)
212 #define CAN_CTRL_TDA1(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TDA1)
213 #define CAN_CTRL_TDB1(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TDB1)
214 #define CAN_CTRL_TFI2(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TFI2)
215 #define CAN_CTRL_TID2(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TID2)
216 #define CAN_CTRL_TDA2(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TDA2)
217 #define CAN_CTRL_TDB2(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TDB2)
218 #define CAN_CTRL_TFI3(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TFI3)
219 #define CAN_CTRL_TID3(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TID3)
220 #define CAN_CTRL_TDA3(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TDA3)
221 #define CAN_CTRL_TDB3(_extra_)  (CAN_CTRL_BASE(_extra_) + CANREG_TDB3)
222
223
224 //---------------------------------------------------------------------------
225 // CAN_CTRL_ICR register bits
226 //
227 #define ICR_RX                  0x00000001
228 #define ICR_TX1                 0x00000002
229 #define ICR_ERR_WARN            0x00000004
230 #define ICR_DATA_OVR            0x00000008
231 #define ICR_WAKE_UP             0x00000010
232 #define ICR_ERR_PASSIVE         0x00000020
233 #define ICR_ARBITR_LOST         0x00000040
234 #define ICR_BUS_ERR             0x00000080
235 #define ICR_ID_READY            0x00000100
236 #define ICR_TX2                 0x00000200
237 #define ICR_TX3                 0x00000400
238 #define ICR_LUT_ERR             0x00000800
239 #define ICR_GET_ERRBIT(_icr_)   (((_icr_) >> 16) & 0x1F)
240 #define ICR_ERR_DIRECTION       0x00200000
241 #define ICR_GET_ERRCODE(_icr_)  (((_icr_) >> 22) & 0x03)
242 #define ICR_GET_ALCBIT(_icr_)   (((_icr_) >> 24) & 0x1F)
243
244 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_ALIE
245 #define CAN_ALL_ERR_INT (ICR_ERR_PASSIVE | ICR_ARBITR_LOST | ICR_BUS_ERR | ICR_ERR_WARN)
246 #else
247 #define CAN_ALL_ERR_INT (ICR_ERR_PASSIVE | ICR_BUS_ERR | ICR_ERR_WARN)
248 #endif
249 #define CAN_MISC_INT    (CAN_ALL_ERR_INT | ICR_WAKE_UP)
250
251
252 //---------------------------------------------------------------------------
253 // CAN_CTRL_ICR register bits
254 //
255 #define ICR_ERRCODE_BIT_ERR   0x00
256 #define ICR_ERRCODE_FORM_ERR  0x01
257 #define ICR_ERRCODE_STUFF_ERR 0x02
258 #define ICR_ERRCODE_OTHER_ERR 0x03
259
260
261 //---------------------------------------------------------------------------
262 // CAN_CTRL_RFS register bits
263 //
264 #define RFS_ACCFILT_INDEX_MASK       0x000003FF
265 #define RFS_RECEIVED_IN_BYPASS_MODE  0x00000400
266 #define RFS_DLC_MASK                 0x000F0000
267 #define RFS_RTR                      0x40000000
268 #define RFS_EXT                      0x80000000
269 #define RFS_GET_DLC(_regval_)        (((_regval_) >> 16) & 0xF)
270
271 //---------------------------------------------------------------------------
272 // CAN_CTRL_CMR register bits
273 //
274 #define CMR_TX_REQ          0x00000001
275 #define CMR_TX_ABORT        0x00000002
276 #define CMR_RX_RELEASE_BUF  0x00000004
277 #define CMR_CLEAR_DATA_OVR  0x00000008
278 #define CMR_SELF_RX_REQ     0x00000010
279 #define CMR_SEND_TX_BUF1    0x00000020
280 #define CMR_SEND_TX_BUF2    0x00000040
281 #define CMR_SEND_TX_BUF3    0x00000080
282
283
284 //---------------------------------------------------------------------------
285 // CAN_CTRL_TFI register bits
286 //
287 #define TFI_PRIO_MASK 0x000000FF
288 #define TFI_DLC_MASK  0x000F0000
289 #define TFI_DLC_RTR   0x40000000
290 #define TFI_DLC_EXT   0x80000000
291
292
293 //---------------------------------------------------------------------------
294 // CAN_CTRL_MOD register bits
295 //
296 #define CANMOD_OPERATIONAL    0x00000000
297 #define CANMOD_RESET          0x00000001
298 #define CANMOD_LISTEN_ONLY    0x00000002
299 #define CANMOD_SELF_TEST      0x00000004
300 #define CANMOD_TX_BUF_CFG     0x00000008
301 #define CANMOD_SLEEP          0x00000010
302 #define CANMOD_REV_POLARITY   0x00000020
303 #define CANMOD_TEST           0x00000040
304
305
306 //---------------------------------------------------------------------------
307 // CAN_CTRL_IER register bits
308 //
309 #define IER_RX                0x00000001
310 #define IER_TX1               0x00000002
311 #define IER_ERR_WARN          0x00000004
312 #define IER_DATA_OVR          0x00000008
313 #define IER_WAKE_UP           0x00000010
314 #define IER_ERR_PASSIVE       0x00000020
315 #define IER_ARBITR_LOST       0x00000040
316 #define IER_BUS_ERR           0x00000080
317 #define IER_ID_READY          0x00000100
318 #define IER_TX2               0x00000200
319 #define IER_TX3               0x00000400
320
321
322 //---------------------------------------------------------------------------
323 // CAN_CTRL_GSR register bits
324 //
325 #define GSR_RX_MSG_AVAILABLE  0x00000001
326 #define GSR_DATA_OVR          0x00000002
327 #define GSR_TX_NOT_PENDING    0x00000004
328 #define GSR_ALL_TX_COMPLETE   0x00000008
329 #define GSR_RECEIVING_ACTIVE  0x00000010
330 #define GSR_SENDING_ACTIVE    0x00000020
331 #define GSR_ERR               0x00000040
332 #define GSR_BUS_OFF           0x00000080
333 #define GSR_RXERR_CNT(_reg_)  (((_reg_) >> 16) & 0xFF)
334 #define GSR_TXERR_CNT(_reg_)  (((_reg_) >> 24) & 0xFF)
335
336
337 //---------------------------------------------------------------------------
338 // CAN_CTRL_SR register bits
339 //
340 #define SR_RX_MSG_AVAILABLE  0x01 
341 #define SR_DATA_OVR          0x02
342 #define SR_TX_BUF_WRITE_OK   0x04 // TBS1, TBS2, TBS3 (Bit 2, 10, 18)
343 #define SR_TX_COMPLETE       0x08 // TCS1, TCS2, TCS3 (Bit 3, 11, 19)
344 #define SR_RECEIVING_ACTIVE  0x10
345 #define SR_SENDING_ACTIVE    0x20 // TS1, TS2, TS3 (5, 13, 21)
346 #define SR_ERR               0x40
347 #define SR_BUS_OFF           0x80
348
349
350 //---------------------------------------------------------------------------
351 // Optimize for the case of a single CAN channel, while still allowing
352 // multiple channels.
353 //
354 #if CYGINT_IO_CAN_CHANNELS == 1
355 #define CAN_CTRL_BASE(_extra_)   CAN_CTRL_SINGLETON_BASE
356 #define CAN_ISRVEC(_extra_)      CAN_SINGLETON_ISRVEC
357 #define CAN_CHAN_NO(_extra_)     CAN_SINGLETON_CHAN_NO
358 #define CAN_DECLARE_INFO(_chan_)
359 #define CAN_DECLARE_CHAN(_data_)
360 #else
361 #define CAN_CTRL_BASE(_extra_)   ((_extra_)->base)
362 #define CAN_ISRVEC(_extra_)      ((_extra_)->isrvec)
363 #define CAN_CHAN_NO(_extra_)     ((_extra_)->chan_no)
364 #define CAN_DECLARE_INFO(_chan_) lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
365 #define CAN_DECLARE_CHAN(_data_) can_channel  *chan = (can_channel *)data;
366 #endif // CYGINT_IO_CAN_CHANNELS == 1 
367
368
369 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN0_ACCFILT_STARTUP_CFG_RX_ALL
370 #define CAN0_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
371 #else
372 #define CAN0_FLAG_STARTUP_ACCFILT_SETUP 0x00
373 #endif
374
375 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN1_ACCFILT_STARTUP_CFG_RX_ALL
376 #define CAN1_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
377 #else
378 #define CAN1_FLAG_STARTUP_ACCFILT_SETUP 0x00
379 #endif
380
381 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN2_ACCFILT_STARTUP_CFG_RX_ALL
382 #define CAN2_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
383 #else
384 #define CAN2_FLAG_STARTUP_ACCFILT_SETUP 0x00
385 #endif
386
387 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN3_ACCFILT_STARTUP_CFG_RX_ALL
388 #define CAN3_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
389 #else
390 #define CAN3_FLAG_STARTUP_ACCFILT_SETUP 0x00
391 #endif
392
393
394 //===========================================================================
395 //                              DATA TYPES
396 //===========================================================================
397 //
398 // Structure stores LPC2xxx CAN channel related stuff
399 //
400
401 // If we use Self Reception Request command instead of the Transmission Request
402 // we must add last transmit message id in order to reject it in rx_ISR
403 // There are two last_tx_id because tx interrupt (and so transmission of next 
404 // message) happens before rx interrupt (which uses last_tx_id for rejecting)) 
405
406 // Format of last_tx_id:
407 //  (bits: 28:0-ID, 29-Validation, 30-RTR, 31-EXT)
408 //  if last_tx_id == 0xFFFFFFFF (Validation == 1) then last id is not valid
409 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
410  #define LPC2XXX_CAN_INFO_LAST_TX_ID_IDMASK   0x1FFFFFFF
411  #define LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK   0xC0000000
412  #define LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID  0xFFFFFFFF
413
414  #define LPC2XXX_CAN_INFO_LAST_TX_ID_DECL     cyg_uint8    last_tx_index;                 \
415                                               cyg_uint32   last_tx_id[2];
416  #define LPC2XXX_CAN_INFO_LAST_TX_ID_INIT     last_tx_index : 0,                          \
417                                               last_tx_id    : {LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID, LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID},
418 #else
419  #define LPC2XXX_CAN_INFO_LAST_TX_ID_DECL
420  #define LPC2XXX_CAN_INFO_LAST_TX_ID_INIT
421 #endif
422
423 typedef struct lpc2xxx_can_info_st
424 {
425 //
426 // Newer LPC2xxx variants like the LPC2468 do not support per channel 
427 // interrupts. They provide only one single interrupt vector for all
428 // CAN interrupts
429 //
430 #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
431     cyg_interrupt      tx_interrupt;
432     cyg_handle_t       tx_interrupt_handle;     
433     cyg_uint8          tx_interrupt_priority;     
434     cyg_interrupt      rx_interrupt;
435     cyg_handle_t       rx_interrupt_handle; 
436     cyg_uint8          rx_interrupt_priority;
437 #endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
438     cyg_can_state      state;            // state of CAN controller 
439     cyg_uint8          flags;            // flags indicating several states       
440     LPC2XXX_CAN_INFO_LAST_TX_ID_DECL     // last transmitted messages ids   
441 #if CYGINT_IO_CAN_CHANNELS > 1
442     cyg_uint32         base;             // Per-bus h/w details
443 #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
444     cyg_uint8          isrvec;           // ISR vector (peripheral id)
445 #endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
446     cyg_uint8          chan_no;          // number of CAN channel
447 #endif // CYGINT_IO_CAN_CHANNELS > 1
448 } lpc2xxx_can_info_t;
449
450
451 #define INFO_FLAG_RX_ALL           0x01 // this bit indicates that channel receives all CAN messages - no filtering active
452 #define INFO_FLAG_STARTUP_RX_ALL   0x02 // this bit indicates filter state at startup
453
454
455 //
456 // lpc2xxx info initialisation
457 //
458 #define LPC2XXX_CTRL_NOT_INITIALIZED 0xFF
459
460 #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
461 #if CYGINT_IO_CAN_CHANNELS > 1
462 #define LPC2XXX_CAN_INFO(_l, _base, _isrvec, _chan_no_, _tx_priority, _rx_priority, _flags) \
463 lpc2xxx_can_info_t _l  = {                                                                  \
464     state             :  LPC2XXX_CTRL_NOT_INITIALIZED,                                      \
465     base              : (_base),                                                            \
466     isrvec            : (_isrvec),                                                          \
467     chan_no           : (_chan_no_),                                                        \
468     tx_interrupt_priority : (_tx_priority),                                                 \
469     rx_interrupt_priority : (_rx_priority),                                                 \
470     flags             : (_flags),                                                           \
471     LPC2XXX_CAN_INFO_LAST_TX_ID_INIT                                                        \
472 };
473 #else // CYGINT_IO_CAN_CHANNELS == 1
474 #define LPC2XXX_CAN_INFO(_l, _tx_priority, _rx_priority, _flags) \
475 lpc2xxx_can_info_t _l = {                          \
476     state      : CYGNUM_CAN_STATE_STOPPED,         \
477     tx_interrupt_priority : (_tx_priority),        \
478     rx_interrupt_priority : (_rx_priority),        \
479     flags      : (_flags),                         \
480     LPC2XXX_CAN_INFO_LAST_TX_ID_INIT               \
481 };
482 #endif // CYGINT_IO_CAN_CHANNELS == 1
483 #else // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
484 //
485 // Newer devices support only one global CAN interrupt. We do not need
486 // per channel interrupt data an ignore the values during initialisation
487 //
488 #if CYGINT_IO_CAN_CHANNELS > 1
489 #define LPC2XXX_CAN_INFO(_l, _base, _isrvec, _chan_no_, _tx_priority, _rx_priority, _flags) \
490 lpc2xxx_can_info_t _l  = {                                                       \
491     state             :  LPC2XXX_CTRL_NOT_INITIALIZED,                           \
492     base              : (_base),                                                 \
493     chan_no           : (_chan_no_),                                             \
494     flags             : (_flags),                                                \
495     LPC2XXX_CAN_INFO_LAST_TX_ID_INIT                                             \
496 };
497 #else // CYGINT_IO_CAN_CHANNELS == 1
498 #define LPC2XXX_CAN_INFO(_l, _tx_priority, _rx_priority, _flags) \
499 lpc2xxx_can_info_t _l = {                          \
500     state      : CYGNUM_CAN_STATE_STOPPED,         \
501     flags      : (_flags),                         \
502     LPC2XXX_CAN_INFO_LAST_TX_ID_INIT               \
503 };
504 #endif // CYGINT_IO_CAN_CHANNELS == 1
505
506 //
507 // The following defines are only dummies required for proper 
508 // initialisation of can channel data structures
509 //
510 #define CYGNUM_HAL_INTERRUPT_CAN1_TX
511 #define CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY
512 #define CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY
513 #define CYGNUM_HAL_INTERRUPT_CAN2_TX
514 #define CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY
515 #define CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY
516 #define CYGNUM_HAL_INTERRUPT_CAN3_TX
517 #define CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY
518 #define CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY
519 #define CYGNUM_HAL_INTERRUPT_CAN4_TX
520 #define CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY
521 #define CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY
522 #endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
523
524
525 //
526 // Acceptance filter data
527 //
528 typedef struct lpc2xxx_global_can_info_st
529 {
530     cyg_interrupt       interrupt;          // common CAN interrupt
531     cyg_handle_t        interrupt_handle;   // common CAN interrupt handle 
532     cyg_uint16          free_filters;       // number of free message filter
533 #if CYGINT_IO_CAN_CHANNELS > 1              // optimize for single channel
534     cyg_uint8           init_cnt;           // counts number of initialized channels
535     can_channel*        active_channels[5]; // stores pointers to active channels - the last entry is just a delimiter
536 #else // CYGINT_IO_CAN_CHANNELS > 1
537     can_channel*        active_channels[1]; // optimize for one single channel
538 #endif // CYGINT_IO_CAN_CHANNELS > 1
539 } lpc2xxx_global_can_info_t;
540
541
542 #if CYGINT_IO_CAN_CHANNELS > 1
543 #define LPC2XXX_GET_CAN_CHANNEL(_can_info_, _chan_no_) ((can_channel*)(_can_info_).active_channels[_chan_no_])
544 #else
545 #define LPC2XXX_GET_CAN_CHANNEL(_can_info_, _chan_no_) ((can_channel*)(_can_info_).active_channels[0])
546 #endif
547
548 //
549 // The number of available message filters depends on the size of the
550 // acceptance filter RAM and on the size of one entry. The size of
551 // one entry is 4 byte (standard ID only 2 byte, extended groups 8 byte)
552 //
553 #define ACCFILT_COMMON_ENTRY_SIZE 4
554 #define LPC2XXX_CAN_MSG_FILTERS_MAX (ACCFILT_RAM_SIZE / ACCFILT_COMMON_ENTRY_SIZE)
555 lpc2xxx_global_can_info_t lpc2xxx_global_can_info =
556 {
557     .free_filters     = LPC2XXX_CAN_MSG_FILTERS_MAX,
558 #if CYGINT_IO_CAN_CHANNELS > 1 // optimize for single channel
559     .init_cnt         = 0,
560     .active_channels  = {0, 0, 0, 0, 0},
561 #endif // #if CYGINT_IO_CAN_CHANNELS > 1
562 };
563
564
565
566 //
567 // Data type for access of single bytes/words of an dword value
568 //
569 typedef union lsc_buf_u
570 {
571     cyg_uint8  bytes[4];
572     struct 
573     {
574         cyg_uint16 low;
575         cyg_uint16 high;
576     } words;
577     
578     struct
579     {
580         cyg_uint16 upper; // uppper column of acceptance filter ram
581         cyg_uint16 lower; // lower column of acceptance filter ram
582     } column;
583     
584     cyg_uint32 dword;
585 } lsc_buf_t;
586
587
588 //===========================================================================
589 //                          GLOBAL DATA
590 //===========================================================================
591 #if CYGINT_IO_CAN_CHANNELS > 1
592 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
593 LPC2XXX_CAN_INFO(lpc2xxx_can0_info,
594                  CAN_CTRL_1_REG_BASE,
595                  CYGNUM_HAL_INTERRUPT_CAN1_TX,
596                  0,
597                  CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY,
598                  CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY,
599                  CAN0_FLAG_STARTUP_ACCFILT_SETUP);
600 #endif
601
602 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
603 LPC2XXX_CAN_INFO(lpc2xxx_can1_info, 
604                  CAN_CTRL_2_REG_BASE, 
605                  CYGNUM_HAL_INTERRUPT_CAN2_TX,
606                  1,
607                  CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY,
608                  CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY,
609                  CAN1_FLAG_STARTUP_ACCFILT_SETUP);
610 #endif
611
612 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
613 LPC2XXX_CAN_INFO(lpc2xxx_can2_info, 
614                  CAN_CTRL_3_REG_BASE, 
615                  CYGNUM_HAL_INTERRUPT_CAN3_TX,
616                  2,
617                  CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY,
618                  CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY,
619                  CAN2_FLAG_STARTUP_ACCFILT_SETUP);
620 #endif
621
622 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
623 LPC2XXX_CAN_INFO(lpc2xxx_can3_info, 
624                  CAN_CTRL_4_REG_BASE, 
625                  CYGNUM_HAL_INTERRUPT_CAN4_TX,
626                  3,
627                  CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY,
628                  CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY,
629                  CAN3_FLAG_STARTUP_ACCFILT_SETUP);
630 #endif
631 #else // CYGINT_IO_CAN_CHANNELS == 1
632 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
633 LPC2XXX_CAN_INFO(lpc2xxx_can0_info, 
634                  CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY, 
635                  CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY, 
636                  CAN0_FLAG_STARTUP_ACCFILT_SETUP);
637 #define CAN_CTRL_SINGLETON_BASE   CAN_CTRL_1_REG_BASE
638 #define CAN_SINGLETON_ISRVEC      CYGNUM_HAL_INTERRUPT_CAN1_TX
639 #define CAN_SINGLETON_CHAN_NO     0
640 #endif
641
642 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
643 LPC2XXX_CAN_INFO(lpc2xxx_can1_info,
644                  CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY,
645                  CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY,
646                  CAN1_FLAG_STARTUP_ACCFILT_SETUP);
647 #define CAN_CTRL_SINGLETON_BASE   CAN_CTRL_2_REG_BASE
648 #define CAN_SINGLETON_ISRVEC      CYGNUM_HAL_INTERRUPT_CAN2_TX
649 #define CAN_SINGLETON_CHAN_NO     1
650 #endif
651
652 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
653 LPC2XXX_CAN_INFO(lpc2xxx_can2_info,
654                  CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY,
655                  CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY,
656                  CAN2_FLAG_STARTUP_ACCFILT_SETUP);
657 #define CAN_CTRL_SINGLETON_BASE   CAN_CTRL_3_REG_BASE
658 #define CAN_SINGLETON_ISRVEC      CYGNUM_HAL_INTERRUPT_CAN3_TX
659 #define CAN_SINGLETON_CHAN_NO     2
660 #endif
661
662 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
663 LPC2XXX_CAN_INFO(lpc2xxx_can3_info,
664                  CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY,
665                  CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY,
666                  CAN3_FLAG_STARTUP_ACCFILT_SETUP);
667 #define CAN_CTRL_SINGLETON_BASE   CAN_CTRL_4_REG_BASE
668 #define CAN_SINGLETON_ISRVEC      CYGNUM_HAL_INTERRUPT_CAN4_TX
669 #define CAN_SINGLETON_CHAN_NO     3
670 #endif
671
672 #endif // #if CYGINT_IO_CAN_CHANNELS > 1
673
674
675 //===========================================================================
676 //                              PROTOTYPES
677 //===========================================================================
678
679 //--------------------------------------------------------------------------
680 // Device driver interface functions
681 //
682 static bool        lpc2xxx_can_init(struct cyg_devtab_entry* devtab_entry);
683 static Cyg_ErrNo   lpc2xxx_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name);
684 static Cyg_ErrNo   lpc2xxx_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
685 static Cyg_ErrNo   lpc2xxx_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
686 static bool        lpc2xxx_can_putmsg(can_channel *priv, CYG_CAN_MSG_T *pmsg, void *pdata);
687 static bool        lpc2xxx_can_getevent(can_channel *priv, CYG_CAN_EVENT_T *pevent, void *pdata);
688 static void        lpc2xxx_can_start_xmit(can_channel* chan);
689 static void        lpc2xxx_can_stop_xmit(can_channel* chan);
690
691
692 //--------------------------------------------------------------------------
693 // ISRs and DSRs
694 //
695 #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
696 static cyg_uint32 lpc2xxx_can_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
697 static void       lpc2xxx_can_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
698 static cyg_uint32 lpc2xxx_can_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
699 static void       lpc2xxx_can_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
700 #endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
701 static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data);
702 static void       lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
703
704
705 //--------------------------------------------------------------------------
706 // Private utility functions
707 //
708 static bool lpc2xxx_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init);
709 static bool lpc2xxx_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate);
710 static Cyg_ErrNo lpc2xxx_enter_lowpower_mode(can_channel *chan);
711 static void lpc2xxx_start_module(can_channel *chan);
712 static cyg_can_state lpc2xxx_get_state(lpc2xxx_can_info_t *info);
713 static void lpc2xxx_set_state(lpc2xxx_can_info_t *info, cyg_can_state state);
714
715
716 //--------------------------------------------------------------------------
717 // Message box configuration
718 //
719 static void lpc2xxx_can_config_rx_all(can_channel *chan);
720 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
721 static void lpc2xxx_can_config_rx_none(can_channel *chan);
722 static bool lpc2xxx_can_add_rx_filter(lpc2xxx_can_info_t *info, cyg_can_filter *filter);
723 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
724
725
726 #include "can_accfilt_lpc2xxx.c"
727
728 //===========================================================================
729 //                   GENERIC CAN IO DATA INITIALISATION
730 //===========================================================================
731 CAN_LOWLEVEL_FUNS(lpc2xxx_can_lowlevel_funs,
732                   lpc2xxx_can_putmsg,
733                   lpc2xxx_can_getevent,
734                   lpc2xxx_can_get_config,
735                   lpc2xxx_can_set_config,
736                   lpc2xxx_can_start_xmit,
737                   lpc2xxx_can_stop_xmit
738      );
739
740
741 //---------------------------------------------------------------------------
742 // CAN channel 0
743 //
744 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
745 CYG_CAN_EVENT_T  lpc2xxx_can0_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX]; // buffer for RX can events
746 CYG_CAN_MSG_T    lpc2xxx_can0_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_TX]; // buffer for TX can messages
747
748
749 CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can0_chan,
750                              lpc2xxx_can_lowlevel_funs,
751                              lpc2xxx_can0_info,
752                              CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD),
753                              lpc2xxx_can0_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_TX,
754                              lpc2xxx_can0_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX
755     );
756
757
758 DEVTAB_ENTRY(lpc2xxx_can0_devtab, 
759              CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME,
760              0,                     // Does not depend on a lower level interface
761              &cyg_io_can_devio, 
762              lpc2xxx_can_init, 
763              lpc2xxx_can_lookup,    // CAN driver may need initializing
764              &lpc2xxx_can0_chan
765     );
766 #endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN0
767
768
769 //---------------------------------------------------------------------------
770 // CAN channel 1
771 //
772 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
773 CYG_CAN_EVENT_T  lpc2xxx_can1_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_RX]; // buffer for RX can events
774 CYG_CAN_MSG_T    lpc2xxx_can1_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_TX]; // buffer for TX can messages
775
776
777 CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can1_chan,
778                              lpc2xxx_can_lowlevel_funs,
779                              lpc2xxx_can1_info,
780                              CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD),
781                              lpc2xxx_can1_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_TX,
782                              lpc2xxx_can1_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_RX
783     );
784
785
786 DEVTAB_ENTRY(lpc2xxx_can1_devtab, 
787              CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME,
788              0,                     // Does not depend on a lower level interface
789              &cyg_io_can_devio, 
790              lpc2xxx_can_init, 
791              lpc2xxx_can_lookup,    // CAN driver may need initializing
792              &lpc2xxx_can1_chan
793     );
794 #endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN1
795
796
797 //---------------------------------------------------------------------------
798 // CAN channel 2
799 //
800 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
801 CYG_CAN_EVENT_T  lpc2xxx_can2_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_RX]; // buffer for RX can events
802 CYG_CAN_MSG_T    lpc2xxx_can2_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_TX]; // buffer for TX can messages
803
804
805 CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can2_chan,
806                              lpc2xxx_can_lowlevel_funs,
807                              lpc2xxx_can2_info,
808                              CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN2_KBAUD),
809                              lpc2xxx_can2_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_TX,
810                              lpc2xxx_can2_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_RX
811     );
812
813
814 DEVTAB_ENTRY(lpc2xxx_can2_devtab, 
815              CYGPKG_DEVS_CAN_LPC2XXX_CAN2_NAME,
816              0,                     // Does not depend on a lower level interface
817              &cyg_io_can_devio, 
818              lpc2xxx_can_init, 
819              lpc2xxx_can_lookup,    // CAN driver may need initializing
820              &lpc2xxx_can2_chan
821     );
822 #endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN2
823
824
825 //---------------------------------------------------------------------------
826 // CAN channel 3
827 //
828 #ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
829 CYG_CAN_EVENT_T  lpc2xxx_can3_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_RX]; // buffer for RX can events
830 CYG_CAN_MSG_T    lpc2xxx_can3_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_TX]; // buffer for TX can messages
831
832
833 CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can3_chan,
834                              lpc2xxx_can_lowlevel_funs,
835                              lpc2xxx_can3_info,
836                              CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN3_KBAUD),
837                              lpc2xxx_can3_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_TX,
838                              lpc2xxx_can3_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_RX
839     );
840
841
842 DEVTAB_ENTRY(lpc2xxx_can3_devtab, 
843              CYGPKG_DEVS_CAN_LPC2XXX_CAN3_NAME,
844              0,                     // Does not depend on a lower level interface
845              &cyg_io_can_devio, 
846              lpc2xxx_can_init, 
847              lpc2xxx_can_lookup,    // CAN driver may need initializing
848              &lpc2xxx_can3_chan
849     );
850 #endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN3
851
852
853 //===========================================================================
854 //                            IMPLEMENTATION
855 //===========================================================================
856
857
858
859 //===========================================================================
860 /// First initialisation and reset of CAN modul.
861 //===========================================================================
862 static bool lpc2xxx_can_init(struct cyg_devtab_entry* devtab_entry)
863 {
864     can_channel          *chan    = (can_channel*)devtab_entry->priv;
865     bool                  res;
866
867 #ifdef CYGDBG_IO_INIT
868     diag_printf("LPC2XXX CAN init\n");
869 #endif  
870
871     //
872     // Newer LPC2xxx variants do not support individual interrupt
873     // sources for CAN on chip peripherals
874     //
875 #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY  
876     lpc2xxx_can_info_t   *info    = (lpc2xxx_can_info_t *)chan->dev_priv;  
877     //
878     // Create TX interrupt
879     //
880     cyg_drv_interrupt_create(CAN_ISRVEC(info),
881                              info->tx_interrupt_priority,
882                              (cyg_addrword_t)chan,     // Data item passed to interrupt handler
883                              lpc2xxx_can_tx_ISR,
884                              lpc2xxx_can_tx_DSR,
885                              &info->tx_interrupt_handle,
886                              &info->tx_interrupt);
887     cyg_drv_interrupt_attach(info->tx_interrupt_handle);
888     cyg_drv_interrupt_unmask(CAN_ISRVEC(info));
889     
890     //
891     // Create RX interrupt
892     //
893     cyg_drv_interrupt_create(CAN_ISRVEC(info) + 6,
894                              info->rx_interrupt_priority,
895                              (cyg_addrword_t)chan,     // Data item passed to interrupt handler
896                              lpc2xxx_can_rx_ISR,
897                              lpc2xxx_can_rx_DSR,
898                              &info->rx_interrupt_handle,
899                              &info->rx_interrupt);
900     cyg_drv_interrupt_attach(info->rx_interrupt_handle);
901     cyg_drv_interrupt_unmask(CAN_ISRVEC(info) + 6);
902 #endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
903     
904     //
905     // Now create and enable global CAN interrupt. This interrupt is
906     // global for all channels and so we need to call it only one times -
907     // when the first channel is initialized
908     //
909 #if CYGINT_IO_CAN_CHANNELS > 1
910     if (!lpc2xxx_global_can_info.init_cnt)
911 #endif // #if CYGINT_IO_CAN_CHANNELS > 1
912     {
913         //
914         // Create err interrupt
915         //
916         cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_CAN,
917 #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
918                                  CYGNUM_DEVS_CAN_LPC2XXX_ERR_INT_PRIORITY,
919 #else // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
920                                  CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY,
921 #endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
922                                  0,                        // Data item passed to interrupt handler
923                                  lpc2xxx_can_ISR,
924                                  lpc2xxx_can_DSR,
925                                  &lpc2xxx_global_can_info.interrupt_handle,
926                                  &lpc2xxx_global_can_info.interrupt);
927         cyg_drv_interrupt_attach(lpc2xxx_global_can_info.interrupt_handle);
928         cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_CAN);     
929     }   
930    
931     res = lpc2xxx_can_config_channel(chan, &chan->config, true);
932 #if CYGINT_IO_CAN_CHANNELS > 1
933     lpc2xxx_global_can_info.active_channels[lpc2xxx_global_can_info.init_cnt++] = chan;
934 #else // CYGINT_IO_CAN_CHANNELS > 1
935     lpc2xxx_global_can_info.active_channels[0] = chan;
936 #endif
937     return res; 
938 }
939
940
941 //===========================================================================
942 // Configure can channel
943 //===========================================================================
944 static bool lpc2xxx_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init)
945 {
946     CAN_DECLARE_INFO(chan);
947     bool       res = true;
948     
949     if (init)
950     {
951         //
952         // In case platform needs extra initialization (i.e. setup of
953         // CAN transceivers) it should implement this macro
954         //
955 #ifdef CYGPRI_IO_CAN_LPC2XXX_PLF_INIT_HOOK
956         CYGPRI_IO_CAN_LPC2XXX_PLF_INIT_HOOK(chan, config);
957 #endif
958         
959         HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF);       // Acceptance Filter Mode Register = off
960         HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET); // Go into reset mode
961         HAL_WRITE_UINT32(CAN_CTRL_IER(info), 0);            // disable all interrupts
962         HAL_WRITE_UINT32(CAN_CTRL_GSR(info), 0);            // Clear Status register - clears error counters  
963         
964         //
965         // Perform platform/variant specific initialisation here. 
966         // The variant/ platform should setup the pin configuration to support 
967         // CAN here
968         //
969         HAL_LPC2XXX_INIT_CAN(CAN_CHAN_NO(info)); 
970          
971         //
972         // If this is the first channel to initialize then we reset the CAN 
973         // registers and setup the CAN I/O pins
974         //
975 #if CYGINT_IO_CAN_CHANNELS > 1
976         if (!lpc2xxx_global_can_info.init_cnt)
977 #endif // #if CYGINT_IO_CAN_CHANNELS > 1
978         {
979             lpc2xxx_can_accfilt_reset();           
980         }   
981     } // if (init)
982     
983     res = lpc2xxx_can_set_baud(chan, &config->baud);           // set baudrate
984     // $$$$ enable receive interrupt?
985     HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_OPERATIONAL);  // enter normal operating mode
986             
987     //
988     // store new config values
989     //
990     if (config != &chan->config) 
991     {
992         chan->config = *config;
993     }   
994     
995     return res;
996 }
997
998
999 //===========================================================================
1000 // Set baudrate of certain can channel
1001 //===========================================================================
1002 static bool lpc2xxx_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate)
1003 {
1004     bool                  res = true;
1005     cyg_uint32            canbtr;
1006     cyg_uint32            canmod;
1007     CAN_DECLARE_INFO(chan);
1008     
1009     //
1010     // Get bit timings from HAL because bit timings depend on sysclock
1011     // If the macro fills the canbtr value with 0 then the baudrate
1012     // is not supported and the function returns false
1013     //
1014     HAL_LPC2XXX_GET_CAN_BR(*baudrate, canbtr);   
1015     if (0 == canbtr)
1016     {
1017         return false;
1018     }
1019     
1020     //
1021     // Any modificatons to the baudrate register must be done while CAN
1022     // module is in reset mode. So we first set the CAN module in reset
1023     // mode, then we set baudrate and then we restore content of CANMOD 
1024     // register
1025     //
1026     HAL_READ_UINT32(CAN_CTRL_MOD(info), canmod);        // backup canmod register
1027     HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET); // Go into reset mode
1028     HAL_WRITE_UINT32(CAN_CTRL_BTR(info), canbtr);       // write baudrate value
1029     HAL_WRITE_UINT32(CAN_CTRL_MOD(info), canmod);       // restore previous value
1030        
1031     return res;
1032 }
1033
1034
1035 //===========================================================================
1036 //  Lookup the device and return its handle
1037 //===========================================================================
1038 static Cyg_ErrNo lpc2xxx_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name)
1039 {
1040     can_channel* chan    = (can_channel*) (*tab)->priv;
1041     lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
1042     cyg_uint32   regval;
1043
1044     chan->callbacks->can_init(chan); 
1045     
1046     //
1047     // If runtime acceptance filter configuration is supported then we only
1048     // configure RX ALL if the user selected the RX ALL setup in config utility
1049     //
1050 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
1051     if (info->flags & INFO_FLAG_STARTUP_RX_ALL)
1052 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
1053     {
1054        lpc2xxx_can_config_rx_all(chan); 
1055     }
1056     
1057     HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_ON);       // Activate acceptance filter
1058     HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
1059     regval = regval | IER_RX | CAN_MISC_INT;           // enable all interrupts     
1060     HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);  
1061       
1062     return ENOERR;
1063 }
1064
1065
1066 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
1067 //===========================================================================
1068 // Setup LPC2XXX CAN module in a state where all message boxes are disabled
1069 // After this call it is possible to add single message buffers and filters
1070 //===========================================================================
1071 static void lpc2xxx_can_config_rx_none(can_channel *chan)
1072 {
1073     lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
1074       
1075     //
1076     // Remove all acceptance filters
1077     // $$$$ maybe we should also abort any pending transfers and
1078     // disable receive interrupts ?
1079     //
1080     lpc2xxx_can_accfilt_remove_all_ctrl_entries(info);
1081     info->flags  &= ~INFO_FLAG_RX_ALL;
1082 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
1083     lpc2xxx_can_accfilt_dbg_dump();
1084 #endif
1085 }
1086
1087
1088 //===========================================================================
1089 // Add one single message filter to acceptance filter
1090 //===========================================================================
1091 static bool lpc2xxx_can_add_rx_filter(lpc2xxx_can_info_t *info, cyg_can_filter *filter)
1092 {
1093     bool res;
1094     
1095     res = lpc2xxx_can_accfilt_add(info, filter->msg.id, 0, filter->msg.ext); 
1096     if (!res)
1097     {
1098         filter->handle = CYGNUM_CAN_MSGBUF_NA;
1099     }
1100 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
1101     lpc2xxx_can_accfilt_dbg_dump();
1102 #endif    
1103     return res;
1104 }
1105 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
1106
1107
1108
1109 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
1110 //===========================================================================
1111 // Configure message buffers
1112 //===========================================================================
1113 static Cyg_ErrNo lpc2xxx_can_config_msgbuf(can_channel *chan, const void* buf, cyg_uint32* len)
1114 {
1115     Cyg_ErrNo             res  = ENOERR;
1116     lpc2xxx_can_info_t   *info = (lpc2xxx_can_info_t *)chan->dev_priv;   
1117     cyg_can_msgbuf_cfg   *msg_buf = (cyg_can_msgbuf_cfg *)buf;
1118
1119     if (*len != sizeof(cyg_can_msgbuf_cfg))
1120     {
1121         return -EINVAL;
1122     }
1123
1124     switch (msg_buf->cfg_id)
1125     {
1126         //
1127         // clear all message filters and remote buffers - prepare for message buffer
1128         // configuration
1129         //
1130         case CYGNUM_CAN_MSGBUF_RESET_ALL :
1131              {
1132                  lpc2xxx_can_config_rx_none(chan);
1133              }
1134              break;
1135
1136         //
1137         // setup driver for reception of all standard and extended messages
1138         //
1139         case CYGNUM_CAN_MSGBUF_RX_FILTER_ALL :
1140              {
1141                  if (!(info->flags & INFO_FLAG_RX_ALL)) // if rx_all is enabled we do not need to do anything
1142                  {
1143                     lpc2xxx_can_config_rx_all(chan);  // setup RX all state
1144                  }
1145              }
1146              break;
1147         
1148         //
1149         // add single message filter, message with filter ID will be received
1150         //     
1151         case CYGNUM_CAN_MSGBUF_RX_FILTER_ADD :
1152              {
1153                  cyg_can_filter *filter   = (cyg_can_filter*) buf;
1154                  
1155                  //
1156                  // if the acceptance filter is configured to receive all messages then 
1157                  // it is not allowed to add single message filters because then more 
1158                  // than one acceptance filter would receive the same CAN id
1159                  //
1160                  if (info->flags & INFO_FLAG_RX_ALL)
1161                  {
1162                     return -EPERM;
1163                  }
1164                  
1165                  //
1166                  // try to allocate a free acceptance filter entry - if we have a free one
1167                  // then we can prepare the acceptance filter table for reception of
1168                  // this message
1169                  //
1170                  if (!lpc2xxx_can_add_rx_filter(info, filter))
1171                  {
1172                      return -EPERM;
1173                  }
1174              }
1175              break; //CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
1176              
1177
1178 #ifdef CYGOPT_IO_CAN_REMOTE_BUF
1179         //
1180         // Try to add a new RTR response message buffer for automatic
1181         // transmission of data frame on reception of a remote frame
1182         //
1183         case CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD :
1184              {
1185                  // $$$$ TODO implement remote response buffers in software
1186                  return -ENOSUPP;
1187              }
1188              break;
1189                      
1190         //
1191         // write data into remote response buffer
1192         //
1193         case CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE :
1194              {
1195                  // $$$$ TODO implement remote response buffers in software
1196                  return -ENOSUPP;
1197              }
1198              break;
1199 #endif // #ifdef CYGOPT_IO_CAN_REMOTE_BUF
1200         default:
1201             return -EINVAL;
1202     } // switch (buf->cfg_id)
1203     
1204     return res;
1205 }
1206 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
1207
1208
1209 //===========================================================================
1210 // Read state of CAN controller
1211 // The CAN state variable for each channel is modified by DSR so if we 
1212 // read the state we need to lock DSRs to protect the data access
1213 //===========================================================================
1214 static cyg_can_state lpc2xxx_get_state(lpc2xxx_can_info_t *info)
1215 {
1216     cyg_can_state result;
1217     
1218     cyg_drv_dsr_lock();
1219     result = info->state;
1220     cyg_drv_dsr_unlock();
1221     
1222     return result;
1223 }
1224
1225
1226 //===========================================================================
1227 // Set state of CAN controller
1228 // The CAN state variable for each channel is modified by DSR so if we 
1229 // write the state we need to lock DSRs to protect the data access
1230 //===========================================================================
1231 static void lpc2xxx_set_state(lpc2xxx_can_info_t *info, cyg_can_state state)
1232 {   
1233     cyg_drv_dsr_lock();
1234     info->state = state;
1235     cyg_drv_dsr_unlock();
1236 }
1237
1238
1239 //===========================================================================
1240 // Enter low power mode
1241 //===========================================================================
1242 static Cyg_ErrNo lpc2xxx_enter_lowpower_mode(can_channel *chan)
1243 {
1244     cyg_uint32          regval;
1245     lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
1246     
1247     //
1248     // Before we enter low power mode, we have to enable wake up interrupt
1249     // Normally this interrupt is always enabled so we do not need to do
1250     // anything here
1251     //
1252     HAL_READ_UINT32(CAN_CTRL_MOD(info), regval); 
1253     
1254     //
1255     // Software can only set SM when RM in the CAN Mode register is 0
1256     //
1257     if (regval & CANMOD_RESET)
1258     {
1259         return -EPERM;
1260     }
1261     
1262     //regval &= CANMOD_SLEEP;
1263     lpc2xxx_set_state(info, CYGNUM_CAN_STATE_STANDBY);
1264     HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_SLEEP); 
1265     return ENOERR;
1266 }
1267
1268
1269 //===========================================================================
1270 // Start CAN module - set CANMOD operational and enable all interrupts
1271 //===========================================================================
1272 static void lpc2xxx_start_module(can_channel *chan)
1273 {
1274     cyg_uint32          regval;
1275     lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
1276     
1277     HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_OPERATIONAL);  
1278     //
1279     // The interrupt enable register is also modified by ISR and DSR so
1280     // we need to protect acces here
1281     //
1282     cyg_drv_isr_lock();
1283     HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
1284     regval = regval | IER_RX | CAN_MISC_INT;           // enable all interrupts     
1285     HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval); 
1286     info->state = CYGNUM_CAN_STATE_ACTIVE; 
1287     cyg_drv_isr_unlock();
1288 }
1289
1290
1291 //===========================================================================
1292 // Enter reset mode
1293 //===========================================================================
1294 static void lpc2xxx_enter_reset_mode(can_channel *chan)
1295 {
1296     lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;  
1297     
1298     info->state = CYGNUM_CAN_STATE_STOPPED;
1299     HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET);
1300 }
1301
1302
1303 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
1304 //===========================================================================
1305 // Add message filter group
1306 //===========================================================================
1307 static Cyg_ErrNo lpc2xxx_can_config_accfilt_group(can_channel *chan, const void* buf, cyg_uint32* len)
1308 {
1309     bool                     res;
1310     cyg_can_filtergroup_cfg *filter_grp = (cyg_can_filtergroup_cfg *)buf;
1311     lpc2xxx_can_info_t      *info = (lpc2xxx_can_info_t *)chan->dev_priv; 
1312     
1313     
1314     if (*len != sizeof(cyg_can_filtergroup_cfg))
1315     {
1316         return -EINVAL;
1317     }
1318     
1319     if (filter_grp->lower_id_bound >= filter_grp->upper_id_bound)
1320     {
1321         return -EINVAL;
1322     }
1323     
1324     //
1325     // if the acceptance filter is configured to receive all messages then 
1326     // it is not allowed to add single message filter groups because then more 
1327     // than one acceptance filter would receive the same CAN id
1328     //
1329     if (info->flags & INFO_FLAG_RX_ALL)
1330     {
1331         return -EPERM;
1332     }
1333     
1334     res = lpc2xxx_can_accfilt_add(info, 
1335                                   filter_grp->lower_id_bound, 
1336                                   filter_grp->upper_id_bound, 
1337                                   filter_grp->ext);
1338     
1339 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
1340     lpc2xxx_can_accfilt_dbg_dump();
1341 #endif        
1342     return res ? ENOERR : -EPERM;
1343 }
1344 #endif // CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
1345
1346
1347 //===========================================================================
1348 // Change device configuration
1349 //===========================================================================
1350 static Cyg_ErrNo lpc2xxx_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
1351 {
1352     Cyg_ErrNo  res = ENOERR;
1353     
1354     switch (key)
1355     {   
1356         //
1357         // Setup a new CAN configuration. This will i.e. setup a new baud rate
1358         //
1359         case CYG_IO_SET_CONFIG_CAN_INFO:
1360              {
1361                  cyg_can_info_t*  config = (cyg_can_info_t*) buf;
1362                  if (*len < sizeof(cyg_can_info_t))
1363                  {
1364                      return -EINVAL;
1365                  }
1366                  *len = sizeof(cyg_can_info_t);
1367                  if (!lpc2xxx_can_config_channel(chan, config, false))
1368                  {
1369                      return -EINVAL;
1370                  }
1371              }
1372              break;
1373
1374 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG            
1375         //
1376         // configure message buffers
1377         //
1378         case CYG_IO_SET_CONFIG_CAN_MSGBUF :
1379              {               
1380                 res = lpc2xxx_can_config_msgbuf(chan, buf, len);
1381              }
1382              break;
1383 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
1384          
1385 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
1386         //
1387         // Add message filter group to acceptance filter
1388         //
1389         case CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP :
1390              {
1391                  return lpc2xxx_can_config_accfilt_group(chan, buf, len);
1392              }
1393              break;
1394 #endif // CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS 
1395                         
1396         //
1397         // Change CAN state of CAN module
1398         //    
1399         case CYG_IO_SET_CONFIG_CAN_MODE :
1400              {
1401                 cyg_can_mode   *can_mode  = (cyg_can_mode*) buf;
1402                 
1403                 if (*len != sizeof(cyg_can_mode)) 
1404                 {
1405                     return -EINVAL;
1406                 }
1407                 *len = sizeof(cyg_can_mode);
1408                 
1409                 //
1410                 // decide what to do according to mode
1411                 //
1412                 switch (*can_mode)
1413                 {
1414                     //
1415                     // The controller does not support a stopped and standby state so we
1416                     // simply enter the low power state here. This state is also safe for
1417                     // message buffer configuration
1418                     //
1419                     case CYGNUM_CAN_MODE_STOP :    lpc2xxx_enter_reset_mode(chan);    break; 
1420                     case CYGNUM_CAN_MODE_START :   lpc2xxx_start_module(chan);        break;                       
1421                     case CYGNUM_CAN_MODE_STANDBY : lpc2xxx_enter_lowpower_mode(chan); break;
1422                     case CYGNUM_CAN_MODE_CONFIG :  lpc2xxx_enter_reset_mode(chan);    break;
1423                 }
1424              }
1425              break; // case CYG_IO_SET_CONFIG_CAN_MODE :
1426         //
1427         // Unknown config key - indicate this by returning -EINVAL
1428         //
1429         default:
1430                     return -EINVAL;
1431     } // switch (key)
1432     
1433     return res;
1434 }
1435
1436
1437 //===========================================================================
1438 // Query device configuration
1439 //===========================================================================
1440 static Cyg_ErrNo lpc2xxx_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
1441 {
1442     Cyg_ErrNo            res  = ENOERR;
1443     lpc2xxx_can_info_t  *info = (lpc2xxx_can_info_t *)chan->dev_priv;
1444     
1445     switch(key)
1446     {
1447         //
1448         // query state of CAN controller
1449         //
1450         case CYG_IO_GET_CONFIG_CAN_STATE :
1451              {
1452                 cyg_can_state *can_state  = (cyg_can_state*) buf;
1453                 
1454                 if (*len != sizeof(cyg_can_state)) 
1455                 {
1456                     return -EINVAL;
1457                 }
1458                 *len = sizeof(cyg_can_state);
1459                 *can_state = lpc2xxx_get_state(info);
1460              }
1461              break;
1462
1463 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG       
1464         //
1465         // Query message box information - returns available and free message
1466         // boxes
1467         //     
1468         case CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO :
1469              {
1470                  cyg_can_msgbuf_info *mbox_info  = (cyg_can_msgbuf_info*) buf;
1471                 
1472                  if (*len != sizeof(cyg_can_msgbuf_info)) 
1473                  {
1474                      return -EINVAL;
1475                  }
1476                  cyg_uint32 end_of_table;
1477                 *len = sizeof(cyg_can_msgbuf_info);
1478               
1479                  HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
1480                  mbox_info->count = LPC2XXX_CAN_MSG_FILTERS_MAX;
1481                  mbox_info->free  = (ACCFILT_RAM_SIZE - end_of_table) / ACCFILT_COMMON_ENTRY_SIZE;
1482              }
1483              break;
1484 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
1485
1486         
1487         //
1488         // Query hardware description of FlexCAN device driver
1489         //     
1490         case CYG_IO_GET_CONFIG_CAN_HDI :
1491              {
1492                 cyg_can_hdi *hdi = (cyg_can_hdi *)buf;
1493                 //
1494                 // comes from high level driver so we do not need to
1495                 // check buffer size here
1496                 //             
1497                 hdi->support_flags = CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE
1498                                    | CYGNUM_CAN_HDI_FULLCAN;
1499              }
1500              break;
1501              
1502         default :
1503             res = -EINVAL;
1504     }// switch(key)
1505     
1506     return res;
1507 }
1508
1509
1510 //===========================================================================
1511 // Send single message
1512 //===========================================================================
1513 static bool lpc2xxx_can_putmsg(can_channel *chan, CYG_CAN_MSG_T *pmsg, void *pdata)
1514 {
1515     cyg_uint32 regval;
1516 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
1517     lpc2xxx_can_info_t  *info = (lpc2xxx_can_info_t *) chan->dev_priv;
1518 #else
1519     CAN_DECLARE_INFO(info);
1520 #endif
1521     
1522     //
1523     // We use only one single transmit buffer of the three available buffers
1524     // We use buffer 1 (buffer 2 and 3 are unused)
1525     //
1526     // The errata sheet tells the following about the transmit buffers:
1527     // Problem: The Triple Transmit Buffer function cannot be used.
1528     // Work-around: Use any one Transmit buffer only (Use either Transmit Buffer 1, 
1529     // Transmit Buffer 2 or Transmit Buffer 3 exclusively). The buffer you decided 
1530     // to use should be loaded only when there is no pending transmission.
1531     //
1532     HAL_READ_UINT32(CAN_CTRL_SR(info), regval);
1533     if (!(regval & SR_TX_BUF_WRITE_OK))
1534     {
1535         return false;    
1536     }
1537     
1538     regval = pmsg->dlc << 16;
1539     if (pmsg->rtr)
1540     {
1541         regval |= TFI_DLC_RTR;
1542     }
1543  
1544 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
1545     if (pmsg->ext)
1546     {
1547         regval |= TFI_DLC_EXT;
1548     }
1549 #endif // #define CYGOPT_IO_CAN_EXT_CAN_ID
1550     HAL_WRITE_UINT32(CAN_CTRL_TFI1(info), regval);                       // write DLC
1551     HAL_WRITE_UINT32(CAN_CTRL_TID1(info), pmsg->id);                     // write ID
1552     HAL_WRITE_UINT32(CAN_CTRL_TDA1(info), pmsg->data.dwords[0]);         // write first 4 data bytes
1553     HAL_WRITE_UINT32(CAN_CTRL_TDB1(info), pmsg->data.dwords[1]);         // write second 4 data bytes
1554     
1555     //
1556     // Request transmission of message
1557     // The errata sheet tells the following about tx request:
1558     // Introduction: The CAN module can lose arbitration to another CAN node during an 
1559     // attempt to transmit a CAN message. The message of the CAN node the arbitration was 
1560     // lost to is supposed to be received correctly by the CAN module.
1561     // Problem: Messages might not be received correctly if during a CAN Transmission the 
1562     // CAN bus arbitration is lost to another CAN node.
1563     // Work-around: Use the Self Reception Request command instead of the Transmission 
1564     // Request command. However, it has to be taken into account that now all transmitted
1565     // messages may be received if not prevented by appropriate Acceptance Filter settings. 
1566     // (Don't set up Acceptance Filter Message Identifiers for the messages you are
1567     // transmitting yourself.)
1568     //
1569 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
1570     // Calc last_tx_id
1571     regval = pmsg->id | (regval & LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK);
1572     
1573     // Save last message id to next last_tx_id
1574     info->last_tx_index = info->last_tx_index == 0 ? 1 : 0;
1575     info->last_tx_id[info->last_tx_index] = regval;
1576     
1577     // Write self transmission request
1578     HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_SELF_RX_REQ | CMR_SEND_TX_BUF1);
1579 #else
1580     // Write transmission request
1581     HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_TX_REQ | CMR_SEND_TX_BUF1);
1582 #endif
1583    
1584     return true;
1585 }
1586
1587
1588 //===========================================================================
1589 // Read event from device driver
1590 //===========================================================================
1591 static bool lpc2xxx_can_getevent(can_channel *chan, CYG_CAN_EVENT_T *pevent, void *pdata)
1592 {
1593     lpc2xxx_can_info_t   *info       = (lpc2xxx_can_info_t *)chan->dev_priv;
1594     bool                  res        = true;
1595     cyg_uint32            regval;
1596     cyg_uint32            event      = *((cyg_uint32*)pdata);
1597     lsc_buf_t             data;
1598       
1599     //
1600     // Handle RX event
1601     //
1602     if (event & ICR_RX)
1603     {
1604         cyg_uint32            id;
1605         
1606         pevent->flags |= CYGNUM_CAN_EVENT_RX;
1607         HAL_READ_UINT32(CAN_CTRL_RFS(info), regval); 
1608         HAL_READ_UINT32(CAN_CTRL_RID(info), id);
1609
1610 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
1611         if (regval & RFS_EXT)
1612         {
1613             pevent->msg.ext = CYGNUM_CAN_ID_EXT;
1614             pevent->msg.id = id & 0x1FFFFFFF;
1615         }
1616         else
1617 #endif // #define CYGOPT_IO_CAN_EXT_CAN_ID
1618         {
1619 #ifdef CYGOPT_IO_CAN_STD_CAN_ID
1620             pevent->msg.ext = CYGNUM_CAN_ID_STD;
1621             pevent->msg.id = id & 0x7FF;
1622 #endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
1623         } // if (regval & RFS_EXT)
1624         
1625         if (regval & RFS_RTR)
1626         {
1627             pevent->msg.rtr = CYGNUM_CAN_FRAME_RTR;
1628         }
1629         else
1630         {
1631             pevent->msg.rtr = CYGNUM_CAN_FRAME_DATA;  
1632             HAL_READ_UINT32(CAN_CTRL_RDA(info), pevent->msg.data.dwords[0]);
1633             HAL_READ_UINT32(CAN_CTRL_RDB(info), pevent->msg.data.dwords[1]);
1634         } //if (regval & RFS_RTR)
1635         pevent->msg.dlc = RFS_GET_DLC(regval);
1636         //
1637         // Release the message buffer. Now this buffer can receive the next message
1638         //
1639         HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_RX_RELEASE_BUF);
1640     
1641         //
1642         // Now check if an data overrun occurred - a message was lost
1643         // because the preceding message to this CAN controller was not read 
1644         // and released quickly enough. After reading the status we clear 
1645         // the overrun bit
1646         // 
1647         HAL_READ_UINT32(CAN_CTRL_GSR(info), regval);
1648         if (regval & GSR_DATA_OVR)
1649         {
1650             pevent->flags |= CYGNUM_CAN_EVENT_OVERRUN_RX;
1651             HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_CLEAR_DATA_OVR);
1652         }
1653     }
1654     
1655     //
1656     // Handle TX events
1657     //
1658 #ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT 
1659     if (event & ICR_TX1)
1660     {
1661         pevent->flags |= CYGNUM_CAN_EVENT_TX;
1662     }
1663 #endif
1664     
1665     //
1666     // Handle all other events
1667     //
1668     if (event & (CAN_MISC_INT | ICR_LUT_ERR))
1669     {
1670         HAL_READ_UINT32(CAN_CTRL_GSR(info), data.dword);
1671         
1672         //
1673         // 1: Error Warning Interrupt -- this bit is set on every change (set or clear) of the Error
1674         // Status or Bus Status bit in CANSR, if the EIE bit in CAN is 1 at the time of the
1675         // change.
1676         //
1677         if (event & ICR_ERR_WARN)
1678         {
1679             //
1680             // If one of the warning counters is above 96 then the controller is in bus warning
1681             // state. If both counters are below 96 the this interrupt indicates that the
1682             // controller has left the bus warning state and is error active again
1683             //
1684             if (data.bytes[2] >= 96)
1685             {
1686                 pevent->flags |= CYGNUM_CAN_EVENT_WARNING_RX;  
1687                 info->state = CYGNUM_CAN_STATE_BUS_WARN;
1688             }
1689             else if (data.bytes[3] >= 96)
1690             {
1691                 pevent->flags |= CYGNUM_CAN_EVENT_WARNING_TX;
1692                 info->state = CYGNUM_CAN_STATE_BUS_WARN;
1693             }
1694             else
1695             {
1696                 info->state = CYGNUM_CAN_STATE_ACTIVE;
1697             }
1698             LPC2XXX_DBG_PRINT("ICR_ERR_WARN (%p)\n", (void*) chan);
1699         }
1700         
1701         //
1702         // 1: Wake-Up Interrupt: this bit is set if the CAN controller is sleeping and bus activity
1703         // is detected, if the WUIE bit in CANIE is 1.
1704         //
1705         if (event & ICR_WAKE_UP)
1706         {
1707             pevent->flags |= CYGNUM_CAN_EVENT_LEAVING_STANDBY; 
1708             info->state = CYGNUM_CAN_STATE_ACTIVE;
1709             LPC2XXX_DBG_PRINT("ICR_WAKE_UP (%p)\n", (void*) chan);
1710         }
1711         
1712         //
1713         // Error Passive Interrupt -- this bit is set if the EPIE bit in CANIE is 1, and the CAN
1714         // controller switches between Error Passive and Error Active mode in either
1715         // direction. We have to check if the ERR bit is set in global status register.
1716         // If it is set, then it is a switch to error passive else it is a switch to
1717         // error active state
1718         //
1719         if (event & ICR_ERR_PASSIVE)
1720         {
1721             if (data.dword & GSR_ERR)
1722             {
1723                 pevent->flags |= CYGNUM_CAN_EVENT_ERR_PASSIVE;    
1724                 info->state = CYGNUM_CAN_STATE_ERR_PASSIVE;
1725             }
1726             else
1727             {
1728                 info->state = CYGNUM_CAN_STATE_ACTIVE;    
1729             }
1730             LPC2XXX_DBG_PRINT("ICR_ERR_PASSIVE (%p)\n", (void*) chan);
1731         }
1732
1733 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_ALIE       
1734         //
1735         // Arbitration Lost Interrupt -- this bit is set if the ALIE bit in CANIE is 1, and the
1736         // CAN controller loses arbitration while attempting to transmit.
1737         //
1738         if (event & ICR_ARBITR_LOST)
1739         {
1740             pevent->flags |= CYGNUM_CAN_EVENT_ARBITRATION_LOST;   
1741             LPC2XXX_DBG_PRINT("ICR_ARBITR_LOST (%p)\n", (void*) chan);
1742         }
1743 #endif // CYGOPT_DEVS_CAN_LPC2XXX_ALIE
1744         
1745         //
1746         // 1: Bus Error Interrupt -- this bit is set if the BEIE bit in CANIE is 1, and the CAN
1747         // controller detects an error on the bus.
1748         //
1749         if (event & ICR_BUS_ERR)
1750         {
1751             pevent->flags |= CYGNUM_CAN_EVENT_BUS_OFF; 
1752             LPC2XXX_DBG_PRINT("ICR_BUS_ERR (%p)\n", (void*) chan);
1753         }
1754         
1755 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
1756         //
1757         // LUT error interrupt -- this bit is set if bit 0 in LUTerr is 1 and LUTerrAd
1758         // points to entry in filter table for this CAN controller
1759         //
1760         if(event & ICR_LUT_ERR)
1761         {
1762             pevent->flags |= CYGNUM_CAN_EVENT_FILTER_ERR;
1763             LPC2XXX_DBG_PRINT("ICR_LUT_ERR (%p)\n", (void*) chan);
1764         }
1765 #endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
1766
1767     } // if (event & (CAN_MISC_INT | ICR_LUT_ERR))
1768           
1769     return res;
1770 }
1771
1772
1773 //===========================================================================
1774 // Kick transmitter
1775 //===========================================================================
1776 static void lpc2xxx_can_start_xmit(can_channel* chan)
1777 {
1778     cyg_uint32 regval;
1779     CAN_DECLARE_INFO(chan);
1780     
1781     LPC2XXX_DBG_PRINT("start_xmit (%p)\n", (void*) chan);
1782
1783     cyg_drv_dsr_lock();
1784     HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
1785     regval |= IER_TX1;                           // enable tx interrupt for tx buf 1
1786     HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval); 
1787     cyg_drv_dsr_unlock();
1788     
1789     //
1790     // kick transmitter
1791     //
1792     chan->callbacks->xmt_msg(chan, 0);  // Kick transmitter (if necessary)
1793 }
1794
1795
1796 //===========================================================================
1797 // Stop transmitter
1798 //===========================================================================
1799 static void lpc2xxx_can_stop_xmit(can_channel* chan)
1800 {
1801     cyg_uint32 regval; 
1802     CAN_DECLARE_INFO(chan);
1803     
1804     LPC2XXX_DBG_PRINT("stop_xmit (%p)\n", (void*) chan);
1805      
1806     cyg_drv_dsr_lock();
1807     HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
1808     regval &= ~IER_TX1;                           // disable tx interrupt for tx buf 1
1809     HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval); 
1810     cyg_drv_dsr_unlock();
1811 }
1812
1813
1814 #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
1815 //===========================================================================
1816 // Low level transmit interrupt handler
1817 //===========================================================================
1818 static cyg_uint32 lpc2xxx_can_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
1819 {
1820     //
1821     // Now read input capture register - this clears all interrupt bits in this
1822     // register and also acknowledges the interrupt - any further processing is done
1823     // by the DSR
1824     //
1825     cyg_drv_interrupt_mask(vector);
1826     cyg_drv_interrupt_acknowledge(vector);
1827     LPC2XXX_DBG_PRINT("tx_ISR (%p)\n", (void*) data);
1828     return CYG_ISR_CALL_DSR;
1829 }
1830
1831
1832 //===========================================================================
1833 // High level transmit interrupt handler
1834 //===========================================================================
1835 static void lpc2xxx_can_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
1836 {
1837     can_channel              *chan = (can_channel *)data;
1838     cyg_uint32                regval;
1839     lpc2xxx_can_info_t       *info = (lpc2xxx_can_info_t *)chan->dev_priv;
1840     
1841     //
1842     // First read the ICR register to acknowledge all interrupts and
1843     // get all captured interrupts
1844     //
1845     HAL_READ_UINT32(CAN_CTRL_ICR(info), regval);
1846     
1847     //
1848     // If TX events are supported then only call the rcv_event() callback
1849     // if any other event occurred - pass the event field to the getevent function
1850     // to indicate the events
1851     //
1852 #ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
1853     if (regval & ~ICR_TX1) 
1854 #endif
1855     {
1856         chan->callbacks->rcv_event(chan, &regval); 
1857     }
1858     
1859     //
1860     // Now transmit next message and reenable interrupts
1861     //
1862     chan->callbacks->xmt_msg(chan, 0); // send next message 
1863     LPC2XXX_DBG_PRINT("tx_DSR (%p)\n", (void*) data);
1864     cyg_drv_interrupt_unmask(vector);    
1865 }
1866
1867
1868 //===========================================================================
1869 // Low level receive interrupt handler
1870 //===========================================================================
1871 static cyg_uint32 lpc2xxx_can_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
1872 {   
1873 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
1874     cyg_uint32   regval;
1875     can_channel* chan = (can_channel*)data;
1876     lpc2xxx_can_info_t  *info = (lpc2xxx_can_info_t *) chan->dev_priv;
1877     cyg_uint32 id;
1878     cyg_uint32 index;
1879     
1880     // We have to reject self tx message, so read message id
1881     HAL_READ_UINT32(CAN_CTRL_RID(info), id);
1882     HAL_READ_UINT32(CAN_CTRL_RFS(info), regval);
1883     id |= (regval & LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK);
1884     
1885     // Test message id
1886     for(index = 0; index < 2; index++)
1887     {
1888         if(id == info->last_tx_id[index])
1889         {
1890             // Clear last_tx_id
1891             info->last_tx_id[index] = LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID;
1892             
1893             // Clear receive buffer
1894             HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_RX_RELEASE_BUF);
1895             
1896             // Acknowledge a vector
1897             cyg_drv_interrupt_acknowledge(vector);
1898             
1899             // Exit without calling DSR
1900             LPC2XXX_DBG_PRINT("self_rx_ISR (%p)\n", (void*) data);
1901             return CYG_ISR_HANDLED;
1902         }
1903     }
1904 #endif
1905         
1906     //
1907     // The ISR only disables and acknowledges the RX interrupt
1908     // any further processing is done by DSR. We also need to mask the
1909     // global CAN status interrupt here because the interrupt flag
1910     // in ICR is not cleared yet and may still cause a status 
1911     // interrupt
1912     //
1913     cyg_drv_interrupt_mask(vector);
1914     cyg_drv_interrupt_acknowledge(vector);
1915     LPC2XXX_DBG_PRINT("rx_ISR (%p)\n", (void*) data);
1916
1917     return CYG_ISR_CALL_DSR;
1918 }
1919
1920
1921 //===========================================================================
1922 // High level receive interrupt handler
1923 //===========================================================================
1924 static void lpc2xxx_can_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
1925 {
1926     can_channel  *chan = (can_channel *)data;
1927     cyg_uint32    icr = ICR_RX;
1928       
1929     //
1930     // Read the event, the receive buffer will be released by the
1931     // get_event() function
1932     //
1933     chan->callbacks->rcv_event(chan, &icr); 
1934     LPC2XXX_DBG_PRINT("rx_DSR (%p)\n", (void*) data);
1935     cyg_drv_interrupt_unmask(vector);
1936 }
1937
1938
1939
1940 //===========================================================================
1941 // status ISR handler
1942 //===========================================================================
1943 static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data)
1944 {
1945     //
1946     // Acknowledge and disable the interrupt - any further processing is
1947     // done by the DSR
1948     //    
1949     cyg_drv_interrupt_mask(vector);    
1950     cyg_drv_interrupt_acknowledge(vector);
1951     LPC2XXX_DBG_PRINT("err_ISR\n");
1952     return CYG_ISR_CALL_DSR;    
1953 }
1954
1955
1956 //===========================================================================
1957 // status ISR handler
1958 //===========================================================================
1959 static void lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
1960 {     
1961 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
1962     // If we use acceptance filter we can get LUT error
1963     cyg_uint32 luterr;
1964     cyg_uint8  luterr_chan0 = 0; // Init to avoid warnings
1965     cyg_uint8  luterr_chan1 = 0; // Init to avoid warnings
1966     
1967     // Read LUT error flag
1968     HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, luterr);
1969     
1970     if (luterr & 1)
1971     {
1972         cyg_uint32 lutaddr;
1973         cyg_uint32 eff_sa;
1974         lsc_buf_t  errentry;
1975         
1976         // Read address of failed entry (it clears interrupt flag)
1977         HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, lutaddr);
1978         
1979         // Read address of extended id individual table
1980         HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa); 
1981         
1982         // Read error entry
1983         HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + lutaddr, errentry.dword);
1984         
1985         // If err entry from standard id tables then read two
1986         // controllers numbers
1987         if(lutaddr < eff_sa)
1988         {
1989             // Calc CAN controllers numbers
1990             luterr_chan0 = (cyg_uint8) ACCFILT_STD_GET_CTRL_UPPER(errentry.dword);
1991             
1992             if(errentry.column.lower & ACCFILT_STD_DIS)
1993             {
1994                 luterr_chan1 = luterr_chan0;
1995             }
1996             else 
1997             {
1998                 luterr_chan1 = (cyg_uint8) ACCFILT_STD_GET_CTRL_LOWER(errentry.dword);
1999             }
2000         }
2001         else
2002         {
2003             // Calc CAN controller number 
2004             luterr_chan0 = luterr_chan1 = (cyg_uint8) ACCFILT_EXT_GET_CTRL(errentry.dword);
2005         }
2006     }
2007 #endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
2008
2009     //
2010     // Loop through all channels - we need to do this only if we have more
2011     // than one channel so we can optimize here for single channel
2012     //
2013 #if CYGINT_IO_CAN_CHANNELS > 1 
2014     cyg_uint8 i = 0;     
2015     while (lpc2xxx_global_can_info.active_channels[i])
2016 #endif
2017     {
2018         cyg_uint32 regval;
2019         can_channel *chan = LPC2XXX_GET_CAN_CHANNEL(lpc2xxx_global_can_info, i++);
2020         CAN_DECLARE_INFO(chan);
2021
2022         HAL_READ_UINT32(CAN_CTRL_ICR(info), regval);      
2023 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
2024         // Set ICR_LUT_ERR flag only for controller which cause LUT error
2025         if ((luterr & 1) && ((luterr_chan0 == i) || (luterr_chan1 == i)))
2026         {
2027             regval |= ICR_LUT_ERR;
2028         } 
2029 #endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
2030         regval &= CAN_MISC_INT; // don't care about RX and TX events here
2031         if (regval)
2032         {
2033             chan->callbacks->rcv_event(chan, &regval);
2034         }
2035     } // while (lpc2xxx_global_can_info.active_channels[i])
2036     
2037     LPC2XXX_DBG_PRINT("err_DSR\n");
2038     cyg_drv_interrupt_unmask(vector);
2039 }
2040 #else // #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
2041
2042
2043 //===========================================================================
2044 // Global CAN interrupt handler
2045 //===========================================================================
2046 static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data)
2047 {   
2048     //
2049     // Disable interrupts, the DSR will enable it as soon as it processed
2050     // the current interrupt
2051     //
2052     cyg_drv_interrupt_mask(vector);    
2053     cyg_drv_interrupt_acknowledge(vector);
2054     LPC2XXX_DBG_PRINT("CAN_ISR\n");
2055     return CYG_ISR_CALL_DSR;   
2056 }
2057
2058 //===========================================================================
2059 // Global CAN DSR
2060 //===========================================================================
2061 static void lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2062
2063 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
2064     // If we use acceptance filter we can get LUT error
2065     cyg_uint32 luterr;
2066     cyg_uint8  luterr_chan0 = 0xFF; // Init to avoid warnings
2067     cyg_uint8  luterr_chan1 = 0xFF; // Init to avoid warnings
2068     
2069     // Read LUT error flag
2070     HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, luterr);
2071     
2072     if (luterr & 1)
2073     {
2074         cyg_uint32 lutaddr;
2075         cyg_uint32 eff_sa;
2076         lsc_buf_t  errentry;
2077         
2078         // Read address of failed entry (it clears interrupt flag)
2079         HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, lutaddr);
2080         
2081         // Read address of extended id individual table
2082         HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa); 
2083         
2084         // Read error entry
2085         HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + lutaddr, errentry.dword);
2086         
2087         // If errentry from standard id tables then read two controllers numbers
2088         if(lutaddr < eff_sa)
2089         {
2090             // Calc CAN controllers numbers
2091             luterr_chan0 = (cyg_uint8) ACCFILT_STD_GET_CTRL_UPPER(errentry.dword);
2092             
2093             if(errentry.column.lower & ACCFILT_STD_DIS)
2094             {
2095                 luterr_chan1 = luterr_chan0;
2096             }
2097             else 
2098             {
2099                 luterr_chan1 = (cyg_uint8) ACCFILT_STD_GET_CTRL_LOWER(errentry.dword);
2100             }
2101         }
2102         else
2103         {
2104             // Calc CAN controller number 
2105             luterr_chan0 = luterr_chan1 = (cyg_uint8) ACCFILT_EXT_GET_CTRL(errentry.dword);
2106         }
2107     }
2108 #endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
2109     
2110     //
2111     // Walk through list of active CAN channels and process interrupts
2112     // of all channels - we need to loop only if we have more than one CAN channel so
2113     // we can optimize for single CAN channel here
2114     //
2115 #if CYGINT_IO_CAN_CHANNELS > 1
2116     cyg_uint8 i = 0; 
2117     while (lpc2xxx_global_can_info.active_channels[i])
2118 #endif // CYGINT_IO_CAN_CHANNELS > 1
2119     {
2120         cyg_uint32   icr;
2121         can_channel *chan = LPC2XXX_GET_CAN_CHANNEL(lpc2xxx_global_can_info, i++);
2122         CAN_DECLARE_INFO(chan);
2123         
2124         HAL_READ_UINT32(CAN_CTRL_ICR(info), icr);      // this read clears ICR     
2125 #ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
2126         // Set ICR_LUT_ERR flag only for controller which cause LUT error
2127         if ((luterr_chan0 == i) || (luterr_chan1 == i))
2128         {
2129             icr |= ICR_LUT_ERR;
2130         }
2131 #endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
2132         //
2133         // If TX events are supported then we simply call the rcv_event()
2134         // callback to store the event. If TX events are not supported then
2135         // we only call the rcv_event() function if any other interrupt than
2136         // the TX interrupt was captured
2137         //
2138 #ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT  
2139         if (icr & ~ICR_TX1)
2140 #endif // CYGOPT_IO_CAN_TX_EVENT_SUPPORT 
2141         {
2142             chan->callbacks->rcv_event(chan, &icr); 
2143         }   
2144         //
2145         // If this was an TX interrupt then transmit next message now
2146         //
2147         if (icr & ICR_TX1)
2148         { 
2149             chan->callbacks->xmt_msg(chan, 0); // send next message 
2150         }
2151     } // while (lpc2xxx_global_can_info.active_channels[i])   
2152     LPC2XXX_DBG_PRINT("CAN_DSR\n"); 
2153     cyg_drv_interrupt_unmask(vector);
2154 }
2155 #endif // #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
2156
2157
2158 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
2159 //===========================================================================
2160 // Configure message boxes for reception of any CAN message
2161 //===========================================================================
2162 static void lpc2xxx_can_config_rx_all(can_channel *chan)
2163 {   
2164     lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
2165     //
2166     // First clear all acceptance filter entries and then insert the
2167     // two RX all groups
2168     //
2169     lpc2xxx_can_config_rx_none(chan); 
2170 #ifdef CYGOPT_IO_CAN_STD_CAN_ID
2171     lpc2xxx_can_accfilt_add(info, 0x000, 0x7FF, CYGNUM_CAN_ID_STD);
2172 #endif //  CYGOPT_IO_CAN_STD_CAN_ID
2173 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
2174     lpc2xxx_can_accfilt_add(info, 0x000, 0x1FFFFFFF, CYGNUM_CAN_ID_EXT);
2175 #endif // CYGOPT_IO_CAN_EXT_CAN_ID   
2176   
2177     info->flags  |= INFO_FLAG_RX_ALL;
2178 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
2179     lpc2xxx_can_accfilt_dbg_dump();
2180 #endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
2181 }
2182 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
2183
2184
2185 #ifndef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
2186 //===========================================================================
2187 // Configure message boxes for reception of any CAN message
2188 //===========================================================================
2189 static void lpc2xxx_can_config_rx_all(can_channel *chan)
2190 {   
2191     lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
2192
2193     lpc2xxx_can_accfilt_simple_rx_all();
2194     info->flags  |= INFO_FLAG_RX_ALL;
2195
2196 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
2197     lpc2xxx_can_accfilt_dbg_dump();
2198 #endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
2199 }
2200 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
2201
2202
2203 //---------------------------------------------------------------------------
2204 // EOF can_lpc2xxx.c