]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/drivers/Atmel/at91lib/peripherals/can/can.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / Common / drivers / Atmel / at91lib / peripherals / can / can.c
1 /* ----------------------------------------------------------------------------\r
2  *         ATMEL Microcontroller Software Support \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2008, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 //------------------------------------------------------------------------------\r
31 //         Headers\r
32 //------------------------------------------------------------------------------\r
33 \r
34 #include <board.h>\r
35 #include <pio/pio.h>\r
36 #include <utility/trace.h>\r
37 #include <aic/aic.h>\r
38 #include "can.h"\r
39 \r
40 //------------------------------------------------------------------------------\r
41 //         Local definitions\r
42 //------------------------------------------------------------------------------\r
43 // CAN state\r
44 #define CAN_DISABLED       0\r
45 #define CAN_HALTED         1\r
46 #define CAN_IDLE           2\r
47 #define CAN_SENDING        3\r
48 #define CAN_RECEIVING      4\r
49 \r
50 // MOT: Mailbox Object Type\r
51 #define CAN_MOT_DISABLE    0 // Mailbox is disabled\r
52 #define CAN_MOT_RECEPT     1 // Reception Mailbox\r
53 #define CAN_MOT_RECEPT_OW  2 // Reception mailbox with overwrite\r
54 #define CAN_MOT_TRANSMIT   3 // Transmit mailbox\r
55 #define CAN_MOT_CONSUMER   4 // Consumer mailbox\r
56 #define CAN_MOT_PRODUCER   5 // Producer mailbox\r
57 \r
58 //------------------------------------------------------------------------------\r
59 //         Local variables\r
60 //------------------------------------------------------------------------------\r
61 #if defined (PINS_CAN_TRANSCEIVER_TXD)\r
62 static const Pin pins_can_transceiver_txd[] = {PINS_CAN_TRANSCEIVER_TXD};\r
63 #endif\r
64 #if defined (PINS_CAN_TRANSCEIVER_RXD)\r
65 static const Pin pins_can_transceiver_rxd[] = {PINS_CAN_TRANSCEIVER_RXD};\r
66 #endif\r
67 static const Pin pin_can_transceiver_rs   = PIN_CAN_TRANSCEIVER_RS;\r
68 #if defined (PIN_CAN_TRANSCEIVER_RXEN)\r
69 static const Pin pin_can_transceiver_rxen = PIN_CAN_TRANSCEIVER_RXEN;\r
70 #endif\r
71 \r
72 static CanTransfer *pCAN0Transfer=NULL;\r
73 #ifdef AT91C_BASE_CAN1\r
74 static CanTransfer *pCAN1Transfer=NULL;\r
75 #endif\r
76 \r
77 //------------------------------------------------------------------------------\r
78 //         Local functions\r
79 //------------------------------------------------------------------------------\r
80 \r
81 //------------------------------------------------------------------------------\r
82 /// CAN Error Detection\r
83 /// \param status     error type\r
84 /// \param can_number can nulber\r
85 //------------------------------------------------------------------------------\r
86 static void CAN_ErrorHandling( unsigned int status, unsigned char can_number)\r
87 {\r
88     if( (status&AT91C_CAN_ERRA) ==  AT91C_CAN_ERRA) {\r
89         trace_LOG( trace_ERROR, "-E- (CAN) CAN is in active Error Active mode\n\r");\r
90     }\r
91     else if( (status&AT91C_CAN_ERRP) ==  AT91C_CAN_ERRP) {\r
92         trace_LOG( trace_ERROR, "-E- (CAN) CAN is in Error Passive mode\n\r");\r
93     }\r
94     else if( (status&AT91C_CAN_BOFF) ==  AT91C_CAN_BOFF) {\r
95         trace_LOG( trace_ERROR, "-E- (CAN) CAN is in Buff Off mode\n\r");\r
96         // CAN reset\r
97         trace_LOG( trace_ERROR, "-E- (CAN) CAN%d reset\n\r", can_number);\r
98         // CAN Controller Disable\r
99         if (can_number == 0) {\r
100             AT91C_BASE_CAN0->CAN_MR &= ~AT91C_CAN_CANEN;\r
101             // CAN Controller Enable\r
102             AT91C_BASE_CAN0->CAN_MR |= AT91C_CAN_CANEN;\r
103         }\r
104 #ifdef AT91C_BASE_CAN1\r
105         else if (can_number == 1) {\r
106             AT91C_BASE_CAN1->CAN_MR &= ~AT91C_CAN_CANEN;\r
107             // CAN Controller Enable\r
108             AT91C_BASE_CAN1->CAN_MR |= AT91C_CAN_CANEN;\r
109         }\r
110 #endif\r
111     }\r
112 \r
113     // Error for Frame dataframe\r
114     // CRC error\r
115     if( (status&AT91C_CAN_CERR) ==  AT91C_CAN_CERR) {\r
116         trace_LOG( trace_ERROR, "-E- (CAN) CRC Error\n\r");\r
117     }\r
118     // Bit-stuffing error\r
119     else if( (status&AT91C_CAN_SERR) ==  AT91C_CAN_SERR) {\r
120         trace_LOG( trace_ERROR, "-E- (CAN) Stuffing Error\n\r");\r
121     }\r
122     // Bit error\r
123     else if( (status&AT91C_CAN_BERR) ==  AT91C_CAN_BERR) {\r
124         trace_LOG( trace_ERROR, "-E- (CAN) Bit Error\n\r");\r
125     }\r
126     // Form error\r
127     else if( (status&AT91C_CAN_FERR) ==  AT91C_CAN_FERR) {\r
128         trace_LOG( trace_ERROR, "-E- (CAN) Form Error\n\r");\r
129     }\r
130     // Acknowledgment error\r
131     else if( (status&AT91C_CAN_AERR) ==  AT91C_CAN_AERR) {\r
132         trace_LOG( trace_ERROR, "-E- (CAN) Acknowledgment Error\n\r");\r
133     }\r
134 \r
135     // Error interrupt handler\r
136     // Represent the current status of the CAN bus and are not latched.\r
137     // See CAN, par. Error Interrupt Handler\r
138     // AT91C_CAN_WARN\r
139     // AT91C_CAN_ERRA\r
140 }\r
141 \r
142 //------------------------------------------------------------------------------\r
143 // Generic CAN Interrupt handler\r
144 /// \param can_number can nulber\r
145 //------------------------------------------------------------------------------\r
146 static void CAN_Handler( unsigned char can_number ) \r
147 {\r
148     AT91PS_CAN base_can;\r
149     AT91PS_CAN_MB CAN_Mailbox;\r
150 \r
151     unsigned int status;\r
152     unsigned int can_msr;\r
153     unsigned int* pCan_mcr;\r
154     unsigned int message_mode;\r
155     unsigned char numMailbox;\r
156     unsigned char state0;\r
157     unsigned char state1;\r
158 \r
159     if( can_number == 0 ) {\r
160         base_can = AT91C_BASE_CAN0;\r
161         CAN_Mailbox = AT91C_BASE_CAN0_MB0;\r
162         state0 = pCAN0Transfer->state;\r
163     }\r
164 #ifdef AT91C_BASE_CAN1\r
165     else {\r
166         base_can = AT91C_BASE_CAN1;\r
167         CAN_Mailbox = AT91C_BASE_CAN1_MB0;\r
168         state1 = pCAN1Transfer->state;\r
169     }\r
170 #endif\r
171     status = (base_can->CAN_SR) & (base_can->CAN_IMR);\r
172     base_can->CAN_IDR = status;\r
173 \r
174     trace_LOG( trace_DEBUG, "CAN0 status=0x%X\n\r", status);\r
175     if(status & AT91C_CAN_WAKEUP) {\r
176         if( can_number == 0 ) {\r
177             pCAN0Transfer->test_can = AT91C_TEST_OK;\r
178             pCAN0Transfer->state = CAN_IDLE;\r
179         }\r
180 #ifdef AT91C_BASE_CAN1\r
181         else {\r
182             pCAN1Transfer->test_can = AT91C_TEST_OK;\r
183             pCAN1Transfer->state = CAN_IDLE;\r
184         }\r
185 #endif\r
186     }\r
187     // Mailbox event ?\r
188     else if ((status&0x0000FFFF) != 0) {\r
189         trace_LOG( trace_DEBUG, "Mailbox event\n\r");\r
190 \r
191         // Handle Mailbox interrupts\r
192         for (numMailbox = 0; numMailbox < NUM_MAILBOX_MAX; numMailbox++) {\r
193 \r
194             can_msr = *(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x10+(0x20*numMailbox)));\r
195             if ((AT91C_CAN_MRDY & can_msr) == AT91C_CAN_MRDY) {\r
196                 // Mailbox object type\r
197                 message_mode =  ((*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x00+(0x20*numMailbox))))>>24)&0x7;\r
198                 trace_LOG( trace_DEBUG, "message_mode 0x%X\n\r", message_mode);\r
199                 trace_LOG( trace_DEBUG, "numMailbox 0x%X\n\r", numMailbox);\r
200 \r
201                 if( message_mode == 0 ) {\r
202                     trace_LOG( trace_ERROR, "-E-Error in MOT\n\r");\r
203                 }\r
204                 else if( ( message_mode == CAN_MOT_RECEPT ) \r
205                       || ( message_mode == CAN_MOT_RECEPT_OW ) \r
206                       || ( message_mode == CAN_MOT_PRODUCER ) ) {\r
207                     trace_LOG( trace_DEBUG, "Mailbox is in RECEPTION\n\r");\r
208                     trace_LOG( trace_DEBUG, "Length 0x%X\n\r", (can_msr>>16)&0xF);\r
209                     trace_LOG( trace_DEBUG, "CAN_MB_MID 0x%X\n\r", ((*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x08+(0x20*numMailbox)))&AT91C_CAN_MIDvA)>>18));\r
210 \r
211                     trace_LOG( trace_DEBUG, "can_number %d\n\r", can_number);\r
212                     if( can_number == 0 ) {\r
213                         //CAN_MB_MDLx\r
214                         pCAN0Transfer->data_low_reg = \r
215                            (*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x14+(0x20*numMailbox))));\r
216                         //CAN_MB_MDHx\r
217                         pCAN0Transfer->data_high_reg = \r
218                            (*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x18+(0x20*numMailbox))));\r
219                         pCAN0Transfer->size = (can_msr>>16)&0xF;\r
220                         pCAN0Transfer->mailbox_number = numMailbox;\r
221                         state0 = CAN_IDLE;\r
222                     }\r
223 #ifdef AT91C_BASE_CAN1\r
224                     else {\r
225                         //CAN_MB_MDLx\r
226                         pCAN1Transfer->data_low_reg = \r
227                            (*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x14+(0x20*numMailbox))));\r
228                         //CAN_MB_MDHx\r
229                         pCAN1Transfer->data_high_reg = \r
230                            (*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x18+(0x20*numMailbox))));\r
231                         pCAN1Transfer->size = (can_msr>>16)&0xF;\r
232                         pCAN1Transfer->mailbox_number = numMailbox;\r
233                         state1 = CAN_IDLE;\r
234                     }\r
235 #endif\r
236                     // Message Data has been received\r
237                     pCan_mcr = (unsigned int*)((unsigned int)CAN_Mailbox+0x1C+(0x20*numMailbox));\r
238                     *pCan_mcr = AT91C_CAN_MTCR;\r
239 \r
240                 }\r
241                 else {\r
242                     trace_LOG( trace_DEBUG, "Mailbox is in TRANSMIT\n\r");\r
243                     trace_LOG( trace_DEBUG, "Length 0x%X\n\r", (can_msr>>16)&0xF);\r
244                     trace_LOG( trace_DEBUG, "can_number %d\n\r", can_number);\r
245                     if( can_number == 0 ) {\r
246                         state0 = CAN_IDLE;\r
247                     }\r
248                     else {\r
249                         state1 = CAN_IDLE;\r
250                     }\r
251                 }\r
252             }\r
253         }\r
254         if( can_number == 0 ) {\r
255             pCAN0Transfer->state = state0;\r
256         }\r
257 #ifdef AT91C_BASE_CAN1\r
258         else {\r
259             pCAN1Transfer->state = state1;\r
260         }\r
261 #endif\r
262     }\r
263     if ((status&0xFFCF0000) != 0) {\r
264         CAN_ErrorHandling(status, 0);\r
265     }\r
266 }\r
267 \r
268 //------------------------------------------------------------------------------\r
269 /// CAN 0 Interrupt handler\r
270 //------------------------------------------------------------------------------\r
271 static void CAN0_Handler(void)\r
272 {\r
273     CAN_Handler( 0 );\r
274 }\r
275 \r
276 //------------------------------------------------------------------------------\r
277 /// CAN 1 Interrupt handler\r
278 //------------------------------------------------------------------------------\r
279 #if defined AT91C_BASE_CAN1\r
280 static void CAN1_Handler(void)\r
281 {\r
282     CAN_Handler( 1 );\r
283 }\r
284 #endif\r
285 \r
286 //------------------------------------------------------------------------------\r
287 //         Global functions\r
288 //------------------------------------------------------------------------------\r
289 \r
290 //------------------------------------------------------------------------------\r
291 /// Configure the corresponding mailbox\r
292 /// \param pTransfer can transfer structure\r
293 //------------------------------------------------------------------------------\r
294 void CAN_InitMailboxRegisters( CanTransfer *pTransfer )\r
295 {\r
296     AT91PS_CAN    base_can;\r
297     AT91PS_CAN_MB CAN_Mailbox;\r
298 \r
299     if( pTransfer->can_number == 0 ) {\r
300         base_can = AT91C_BASE_CAN0;\r
301         CAN_Mailbox = AT91C_BASE_CAN0_MB0;\r
302     }\r
303 #ifdef AT91C_BASE_CAN1\r
304     else {\r
305         base_can = AT91C_BASE_CAN1;\r
306         CAN_Mailbox = AT91C_BASE_CAN1_MB0;\r
307     }\r
308 #endif\r
309     CAN_Mailbox = (AT91PS_CAN_MB)((unsigned int)CAN_Mailbox+(unsigned int)(0x20*pTransfer->mailbox_number));\r
310 \r
311     pTransfer->mailbox_in_use |= 1<<(pTransfer->mailbox_number);\r
312     // MailBox Control Register\r
313     CAN_Mailbox->CAN_MB_MCR = 0x0;\r
314     // MailBox Mode Register\r
315     CAN_Mailbox->CAN_MB_MMR = 0x00;\r
316     // CAN Message Acceptance Mask Register\r
317     CAN_Mailbox->CAN_MB_MAM = pTransfer->acceptance_mask_reg;\r
318     // MailBox ID Register\r
319     // Disable the mailbox before writing to CAN_MIDx registers\r
320     if( pTransfer->identifier != 0 ) {\r
321         CAN_Mailbox->CAN_MB_MAM |= AT91C_CAN_MIDE;\r
322         CAN_Mailbox->CAN_MB_MID = pTransfer->identifier;\r
323     }\r
324     else {\r
325         CAN_Mailbox->CAN_MB_MAM &= ~AT91C_CAN_MIDE;\r
326     }\r
327     // MailBox Mode Register\r
328     CAN_Mailbox->CAN_MB_MMR = pTransfer->mode_reg;\r
329     // MailBox Data Low Register\r
330     CAN_Mailbox->CAN_MB_MDL = pTransfer->data_low_reg;\r
331     // MailBox Data High Register\r
332     CAN_Mailbox->CAN_MB_MDH = pTransfer->data_high_reg;\r
333     // MailBox Control Register\r
334     CAN_Mailbox->CAN_MB_MCR = pTransfer->control_reg;\r
335 }\r
336 \r
337 //------------------------------------------------------------------------------\r
338 /// Reset the MBx\r
339 //------------------------------------------------------------------------------\r
340 void CAN_ResetAllMailbox( void )\r
341 {\r
342     unsigned char i;\r
343   \r
344 #if defined (AT91C_BASE_CAN0_MB0)\r
345     CAN_ResetTransfer( pCAN0Transfer );\r
346     for( i=0; i<8; i++ ) {\r
347         pCAN0Transfer->can_number = 0;\r
348         pCAN0Transfer->mailbox_number = i;\r
349         pCAN0Transfer->mode_reg = AT91C_CAN_MOT_DIS;\r
350         pCAN0Transfer->acceptance_mask_reg = 0;\r
351         pCAN0Transfer->identifier = 0;\r
352         pCAN0Transfer->data_low_reg = 0x00000000;\r
353         pCAN0Transfer->data_high_reg = 0x00000000;\r
354         pCAN0Transfer->control_reg = 0x00000000;\r
355         CAN_InitMailboxRegisters( pCAN0Transfer );\r
356     }\r
357 #endif\r
358 #if defined (AT91C_BASE_CAN0_MB8)\r
359     for( i=0; i<8; i++ ) {\r
360         pCAN0Transfer->can_number = 0;\r
361         pCAN0Transfer->mailbox_number = i+8;\r
362         pCAN0Transfer->mode_reg = AT91C_CAN_MOT_DIS;\r
363         pCAN0Transfer->acceptance_mask_reg = 0;\r
364         pCAN0Transfer->identifier = 0;\r
365         pCAN0Transfer->data_low_reg = 0x00000000;\r
366         pCAN0Transfer->data_high_reg = 0x00000000;\r
367         pCAN0Transfer->control_reg = 0x00000000;\r
368         CAN_InitMailboxRegisters( pCAN0Transfer );\r
369     }\r
370 #endif\r
371 \r
372 #if defined (AT91C_BASE_CAN1_MB0)\r
373     if( pCAN1Transfer != NULL ) {\r
374         CAN_ResetTransfer( pCAN1Transfer );\r
375         for( i=0; i<8; i++ ) {\r
376             pCAN1Transfer->can_number = 1;\r
377             pCAN1Transfer->mailbox_number = i;\r
378             pCAN1Transfer->mode_reg = AT91C_CAN_MOT_DIS;\r
379             pCAN1Transfer->acceptance_mask_reg = 0;\r
380             pCAN1Transfer->identifier = 0;\r
381             pCAN1Transfer->data_low_reg = 0x00000000;\r
382             pCAN1Transfer->data_high_reg = 0x00000000;\r
383             pCAN1Transfer->control_reg = 0x00000000;\r
384             CAN_InitMailboxRegisters( pCAN1Transfer );\r
385         }\r
386     }\r
387 #endif\r
388 #if defined (AT91C_BASE_CAN1_MB8)\r
389     if( pCAN1Transfer != NULL ) {\r
390         for( i=0; i<8; i++ ) {\r
391             pCAN1Transfer->can_number = 1;\r
392             pCAN1Transfer->mailbox_number = i+8;\r
393             pCAN1Transfer->mode_reg = AT91C_CAN_MOT_DIS;\r
394             pCAN1Transfer->acceptance_mask_reg = 0;\r
395             pCAN1Transfer->identifier = 0;\r
396             pCAN1Transfer->data_low_reg = 0x00000000;\r
397             pCAN1Transfer->data_high_reg = 0x00000000;\r
398             pCAN1Transfer->control_reg = 0x00000000;\r
399             CAN_InitMailboxRegisters( pCAN1Transfer );\r
400         }\r
401     }\r
402 #endif\r
403 \r
404 }\r
405 \r
406 //------------------------------------------------------------------------------\r
407 /// CAN reset Transfer descriptor\r
408 /// \param pTransfer can transfer structure\r
409 //------------------------------------------------------------------------------\r
410 void CAN_ResetTransfer( CanTransfer *pTransfer )\r
411 {\r
412     pTransfer->state = CAN_IDLE;\r
413     pTransfer->can_number = 0;\r
414     pTransfer->mailbox_number = 0;\r
415     pTransfer->test_can = 0;\r
416     pTransfer->mode_reg = 0;\r
417     pTransfer->acceptance_mask_reg = 0;\r
418     pTransfer->identifier = 0;\r
419     pTransfer->data_low_reg = 0;\r
420     pTransfer->data_high_reg = 0;\r
421     pTransfer->control_reg = 0;\r
422     pTransfer->mailbox_in_use = 0;\r
423     pTransfer->size = 0;\r
424 }\r
425 \r
426 //------------------------------------------------------------------------------\r
427 /// Wait for CAN synchronisation\r
428 /// \return return 1 for good initialisation, otherwise return 0\r
429 //------------------------------------------------------------------------------\r
430 static unsigned char CAN_Synchronisation( void )\r
431 {\r
432     unsigned int tick=0;\r
433 \r
434     trace_LOG( trace_INFO, "CAN_Synchronisation\n\r");\r
435 \r
436     pCAN0Transfer->test_can = AT91C_TEST_NOK;\r
437 #ifdef AT91C_BASE_CAN1\r
438     if( pCAN1Transfer != NULL ) {\r
439         pCAN1Transfer->test_can = AT91C_TEST_NOK;\r
440     }\r
441 #endif\r
442     // Enable CAN and Wait for WakeUp Interrupt\r
443     AT91C_BASE_CAN0->CAN_IER = AT91C_CAN_WAKEUP;\r
444     // CAN Controller Enable\r
445     AT91C_BASE_CAN0->CAN_MR = AT91C_CAN_CANEN;\r
446     // Enable Autobaud/Listen mode\r
447     // dangerous, CAN not answer in this mode\r
448 \r
449      while( (pCAN0Transfer->test_can != AT91C_TEST_OK)\r
450          && (tick < AT91C_CAN_TIMEOUT) ) {\r
451         tick++;\r
452     }\r
453     if (tick == AT91C_CAN_TIMEOUT) {\r
454         trace_LOG( trace_ERROR, "-E- CAN0 Initialisations FAILED\n\r");\r
455         return 0;\r
456     } else {\r
457         trace_LOG( trace_INFO, "-I- CAN0 Initialisations Completed\n\r");\r
458     }\r
459 \r
460 #if defined AT91C_BASE_CAN1\r
461     if( pCAN1Transfer != NULL ) {\r
462         AT91C_BASE_CAN1->CAN_IER = AT91C_CAN_WAKEUP;\r
463         // CAN Controller Enable\r
464         AT91C_BASE_CAN1->CAN_MR = AT91C_CAN_CANEN;\r
465 \r
466         tick = 0;\r
467         // Wait for WAKEUP flag raising <=> 11-recessive-bit were scanned by the transceiver\r
468         while( ((pCAN1Transfer->test_can != AT91C_TEST_OK)) \r
469             && (tick < AT91C_CAN_TIMEOUT) ) {\r
470             tick++;\r
471         }\r
472 \r
473         if (tick == AT91C_CAN_TIMEOUT) {\r
474             trace_LOG( trace_ERROR, "-E- CAN1 Initialisations FAILED\n\r");\r
475             return 0;\r
476         } else {\r
477             trace_LOG( trace_INFO, "-I- CAN1 Initialisations Completed\n\r");\r
478         }\r
479     }\r
480 #endif\r
481     return 1;\r
482 }\r
483 \r
484 //------------------------------------------------------------------------------\r
485 /// Write a CAN transfer\r
486 /// \param pTransfer can transfer structure\r
487 /// \return return CAN_STATUS_SUCCESS if command passed, otherwise \r
488 ///         return CAN_STATUS_LOCKED\r
489 //------------------------------------------------------------------------------\r
490 unsigned char CAN_Write( CanTransfer *pTransfer )\r
491 {\r
492     AT91PS_CAN base_can;\r
493 \r
494     if (pTransfer->state == CAN_RECEIVING)  {\r
495         pTransfer->state = CAN_IDLE;\r
496     }\r
497 \r
498     if (pTransfer->state != CAN_IDLE)  {\r
499         return CAN_STATUS_LOCKED;\r
500     }\r
501 \r
502     trace_LOG( trace_DEBUG, "CAN_Write\n\r");\r
503     pTransfer->state = CAN_SENDING;\r
504     if( pTransfer->can_number == 0 ) {\r
505         base_can = AT91C_BASE_CAN0;\r
506     }\r
507 #ifdef AT91C_BASE_CAN1\r
508     else {\r
509         base_can = AT91C_BASE_CAN1;\r
510     }\r
511 #endif\r
512     base_can->CAN_TCR = pTransfer->mailbox_in_use;\r
513     base_can->CAN_IER = pTransfer->mailbox_in_use;\r
514 \r
515     return CAN_STATUS_SUCCESS;\r
516 \r
517 }\r
518 \r
519 \r
520 //------------------------------------------------------------------------------\r
521 /// Read a CAN transfer\r
522 /// \param pTransfer can transfer structure\r
523 /// \return return CAN_STATUS_SUCCESS if command passed, otherwise \r
524 ///         return CAN_STATUS_LOCKED\r
525 //------------------------------------------------------------------------------\r
526 unsigned char CAN_Read( CanTransfer *pTransfer )\r
527 {\r
528     AT91PS_CAN base_can;\r
529 \r
530     if (pTransfer->state != CAN_IDLE)  {\r
531         return CAN_STATUS_LOCKED;\r
532     }\r
533 \r
534     trace_LOG( trace_DEBUG, "CAN_Read\n\r");\r
535     pTransfer->state = CAN_RECEIVING;\r
536 \r
537 \r
538     if( pTransfer->can_number == 0 ) {\r
539         base_can = AT91C_BASE_CAN0;\r
540     }\r
541 #ifdef AT91C_BASE_CAN1\r
542     else {\r
543         base_can = AT91C_BASE_CAN1;\r
544     }\r
545 #endif\r
546     // enable interrupt\r
547     base_can->CAN_IER = pTransfer->mailbox_in_use;\r
548 \r
549     return CAN_STATUS_SUCCESS;\r
550 }\r
551 \r
552 //------------------------------------------------------------------------------\r
553 /// Test if CAN is in IDLE state\r
554 /// \param pTransfer can transfer structure\r
555 /// \return return 0 if CAN is in IDLE, otherwise return 1\r
556 //------------------------------------------------------------------------------\r
557 unsigned char CAN_IsInIdle( CanTransfer *pTransfer )\r
558 {\r
559   return( pTransfer->state != CAN_IDLE );\r
560 }\r
561 \r
562 //------------------------------------------------------------------------------\r
563 /// Basic CAN test without Interrupt\r
564 //------------------------------------------------------------------------------\r
565 void CAN_BasicTestSuiteWithoutInterrupt(void)\r
566 {\r
567 #if defined AT91C_BASE_CAN1\r
568     unsigned int status;\r
569     unsigned int tick=0;\r
570 \r
571     trace_LOG( trace_INFO, "Without Interrupt ");\r
572     trace_LOG( trace_INFO, "CAN0 Mailbox 0 transmitting to CAN1 Mailbox 0\n\r");\r
573     // Init CAN0 Mailbox 0, transmit\r
574     CAN_ResetTransfer( pCAN0Transfer );\r
575     pCAN0Transfer->can_number = 0;\r
576     pCAN0Transfer->mailbox_number = 0;\r
577     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;\r
578     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
579     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x07<<18);\r
580     pCAN0Transfer->data_low_reg = 0x11223344;\r
581     pCAN0Transfer->data_high_reg = 0x01234567;\r
582     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16));\r
583     CAN_InitMailboxRegisters( pCAN0Transfer );\r
584 \r
585     // Init CAN1 Mailbox 0, receive, \r
586     CAN_ResetTransfer( pCAN1Transfer );\r
587     pCAN1Transfer->can_number = 1;\r
588     pCAN1Transfer->mailbox_number = 0;\r
589     pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RX;\r
590     pCAN1Transfer->acceptance_mask_reg = AT91C_CAN_MIDvA | AT91C_CAN_MIDvB;\r
591     pCAN1Transfer->identifier = AT91C_CAN_MIDvA & (0x07<<18);\r
592     pCAN1Transfer->data_low_reg = 0x00000000;\r
593     pCAN1Transfer->data_high_reg = 0x00000000;\r
594     pCAN1Transfer->control_reg = 0x00000000;\r
595     CAN_InitMailboxRegisters( pCAN1Transfer );\r
596 \r
597     // Transfer Request for Mailbox 0\r
598     AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB0;\r
599 \r
600     tick = 0;\r
601     do {\r
602         // CAN Message Status Register\r
603         status = AT91C_BASE_CAN0_MB0->CAN_MB_MSR;\r
604     }\r
605     while( !(status & AT91C_CAN_MRDY) && (++tick < AT91C_CAN_TIMEOUT) );\r
606 \r
607     if (tick == AT91C_CAN_TIMEOUT) {\r
608         trace_LOG( trace_ERROR, "-E- Test FAILED\n\r");\r
609     } \r
610     else {\r
611         trace_LOG( trace_DEBUG, "-I- Transfer completed: CAN1 Mailbox 0 MRDY flag has raised\n\r");\r
612         if( AT91C_BASE_CAN0_MB0->CAN_MB_MDL != AT91C_BASE_CAN1_MB0->CAN_MB_MDL ) {\r
613             trace_LOG( trace_ERROR, "-E- Data Corrupted\n\r");\r
614         }\r
615         else if( AT91C_BASE_CAN0_MB0->CAN_MB_MDH != AT91C_BASE_CAN1_MB0->CAN_MB_MDH ) {\r
616             trace_LOG( trace_ERROR, "-E- Data Corrupted\n\r");\r
617         }\r
618         else {\r
619             trace_LOG( trace_INFO, "Test passed\n\r");\r
620         }\r
621     }\r
622 \r
623     CAN_ResetAllMailbox();\r
624 \r
625     trace_LOG( trace_INFO, "Without Interrupt ");\r
626     trace_LOG( trace_INFO, "CAN0 Mailboxes 1 & 2 transmitting to CAN1 Mailbox 15\n\r");\r
627     // Init CAN0 Mailbox 1, transmit\r
628     CAN_ResetTransfer( pCAN0Transfer );\r
629     pCAN0Transfer->can_number = 0;\r
630     pCAN0Transfer->mailbox_number = 1;\r
631     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;\r
632     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
633     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x09<<18);      // ID 9\r
634     pCAN0Transfer->data_low_reg = 0xAABBCCDD;\r
635     pCAN0Transfer->data_high_reg = 0xCAFEDECA;\r
636     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code\r
637     CAN_InitMailboxRegisters( pCAN0Transfer );\r
638 \r
639     // Init CAN0 Mailbox 2, transmit\r
640     pCAN0Transfer->can_number = 0;\r
641     pCAN0Transfer->mailbox_number = 2;\r
642     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | (AT91C_CAN_PRIOR-(1<<16));\r
643     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
644     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0A<<18);      // ID 10\r
645     pCAN0Transfer->data_low_reg = 0x55667788;\r
646     pCAN0Transfer->data_high_reg = 0x99AABBCC;\r
647     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code\r
648     CAN_InitMailboxRegisters( pCAN0Transfer );\r
649 \r
650     // Init CAN1 Mailbox 15, reception with overwrite\r
651     CAN_ResetTransfer( pCAN1Transfer );\r
652     pCAN1Transfer->can_number = 1;\r
653     pCAN1Transfer->mailbox_number = 15;\r
654     pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RXOVERWRITE;\r
655     pCAN1Transfer->acceptance_mask_reg = 0;\r
656     pCAN1Transfer->identifier = 0x0;\r
657     pCAN1Transfer->data_low_reg = 0x00000000;\r
658     pCAN1Transfer->data_high_reg = 0x00000000;\r
659     pCAN1Transfer->control_reg = 0x00000000;\r
660     CAN_InitMailboxRegisters( pCAN1Transfer );\r
661 \r
662     // Ask Transmissions on Mailbox 1 & 2 --> AT91C_CAN_MRDY & AT91C_CAN_MMI raises for Mailbox 15 CAN_MB_SR\r
663     AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB1 | AT91C_CAN_MB2;\r
664     \r
665     // Wait for Last Transmit Mailbox\r
666     tick = 0;\r
667     do  {\r
668         status = AT91C_BASE_CAN1_MB15->CAN_MB_MSR;\r
669     }\r
670     while( !(status & AT91C_CAN_MMI) && (++tick < AT91C_CAN_TIMEOUT) );\r
671 \r
672     if (tick == AT91C_CAN_TIMEOUT) {\r
673     }\r
674     else {\r
675         trace_LOG( trace_DEBUG, "-I- Transfer completed: CAN1 Mailbox 15 MRDY and MMI flags have raised\n\r");\r
676         if( AT91C_BASE_CAN0_MB1->CAN_MB_MDL != AT91C_BASE_CAN1_MB15->CAN_MB_MDL ) {\r
677             trace_LOG( trace_ERROR, "-E- Data Corrupted\n\r");\r
678         }\r
679         else if( AT91C_BASE_CAN0_MB1->CAN_MB_MDH != AT91C_BASE_CAN1_MB15->CAN_MB_MDH ) {\r
680             trace_LOG( trace_ERROR, "-E- Data Corrupted\n\r");\r
681         }\r
682         else {\r
683             trace_LOG( trace_INFO, "Test passed\n\r");\r
684         }\r
685     }\r
686 \r
687     CAN_ResetAllMailbox();\r
688     trace_LOG( trace_INFO, "Without Interrupt ");\r
689     trace_LOG( trace_INFO, "CAN0 Mailboxes 1 & 2 transmitting to CAN1 Mailbox 15\n\r");\r
690     // Init CAN0 Mailbox 1, transmit\r
691     CAN_ResetTransfer( pCAN0Transfer );\r
692     pCAN0Transfer->can_number = 0;\r
693     pCAN0Transfer->mailbox_number = 1;\r
694     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;\r
695     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
696     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x09<<18);      // ID 9\r
697     pCAN0Transfer->data_low_reg = 0xAABBCCDD;\r
698     pCAN0Transfer->data_high_reg = 0xCAFEDECA;\r
699     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code\r
700     CAN_InitMailboxRegisters( pCAN0Transfer );\r
701 \r
702     // Init CAN0 Mailbox 2, transmit\r
703     pCAN0Transfer->can_number = 0;\r
704     pCAN0Transfer->mailbox_number = 2;\r
705     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | (AT91C_CAN_PRIOR-(1<<16));\r
706     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
707     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0A<<18);      // ID 10\r
708     pCAN0Transfer->data_low_reg = 0x55667788;\r
709     pCAN0Transfer->data_high_reg = 0x99AABBCC;\r
710     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code\r
711     CAN_InitMailboxRegisters( pCAN0Transfer );\r
712 \r
713     // Init CAN1 Mailbox 15, reception with overwrite\r
714     CAN_ResetTransfer( pCAN1Transfer );\r
715     pCAN1Transfer->can_number = 1;\r
716     pCAN1Transfer->mailbox_number = 15;\r
717     pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RX;\r
718     pCAN1Transfer->acceptance_mask_reg = 0;\r
719     pCAN1Transfer->identifier = 0x0;\r
720     pCAN1Transfer->data_low_reg = 0x00000000;\r
721     pCAN1Transfer->data_high_reg = 0x00000000;\r
722     pCAN1Transfer->control_reg = 0x00000000;\r
723     CAN_InitMailboxRegisters( pCAN1Transfer );\r
724 \r
725     // Ask Transmissions on Mailbox 1 & 2 --> AT91C_CAN_MRDY & AT91C_CAN_MMI raises for Mailbox 15 CAN_MB_SR\r
726     AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB1 | AT91C_CAN_MB2;\r
727     \r
728     // Wait for Last Transmit Mailbox\r
729     tick = 0;\r
730     do  {\r
731         status = AT91C_BASE_CAN1_MB15->CAN_MB_MSR;\r
732     }\r
733     while( !(status & AT91C_CAN_MMI) && (++tick < AT91C_CAN_TIMEOUT) );\r
734 \r
735     if (tick == AT91C_CAN_TIMEOUT) {\r
736     trace_LOG( trace_ERROR, "-E- Test FAILED\n\r");\r
737     }\r
738     else {\r
739         trace_LOG( trace_DEBUG, "Transfer completed: CAN1 Mailbox 15 MRDY and MMI flags have raised\n\r");\r
740         trace_LOG( trace_DEBUG, "MB_MDL: 0x%X\n\r", AT91C_BASE_CAN1_MB15->CAN_MB_MDL);\r
741         trace_LOG( trace_DEBUG, "MB_MDLH: 0x%X\n\r", AT91C_BASE_CAN1_MB15->CAN_MB_MDH);\r
742         if( AT91C_BASE_CAN0_MB2->CAN_MB_MDL != AT91C_BASE_CAN1_MB15->CAN_MB_MDL ) {\r
743             trace_LOG( trace_ERROR, "-E- Data Corrupted\n\r");\r
744         }\r
745         else if( AT91C_BASE_CAN0_MB2->CAN_MB_MDH != AT91C_BASE_CAN1_MB15->CAN_MB_MDH ) {\r
746             trace_LOG( trace_ERROR, "-E- Data Corrupted\n\r");\r
747         }\r
748         else {\r
749             trace_LOG( trace_INFO, "Test passed\n\r");\r
750         }\r
751     }\r
752 \r
753     CAN_ResetAllMailbox();\r
754     trace_LOG( trace_INFO, "Without Interrupt ");\r
755     trace_LOG( trace_INFO, "CAN0 Mailbox 3 asking for CAN1 Mailbox 3 transmission\n\r");\r
756     // Init CAN0 Mailbox 3, consumer mailbox\r
757     // Sends a remote frame and waits for an answer\r
758     CAN_ResetTransfer( pCAN0Transfer );\r
759     pCAN0Transfer->can_number = 0;\r
760     pCAN0Transfer->mailbox_number = 3;\r
761     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_CONSUMER | AT91C_CAN_PRIOR;\r
762     pCAN0Transfer->acceptance_mask_reg = AT91C_CAN_MIDvA | AT91C_CAN_MIDvB;\r
763     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0B<<18);     // ID 11\r
764     pCAN0Transfer->data_low_reg = 0x00000000;\r
765     pCAN0Transfer->data_high_reg = 0x00000000;\r
766     pCAN0Transfer->control_reg = 0x00000000;\r
767     CAN_InitMailboxRegisters( pCAN0Transfer );\r
768 \r
769     // Init CAN1 Mailbox 3, porducer mailbox\r
770     // Waits to receive a Remote Frame before sending its contents\r
771     CAN_ResetTransfer( pCAN1Transfer );\r
772     pCAN1Transfer->can_number = 1;\r
773     pCAN1Transfer->mailbox_number = 3;\r
774     pCAN1Transfer->mode_reg = AT91C_CAN_MOT_PRODUCER | AT91C_CAN_PRIOR;\r
775     pCAN1Transfer->acceptance_mask_reg = 0;\r
776     pCAN1Transfer->identifier = AT91C_CAN_MIDvA & (0x0B<<18);     // ID 11\r
777     pCAN1Transfer->data_low_reg = 0xEEDDFF00;\r
778     pCAN1Transfer->data_high_reg = 0x34560022;\r
779     pCAN1Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16));\r
780     CAN_InitMailboxRegisters( pCAN1Transfer );\r
781 \r
782     // Ask Transmissions on Mailbox 3 --> AT91C_CAN_MRDY raises for Mailbox 3 CAN_MB_SR\r
783     AT91C_BASE_CAN1->CAN_TCR = AT91C_CAN_MB3;\r
784     AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB3;\r
785 \r
786     // Wait for Last Transmit Mailbox\r
787     tick = 0;\r
788     do  {\r
789         status = AT91C_BASE_CAN0_MB3->CAN_MB_MSR;\r
790     }\r
791     while( !(status & AT91C_CAN_MRDY) && (++tick < AT91C_CAN_TIMEOUT) );\r
792 \r
793     if (tick == AT91C_CAN_TIMEOUT) {\r
794         trace_LOG( trace_ERROR, "-E- Test FAILED\n\r");\r
795     }\r
796     else {\r
797         trace_LOG( trace_DEBUG, "-I- Transfer Completed: CAN0 & CAN1 Mailboxes 3 MRDY flags have raised\n\r");\r
798         if( AT91C_BASE_CAN0_MB3->CAN_MB_MDL != AT91C_BASE_CAN1_MB3->CAN_MB_MDL ) {\r
799             trace_LOG( trace_ERROR, "-E- Data Corrupted\n\r");\r
800         }\r
801         else if( AT91C_BASE_CAN0_MB3->CAN_MB_MDH != AT91C_BASE_CAN1_MB3->CAN_MB_MDH ) {\r
802             trace_LOG( trace_ERROR, "-E- Data Corrupted\n\r");\r
803         }\r
804         else {\r
805             trace_LOG( trace_INFO, "Test passed\n\r");\r
806         }\r
807     }\r
808 #endif // AT91C_BASE_CAN1\r
809 \r
810   return;\r
811 }\r
812 \r
813 \r
814 //------------------------------------------------------------------------------\r
815 /// Disable CAN and enter in low power\r
816 //------------------------------------------------------------------------------\r
817 void CAN_disable( void )\r
818 {\r
819     // Disable the interrupt on the interrupt controller\r
820     AIC_DisableIT(AT91C_ID_CAN0);\r
821     // disable all IT\r
822     AT91C_BASE_CAN0->CAN_IDR = 0x1FFFFFFF;\r
823 #if defined AT91C_BASE_CAN1\r
824     AIC_DisableIT(AT91C_ID_CAN1);\r
825     // disable all IT\r
826     AT91C_BASE_CAN1->CAN_IDR = 0x1FFFFFFF;\r
827 #endif\r
828 \r
829     // Enable Low Power mode\r
830     AT91C_BASE_CAN0->CAN_MR |= AT91C_CAN_LPM;\r
831 \r
832     // Disable CANs Transceivers\r
833     // Enter standby mode\r
834     PIO_Set(&pin_can_transceiver_rs);\r
835 #if defined (PIN_CAN_TRANSCEIVER_RXEN)\r
836     // Enable ultra Low Power mode\r
837     PIO_Clear(&pin_can_transceiver_rxen);\r
838 #endif\r
839 \r
840     // Disable clock for CAN PIO\r
841     AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_PIOA);\r
842 \r
843     // Disable the CAN0 controller peripheral clock\r
844     AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_CAN0);\r
845 \r
846 }\r
847 \r
848 //------------------------------------------------------------------------------\r
849 /// baudrate calcul\r
850 /// \param base_CAN CAN base address\r
851 /// \param baudrate Baudrate value\r
852 ///                 allowed values: 1000, 800, 500, 250, 125, 50, 25, 10\r
853 /// \return return 1 in success, otherwise return 0\r
854 //------------------------------------------------------------------------------\r
855 unsigned char CAN_BaudRateCalculate( AT91PS_CAN   base_CAN, \r
856                                      unsigned int baudrate )\r
857 {\r
858     unsigned int BRP;\r
859     unsigned int PROPAG;\r
860     unsigned int PHASE1;\r
861     unsigned int PHASE2;\r
862     unsigned int SJW;\r
863     unsigned int t1t2;\r
864 \r
865     base_CAN->CAN_BR = 0;\r
866 \r
867     BRP = (BOARD_MCK / (baudrate*1000*16))-1;\r
868     //trace_LOG( trace_DEBUG, "BRP = 0x%X\n\r", BRP);\r
869     // timing Delay:\r
870     // Delay Bus Driver: 50 ns\r
871     // Delay Receiver:   30 ns\r
872     // Delay Bus Line:  110 ns\r
873     if( (16*baudrate*2*(50+30+110)/1000000) >= 1) {\r
874         PROPAG = (16*baudrate*2*(50+30+110)/1000000)-1;\r
875     }\r
876     else {\r
877         PROPAG = 0;\r
878     }\r
879     //trace_LOG( trace_DEBUG, "PROPAG = 0x%X\n\r", PROPAG);\r
880 \r
881     t1t2 = 15-(PROPAG+1);\r
882     //trace_LOG( trace_DEBUG, "t1t2 = 0x%X\n\r", t1t2);\r
883 \r
884     if( (t1t2 & 0x01) == 0x01 ) {\r
885         // ODD\r
886         //trace_LOG( trace_DEBUG, "ODD\n\r");\r
887         PHASE1 = ((t1t2-1)/2)-1;\r
888         PHASE2 = PHASE1+1;\r
889     }\r
890     else {\r
891         // EVEN\r
892         //trace_LOG( trace_DEBUG, "EVEN\n\r");\r
893         PHASE1 = (t1t2/2)-1;\r
894         PHASE2 = PHASE1;\r
895     }\r
896     //trace_LOG( trace_DEBUG, "PHASE1 = 0x%X\n\r", PHASE1);\r
897     //trace_LOG( trace_DEBUG, "PHASE2 = 0x%X\n\r", PHASE2);\r
898 \r
899     if( 1 > (4/(PHASE1+1)) ) {\r
900         //trace_LOG( trace_DEBUG, "4*Tcsc\n\r");\r
901         SJW = 3;\r
902     }\r
903     else {\r
904         //trace_LOG( trace_DEBUG, "Tphs1\n\r");\r
905         SJW = PHASE1;\r
906     }\r
907     //trace_LOG( trace_DEBUG, "SJW = 0x%X\n\r", SJW);\r
908     // Verif\r
909     if( BRP == 0 ) {\r
910         trace_LOG( trace_DEBUG, "BRP = 0 is not authorized\n\r");\r
911         return 0;\r
912     }\r
913     if( (PROPAG + PHASE1 + PHASE2) != 12 ) {\r
914         trace_LOG( trace_DEBUG, "(PROPAG + PHASE1 + PHASE2) != 12\n\r");\r
915         return 0;\r
916     }\r
917     base_CAN->CAN_BR = (AT91C_CAN_PHASE2 & (PHASE2 <<  0))\r
918                      + (AT91C_CAN_PHASE1 & (PHASE1 <<  4))\r
919                      + (AT91C_CAN_PROPAG & (PROPAG <<  8))\r
920                      + (AT91C_CAN_SYNC   & (SJW << 12))\r
921                      + (AT91C_CAN_BRP    & (BRP << 16))\r
922                      + (AT91C_CAN_SMP    & (0 << 24));\r
923     return 1;\r
924 \r
925 }\r
926 \r
927 //------------------------------------------------------------------------------\r
928 //------------------------------------------------------------------------------\r
929 //------------------------------------------------------------------------------\r
930 /// Init of the CAN peripheral\r
931 /// \param baudrate Baudrate value\r
932 ///                 allowed values: 1000, 800, 500, 250, 125, 50, 25, 10\r
933 /// \param canTransfer0 CAN0 structure transfer\r
934 /// \param canTransfer1 CAN1 structure transfer\r
935 /// \return return 1 if CAN has good baudrate and CAN is synchronized, \r
936 ///         otherwise return 0\r
937 //------------------------------------------------------------------------------\r
938 unsigned char CAN_Init( unsigned int baudrate, \r
939                         CanTransfer *canTransfer0, \r
940                         CanTransfer *canTransfer1 ) \r
941 {\r
942     unsigned char ret;\r
943 \r
944     // CAN Transmit Serial Data\r
945 #if defined (PINS_CAN_TRANSCEIVER_TXD)\r
946     PIO_Configure(pins_can_transceiver_txd, PIO_LISTSIZE(pins_can_transceiver_txd));\r
947 #endif\r
948 #if defined (PINS_CAN_TRANSCEIVER_RXD)\r
949     // CAN Receive Serial Data\r
950     PIO_Configure(pins_can_transceiver_rxd, PIO_LISTSIZE(pins_can_transceiver_rxd));\r
951 #endif\r
952     // CAN RS\r
953     PIO_Configure(&pin_can_transceiver_rs, PIO_LISTSIZE(pin_can_transceiver_rs));\r
954 #if defined (PIN_CAN_TRANSCEIVER_RXEN)\r
955     // CAN RXEN\r
956     PIO_Configure(&pin_can_transceiver_rxen, PIO_LISTSIZE(pin_can_transceiver_rxen));\r
957 #endif\r
958 \r
959     // Enable clock for CAN PIO\r
960     AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA);\r
961 \r
962     // Enable the CAN0 controller peripheral clock\r
963     AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_CAN0);\r
964 \r
965     // disable all IT\r
966     AT91C_BASE_CAN0->CAN_IDR = 0x1FFFFFFF;\r
967 \r
968     // Enable CANs Transceivers\r
969 #if defined (PIN_CAN_TRANSCEIVER_RXEN)\r
970     // Disable ultra Low Power mode\r
971     PIO_Set(&pin_can_transceiver_rxen);\r
972 #endif\r
973     // Normal Mode (versus Standby mode)\r
974     PIO_Clear(&pin_can_transceiver_rs);\r
975 \r
976     // Configure the AIC for CAN interrupts\r
977     AIC_ConfigureIT(AT91C_ID_CAN0, AT91C_AIC_PRIOR_HIGHEST, CAN0_Handler);\r
978 \r
979     // Enable the interrupt on the interrupt controller\r
980     AIC_EnableIT(AT91C_ID_CAN0);\r
981 \r
982     if( CAN_BaudRateCalculate(AT91C_BASE_CAN0, baudrate) == 0 ) {\r
983         // Baudrate problem\r
984         trace_LOG( trace_DEBUG, "Baudrate CAN0 problem\n\r");\r
985         return 0;\r
986     }\r
987 \r
988     pCAN0Transfer = canTransfer0;\r
989 \r
990 #if defined AT91C_BASE_CAN1\r
991     if( canTransfer1 != NULL ) {\r
992         pCAN1Transfer = canTransfer1;\r
993         // Enable CAN1 Clocks\r
994         AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_CAN1);\r
995 \r
996         // disable all IT\r
997         AT91C_BASE_CAN1->CAN_IDR = 0x1FFFFFFF;\r
998 \r
999         // Configure the AIC for CAN interrupts\r
1000         AIC_ConfigureIT(AT91C_ID_CAN1, AT91C_AIC_PRIOR_HIGHEST, CAN1_Handler);\r
1001 \r
1002         // Enable the interrupt on the interrupt controller\r
1003         AIC_EnableIT(AT91C_ID_CAN1);\r
1004 \r
1005         if( CAN_BaudRateCalculate(AT91C_BASE_CAN1, baudrate) == 0 ) {\r
1006             // Baudrate problem\r
1007             trace_LOG( trace_DEBUG, "Baudrate CAN1 problem\n\r");\r
1008             return 0;\r
1009         }\r
1010     }\r
1011 #endif\r
1012     // Reset all mailbox\r
1013     CAN_ResetAllMailbox();\r
1014 \r
1015     // Enable the interrupt with all error cases\r
1016     AT91C_BASE_CAN0->CAN_IER =  AT91C_CAN_CERR  // (CAN) CRC Error\r
1017                              |  AT91C_CAN_SERR  // (CAN) Stuffing Error\r
1018                              |  AT91C_CAN_BERR  // (CAN) Bit Error\r
1019                              |  AT91C_CAN_FERR  // (CAN) Form Error\r
1020                              |  AT91C_CAN_AERR; // (CAN) Acknowledgment Error\r
1021 \r
1022 #if defined AT91C_BASE_CAN1\r
1023     if( canTransfer1 != NULL ) {\r
1024         AT91C_BASE_CAN1->CAN_IER =  AT91C_CAN_CERR  // (CAN) CRC Error\r
1025                                  |  AT91C_CAN_SERR  // (CAN) Stuffing Error\r
1026                                  |  AT91C_CAN_BERR  // (CAN) Bit Error\r
1027                                  |  AT91C_CAN_FERR  // (CAN) Form Error\r
1028                                  |  AT91C_CAN_AERR; // (CAN) Acknowledgment Error\r
1029     }\r
1030 #endif\r
1031 \r
1032     // Wait for CAN synchronisation\r
1033     if( CAN_Synchronisation( ) == 1 ) {\r
1034         ret = 1;\r
1035     }\r
1036     else {\r
1037         ret = 0;\r
1038     }\r
1039 \r
1040     return ret;\r
1041 }\r
1042 \r