]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_AT91SAM3U256_IAR/AT91Lib/peripherals/can/can.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / CORTEX_AT91SAM3U256_IAR / 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_ERROR("(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_ERROR("(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_ERROR("(CAN) CAN is in Buff Off mode\n\r");\r
96         // CAN reset\r
97         TRACE_ERROR("(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_ERROR("(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_ERROR("(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_ERROR("(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_ERROR("(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_ERROR("(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=CAN_DISABLED;\r
157     unsigned char state1=CAN_DISABLED;\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_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_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_DEBUG("message_mode 0x%X\n\r", message_mode);\r
199                 TRACE_DEBUG("numMailbox 0x%X\n\r", numMailbox);\r
200 \r
201                 if( message_mode == 0 ) {\r
202                     TRACE_ERROR("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_DEBUG("Mailbox is in RECEPTION\n\r");\r
208                     TRACE_DEBUG("Length 0x%X\n\r", (can_msr>>16)&0xF);\r
209                     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_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_DEBUG("Mailbox is in TRANSMIT\n\r");\r
243                     TRACE_DEBUG("Length 0x%X\n\r", (can_msr>>16)&0xF);\r
244                     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 & AT91C_CAN_MIDE) == AT91C_CAN_MIDE ) {\r
321         // Extended\r
322         CAN_Mailbox->CAN_MB_MAM |= AT91C_CAN_MIDE;\r
323     }\r
324     else {\r
325         CAN_Mailbox->CAN_MB_MAM &= ~AT91C_CAN_MIDE;\r
326     }\r
327     CAN_Mailbox->CAN_MB_MID = pTransfer->identifier;\r
328 \r
329     // MailBox Mode Register\r
330     CAN_Mailbox->CAN_MB_MMR = pTransfer->mode_reg;\r
331     // MailBox Data Low Register\r
332     CAN_Mailbox->CAN_MB_MDL = pTransfer->data_low_reg;\r
333     // MailBox Data High Register\r
334     CAN_Mailbox->CAN_MB_MDH = pTransfer->data_high_reg;\r
335     // MailBox Control Register\r
336     CAN_Mailbox->CAN_MB_MCR = pTransfer->control_reg;\r
337 }\r
338 \r
339 //------------------------------------------------------------------------------\r
340 /// Reset the MBx\r
341 //------------------------------------------------------------------------------\r
342 void CAN_ResetAllMailbox( void )\r
343 {\r
344     unsigned char i;\r
345   \r
346 #if defined (AT91C_BASE_CAN0_MB0)\r
347     CAN_ResetTransfer( pCAN0Transfer );\r
348     for( i=0; i<8; i++ ) {\r
349         pCAN0Transfer->can_number = 0;\r
350         pCAN0Transfer->mailbox_number = i;\r
351         pCAN0Transfer->mode_reg = AT91C_CAN_MOT_DIS;\r
352         pCAN0Transfer->acceptance_mask_reg = 0;\r
353         pCAN0Transfer->identifier = 0;\r
354         pCAN0Transfer->data_low_reg = 0x00000000;\r
355         pCAN0Transfer->data_high_reg = 0x00000000;\r
356         pCAN0Transfer->control_reg = 0x00000000;\r
357         CAN_InitMailboxRegisters( pCAN0Transfer );\r
358     }\r
359 #endif\r
360 #if defined (AT91C_BASE_CAN0_MB8)\r
361     for( i=0; i<8; i++ ) {\r
362         pCAN0Transfer->can_number = 0;\r
363         pCAN0Transfer->mailbox_number = i+8;\r
364         pCAN0Transfer->mode_reg = AT91C_CAN_MOT_DIS;\r
365         pCAN0Transfer->acceptance_mask_reg = 0;\r
366         pCAN0Transfer->identifier = 0;\r
367         pCAN0Transfer->data_low_reg = 0x00000000;\r
368         pCAN0Transfer->data_high_reg = 0x00000000;\r
369         pCAN0Transfer->control_reg = 0x00000000;\r
370         CAN_InitMailboxRegisters( pCAN0Transfer );\r
371     }\r
372 #endif\r
373 \r
374 #if defined (AT91C_BASE_CAN1_MB0)\r
375     if( pCAN1Transfer != NULL ) {\r
376         CAN_ResetTransfer( pCAN1Transfer );\r
377         for( i=0; i<8; i++ ) {\r
378             pCAN1Transfer->can_number = 1;\r
379             pCAN1Transfer->mailbox_number = i;\r
380             pCAN1Transfer->mode_reg = AT91C_CAN_MOT_DIS;\r
381             pCAN1Transfer->acceptance_mask_reg = 0;\r
382             pCAN1Transfer->identifier = 0;\r
383             pCAN1Transfer->data_low_reg = 0x00000000;\r
384             pCAN1Transfer->data_high_reg = 0x00000000;\r
385             pCAN1Transfer->control_reg = 0x00000000;\r
386             CAN_InitMailboxRegisters( pCAN1Transfer );\r
387         }\r
388     }\r
389 #endif\r
390 #if defined (AT91C_BASE_CAN1_MB8)\r
391     if( pCAN1Transfer != NULL ) {\r
392         for( i=0; i<8; i++ ) {\r
393             pCAN1Transfer->can_number = 1;\r
394             pCAN1Transfer->mailbox_number = i+8;\r
395             pCAN1Transfer->mode_reg = AT91C_CAN_MOT_DIS;\r
396             pCAN1Transfer->acceptance_mask_reg = 0;\r
397             pCAN1Transfer->identifier = 0;\r
398             pCAN1Transfer->data_low_reg = 0x00000000;\r
399             pCAN1Transfer->data_high_reg = 0x00000000;\r
400             pCAN1Transfer->control_reg = 0x00000000;\r
401             CAN_InitMailboxRegisters( pCAN1Transfer );\r
402         }\r
403     }\r
404 #endif\r
405 \r
406 }\r
407 \r
408 //------------------------------------------------------------------------------\r
409 /// CAN reset Transfer descriptor\r
410 /// \param pTransfer can transfer structure\r
411 //------------------------------------------------------------------------------\r
412 void CAN_ResetTransfer( CanTransfer *pTransfer )\r
413 {\r
414     pTransfer->state = CAN_IDLE;\r
415     pTransfer->can_number = 0;\r
416     pTransfer->mailbox_number = 0;\r
417     pTransfer->test_can = 0;\r
418     pTransfer->mode_reg = 0;\r
419     pTransfer->acceptance_mask_reg = 0;\r
420     pTransfer->identifier = 0;\r
421     pTransfer->data_low_reg = 0;\r
422     pTransfer->data_high_reg = 0;\r
423     pTransfer->control_reg = 0;\r
424     pTransfer->mailbox_in_use = 0;\r
425     pTransfer->size = 0;\r
426 }\r
427 \r
428 //------------------------------------------------------------------------------\r
429 /// Wait for CAN synchronisation\r
430 /// \return return 1 for good initialisation, otherwise return 0\r
431 //------------------------------------------------------------------------------\r
432 static unsigned char CAN_Synchronisation( void )\r
433 {\r
434     unsigned int tick=0;\r
435 \r
436     TRACE_INFO("CAN_Synchronisation\n\r");\r
437 \r
438     pCAN0Transfer->test_can = AT91C_TEST_NOK;\r
439 #ifdef AT91C_BASE_CAN1\r
440     if( pCAN1Transfer != NULL ) {\r
441         pCAN1Transfer->test_can = AT91C_TEST_NOK;\r
442     }\r
443 #endif\r
444     // Enable CAN and Wait for WakeUp Interrupt\r
445     AT91C_BASE_CAN0->CAN_IER = AT91C_CAN_WAKEUP;\r
446     // CAN Controller Enable\r
447     AT91C_BASE_CAN0->CAN_MR = AT91C_CAN_CANEN;\r
448     // Enable Autobaud/Listen mode\r
449     // dangerous, CAN not answer in this mode\r
450 \r
451      while( (pCAN0Transfer->test_can != AT91C_TEST_OK)\r
452          && (tick < AT91C_CAN_TIMEOUT) ) {\r
453         tick++;\r
454     }\r
455     if (tick == AT91C_CAN_TIMEOUT) {\r
456         TRACE_ERROR("CAN0 Initialisations FAILED\n\r");\r
457         return 0;\r
458     } else {\r
459         TRACE_INFO("CAN0 Initialisations Completed\n\r");\r
460     }\r
461 \r
462 #if defined AT91C_BASE_CAN1\r
463     if( pCAN1Transfer != NULL ) {\r
464         AT91C_BASE_CAN1->CAN_IER = AT91C_CAN_WAKEUP;\r
465         // CAN Controller Enable\r
466         AT91C_BASE_CAN1->CAN_MR = AT91C_CAN_CANEN;\r
467 \r
468         tick = 0;\r
469         // Wait for WAKEUP flag raising <=> 11-recessive-bit were scanned by the transceiver\r
470         while( ((pCAN1Transfer->test_can != AT91C_TEST_OK)) \r
471             && (tick < AT91C_CAN_TIMEOUT) ) {\r
472             tick++;\r
473         }\r
474 \r
475         if (tick == AT91C_CAN_TIMEOUT) {\r
476             TRACE_ERROR("CAN1 Initialisations FAILED\n\r");\r
477             return 0;\r
478         } else {\r
479             TRACE_INFO("CAN1 Initialisations Completed\n\r");\r
480         }\r
481     }\r
482 #endif\r
483     return 1;\r
484 }\r
485 \r
486 //------------------------------------------------------------------------------\r
487 /// Write a CAN transfer\r
488 /// \param pTransfer can transfer structure\r
489 /// \return return CAN_STATUS_SUCCESS if command passed, otherwise \r
490 ///         return CAN_STATUS_LOCKED\r
491 //------------------------------------------------------------------------------\r
492 unsigned char CAN_Write( CanTransfer *pTransfer )\r
493 {\r
494     AT91PS_CAN base_can;\r
495 \r
496     if (pTransfer->state == CAN_RECEIVING)  {\r
497         pTransfer->state = CAN_IDLE;\r
498     }\r
499 \r
500     if (pTransfer->state != CAN_IDLE)  {\r
501         return CAN_STATUS_LOCKED;\r
502     }\r
503 \r
504     TRACE_DEBUG("CAN_Write\n\r");\r
505     pTransfer->state = CAN_SENDING;\r
506     if( pTransfer->can_number == 0 ) {\r
507         base_can = AT91C_BASE_CAN0;\r
508     }\r
509 #ifdef AT91C_BASE_CAN1\r
510     else {\r
511         base_can = AT91C_BASE_CAN1;\r
512     }\r
513 #endif\r
514     base_can->CAN_TCR = pTransfer->mailbox_in_use;\r
515     base_can->CAN_IER = pTransfer->mailbox_in_use;\r
516 \r
517     return CAN_STATUS_SUCCESS;\r
518 \r
519 }\r
520 \r
521 \r
522 //------------------------------------------------------------------------------\r
523 /// Read a CAN transfer\r
524 /// \param pTransfer can transfer structure\r
525 /// \return return CAN_STATUS_SUCCESS if command passed, otherwise \r
526 ///         return CAN_STATUS_LOCKED\r
527 //------------------------------------------------------------------------------\r
528 unsigned char CAN_Read( CanTransfer *pTransfer )\r
529 {\r
530     AT91PS_CAN base_can;\r
531 \r
532     if (pTransfer->state != CAN_IDLE)  {\r
533         return CAN_STATUS_LOCKED;\r
534     }\r
535 \r
536     TRACE_DEBUG("CAN_Read\n\r");\r
537     pTransfer->state = CAN_RECEIVING;\r
538 \r
539 \r
540     if( pTransfer->can_number == 0 ) {\r
541         base_can = AT91C_BASE_CAN0;\r
542     }\r
543 #ifdef AT91C_BASE_CAN1\r
544     else {\r
545         base_can = AT91C_BASE_CAN1;\r
546     }\r
547 #endif\r
548     // enable interrupt\r
549     base_can->CAN_IER = pTransfer->mailbox_in_use;\r
550 \r
551     return CAN_STATUS_SUCCESS;\r
552 }\r
553 \r
554 //------------------------------------------------------------------------------\r
555 /// Test if CAN is in IDLE state\r
556 /// \param pTransfer can transfer structure\r
557 /// \return return 0 if CAN is in IDLE, otherwise return 1\r
558 //------------------------------------------------------------------------------\r
559 unsigned char CAN_IsInIdle( CanTransfer *pTransfer )\r
560 {\r
561   return( pTransfer->state != CAN_IDLE );\r
562 }\r
563 \r
564 //------------------------------------------------------------------------------\r
565 /// Basic CAN test without Interrupt\r
566 //------------------------------------------------------------------------------\r
567 void CAN_BasicTestSuiteWithoutInterrupt(void)\r
568 {\r
569 #if defined AT91C_BASE_CAN1\r
570     unsigned int status;\r
571     unsigned int tick=0;\r
572 \r
573     TRACE_INFO("Without Interrupt ");\r
574     TRACE_INFO("CAN0 Mailbox 0 transmitting to CAN1 Mailbox 0\n\r");\r
575     // Init CAN0 Mailbox 0, transmit\r
576     CAN_ResetTransfer( pCAN0Transfer );\r
577     pCAN0Transfer->can_number = 0;\r
578     pCAN0Transfer->mailbox_number = 0;\r
579     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;\r
580     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
581     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x07<<18);\r
582     pCAN0Transfer->data_low_reg = 0x11223344;\r
583     pCAN0Transfer->data_high_reg = 0x01234567;\r
584     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16));\r
585     CAN_InitMailboxRegisters( pCAN0Transfer );\r
586 \r
587     // Init CAN1 Mailbox 0, receive, \r
588     CAN_ResetTransfer( pCAN1Transfer );\r
589     pCAN1Transfer->can_number = 1;\r
590     pCAN1Transfer->mailbox_number = 0;\r
591     pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RX;\r
592     pCAN1Transfer->acceptance_mask_reg = AT91C_CAN_MIDvA | AT91C_CAN_MIDvB;\r
593     pCAN1Transfer->identifier = AT91C_CAN_MIDvA & (0x07<<18);\r
594     pCAN1Transfer->data_low_reg = 0x00000000;\r
595     pCAN1Transfer->data_high_reg = 0x00000000;\r
596     pCAN1Transfer->control_reg = 0x00000000;\r
597     CAN_InitMailboxRegisters( pCAN1Transfer );\r
598 \r
599     // Transfer Request for Mailbox 0\r
600     AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB0;\r
601 \r
602     tick = 0;\r
603     do {\r
604         // CAN Message Status Register\r
605         status = AT91C_BASE_CAN0_MB0->CAN_MB_MSR;\r
606     }\r
607     while( !(status & AT91C_CAN_MRDY) && (++tick < AT91C_CAN_TIMEOUT) );\r
608 \r
609     if (tick == AT91C_CAN_TIMEOUT) {\r
610         TRACE_ERROR("Test FAILED\n\r");\r
611     } \r
612     else {\r
613         TRACE_DEBUG("Transfer completed: CAN1 Mailbox 0 MRDY flag has raised\n\r");\r
614         if( AT91C_BASE_CAN0_MB0->CAN_MB_MDL != AT91C_BASE_CAN1_MB0->CAN_MB_MDL ) {\r
615             TRACE_ERROR("Data Corrupted\n\r");\r
616         }\r
617         else if( AT91C_BASE_CAN0_MB0->CAN_MB_MDH != AT91C_BASE_CAN1_MB0->CAN_MB_MDH ) {\r
618             TRACE_ERROR("Data Corrupted\n\r");\r
619         }\r
620         else {\r
621             TRACE_INFO("Test passed\n\r");\r
622         }\r
623     }\r
624 \r
625     CAN_ResetAllMailbox();\r
626 \r
627     TRACE_INFO("Without Interrupt ");\r
628     TRACE_INFO("CAN0 Mailboxes 1 & 2 transmitting to CAN1 Mailbox 15\n\r");\r
629     // Init CAN0 Mailbox 1, transmit\r
630     CAN_ResetTransfer( pCAN0Transfer );\r
631     pCAN0Transfer->can_number = 0;\r
632     pCAN0Transfer->mailbox_number = 1;\r
633     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;\r
634     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
635     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x09<<18);      // ID 9\r
636     pCAN0Transfer->data_low_reg = 0xAABBCCDD;\r
637     pCAN0Transfer->data_high_reg = 0xCAFEDECA;\r
638     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code\r
639     CAN_InitMailboxRegisters( pCAN0Transfer );\r
640 \r
641     // Init CAN0 Mailbox 2, transmit\r
642     pCAN0Transfer->can_number = 0;\r
643     pCAN0Transfer->mailbox_number = 2;\r
644     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | (AT91C_CAN_PRIOR-(1<<16));\r
645     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
646     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0A<<18);      // ID 10\r
647     pCAN0Transfer->data_low_reg = 0x55667788;\r
648     pCAN0Transfer->data_high_reg = 0x99AABBCC;\r
649     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code\r
650     CAN_InitMailboxRegisters( pCAN0Transfer );\r
651 \r
652     // Init CAN1 Mailbox 15, reception with overwrite\r
653     CAN_ResetTransfer( pCAN1Transfer );\r
654     pCAN1Transfer->can_number = 1;\r
655     pCAN1Transfer->mailbox_number = 15;\r
656     pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RXOVERWRITE;\r
657     pCAN1Transfer->acceptance_mask_reg = 0;\r
658     pCAN1Transfer->identifier = 0x0;\r
659     pCAN1Transfer->data_low_reg = 0x00000000;\r
660     pCAN1Transfer->data_high_reg = 0x00000000;\r
661     pCAN1Transfer->control_reg = 0x00000000;\r
662     CAN_InitMailboxRegisters( pCAN1Transfer );\r
663 \r
664     // Ask Transmissions on Mailbox 1 & 2 --> AT91C_CAN_MRDY & AT91C_CAN_MMI raises for Mailbox 15 CAN_MB_SR\r
665     AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB1 | AT91C_CAN_MB2;\r
666     \r
667     // Wait for Last Transmit Mailbox\r
668     tick = 0;\r
669     do  {\r
670         status = AT91C_BASE_CAN1_MB15->CAN_MB_MSR;\r
671     }\r
672     while( !(status & AT91C_CAN_MMI) && (++tick < AT91C_CAN_TIMEOUT) );\r
673 \r
674     if (tick == AT91C_CAN_TIMEOUT) {\r
675     }\r
676     else {\r
677         TRACE_DEBUG("Transfer completed: CAN1 Mailbox 15 MRDY and MMI flags have raised\n\r");\r
678         if( AT91C_BASE_CAN0_MB1->CAN_MB_MDL != AT91C_BASE_CAN1_MB15->CAN_MB_MDL ) {\r
679             TRACE_ERROR("Data Corrupted\n\r");\r
680         }\r
681         else if( AT91C_BASE_CAN0_MB1->CAN_MB_MDH != AT91C_BASE_CAN1_MB15->CAN_MB_MDH ) {\r
682             TRACE_ERROR("Data Corrupted\n\r");\r
683         }\r
684         else {\r
685             TRACE_INFO("Test passed\n\r");\r
686         }\r
687     }\r
688 \r
689     CAN_ResetAllMailbox();\r
690     TRACE_INFO("Without Interrupt ");\r
691     TRACE_INFO("CAN0 Mailboxes 1 & 2 transmitting to CAN1 Mailbox 15\n\r");\r
692     // Init CAN0 Mailbox 1, transmit\r
693     CAN_ResetTransfer( pCAN0Transfer );\r
694     pCAN0Transfer->can_number = 0;\r
695     pCAN0Transfer->mailbox_number = 1;\r
696     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;\r
697     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
698     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x09<<18);      // ID 9\r
699     pCAN0Transfer->data_low_reg = 0xAABBCCDD;\r
700     pCAN0Transfer->data_high_reg = 0xCAFEDECA;\r
701     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code\r
702     CAN_InitMailboxRegisters( pCAN0Transfer );\r
703 \r
704     // Init CAN0 Mailbox 2, transmit\r
705     pCAN0Transfer->can_number = 0;\r
706     pCAN0Transfer->mailbox_number = 2;\r
707     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | (AT91C_CAN_PRIOR-(1<<16));\r
708     pCAN0Transfer->acceptance_mask_reg = 0x00000000;\r
709     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0A<<18);      // ID 10\r
710     pCAN0Transfer->data_low_reg = 0x55667788;\r
711     pCAN0Transfer->data_high_reg = 0x99AABBCC;\r
712     pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code\r
713     CAN_InitMailboxRegisters( pCAN0Transfer );\r
714 \r
715     // Init CAN1 Mailbox 15, reception with overwrite\r
716     CAN_ResetTransfer( pCAN1Transfer );\r
717     pCAN1Transfer->can_number = 1;\r
718     pCAN1Transfer->mailbox_number = 15;\r
719     pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RX;\r
720     pCAN1Transfer->acceptance_mask_reg = 0;\r
721     pCAN1Transfer->identifier = 0x0;\r
722     pCAN1Transfer->data_low_reg = 0x00000000;\r
723     pCAN1Transfer->data_high_reg = 0x00000000;\r
724     pCAN1Transfer->control_reg = 0x00000000;\r
725     CAN_InitMailboxRegisters( pCAN1Transfer );\r
726 \r
727     // Ask Transmissions on Mailbox 1 & 2 --> AT91C_CAN_MRDY & AT91C_CAN_MMI raises for Mailbox 15 CAN_MB_SR\r
728     AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB1 | AT91C_CAN_MB2;\r
729     \r
730     // Wait for Last Transmit Mailbox\r
731     tick = 0;\r
732     do  {\r
733         status = AT91C_BASE_CAN1_MB15->CAN_MB_MSR;\r
734     }\r
735     while( !(status & AT91C_CAN_MMI) && (++tick < AT91C_CAN_TIMEOUT) );\r
736 \r
737     if (tick == AT91C_CAN_TIMEOUT) {\r
738     TRACE_ERROR("Test FAILED\n\r");\r
739     }\r
740     else {\r
741         TRACE_DEBUG("Transfer completed: CAN1 Mailbox 15 MRDY and MMI flags have raised\n\r");\r
742         TRACE_DEBUG("MB_MDL: 0x%X\n\r", AT91C_BASE_CAN1_MB15->CAN_MB_MDL);\r
743         TRACE_DEBUG("MB_MDLH: 0x%X\n\r", AT91C_BASE_CAN1_MB15->CAN_MB_MDH);\r
744         if( AT91C_BASE_CAN0_MB2->CAN_MB_MDL != AT91C_BASE_CAN1_MB15->CAN_MB_MDL ) {\r
745             TRACE_ERROR("Data Corrupted\n\r");\r
746         }\r
747         else if( AT91C_BASE_CAN0_MB2->CAN_MB_MDH != AT91C_BASE_CAN1_MB15->CAN_MB_MDH ) {\r
748             TRACE_ERROR("Data Corrupted\n\r");\r
749         }\r
750         else {\r
751             TRACE_INFO("Test passed\n\r");\r
752         }\r
753     }\r
754 \r
755     CAN_ResetAllMailbox();\r
756     TRACE_INFO("Without Interrupt ");\r
757     TRACE_INFO("CAN0 Mailbox 3 asking for CAN1 Mailbox 3 transmission\n\r");\r
758     // Init CAN0 Mailbox 3, consumer mailbox\r
759     // Sends a remote frame and waits for an answer\r
760     CAN_ResetTransfer( pCAN0Transfer );\r
761     pCAN0Transfer->can_number = 0;\r
762     pCAN0Transfer->mailbox_number = 3;\r
763     pCAN0Transfer->mode_reg = AT91C_CAN_MOT_CONSUMER | AT91C_CAN_PRIOR;\r
764     pCAN0Transfer->acceptance_mask_reg = AT91C_CAN_MIDvA | AT91C_CAN_MIDvB;\r
765     pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0B<<18);     // ID 11\r
766     pCAN0Transfer->data_low_reg = 0x00000000;\r
767     pCAN0Transfer->data_high_reg = 0x00000000;\r
768     pCAN0Transfer->control_reg = 0x00000000;\r
769     CAN_InitMailboxRegisters( pCAN0Transfer );\r
770 \r
771     // Init CAN1 Mailbox 3, porducer mailbox\r
772     // Waits to receive a Remote Frame before sending its contents\r
773     CAN_ResetTransfer( pCAN1Transfer );\r
774     pCAN1Transfer->can_number = 1;\r
775     pCAN1Transfer->mailbox_number = 3;\r
776     pCAN1Transfer->mode_reg = AT91C_CAN_MOT_PRODUCER | AT91C_CAN_PRIOR;\r
777     pCAN1Transfer->acceptance_mask_reg = 0;\r
778     pCAN1Transfer->identifier = AT91C_CAN_MIDvA & (0x0B<<18);     // ID 11\r
779     pCAN1Transfer->data_low_reg = 0xEEDDFF00;\r
780     pCAN1Transfer->data_high_reg = 0x34560022;\r
781     pCAN1Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16));\r
782     CAN_InitMailboxRegisters( pCAN1Transfer );\r
783 \r
784     // Ask Transmissions on Mailbox 3 --> AT91C_CAN_MRDY raises for Mailbox 3 CAN_MB_SR\r
785     AT91C_BASE_CAN1->CAN_TCR = AT91C_CAN_MB3;\r
786     AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB3;\r
787 \r
788     // Wait for Last Transmit Mailbox\r
789     tick = 0;\r
790     do  {\r
791         status = AT91C_BASE_CAN0_MB3->CAN_MB_MSR;\r
792     }\r
793     while( !(status & AT91C_CAN_MRDY) && (++tick < AT91C_CAN_TIMEOUT) );\r
794 \r
795     if (tick == AT91C_CAN_TIMEOUT) {\r
796         TRACE_ERROR("Test FAILED\n\r");\r
797     }\r
798     else {\r
799         TRACE_DEBUG("Transfer Completed: CAN0 & CAN1 Mailboxes 3 MRDY flags have raised\n\r");\r
800         if( AT91C_BASE_CAN0_MB3->CAN_MB_MDL != AT91C_BASE_CAN1_MB3->CAN_MB_MDL ) {\r
801             TRACE_ERROR("Data Corrupted\n\r");\r
802         }\r
803         else if( AT91C_BASE_CAN0_MB3->CAN_MB_MDH != AT91C_BASE_CAN1_MB3->CAN_MB_MDH ) {\r
804             TRACE_ERROR("Data Corrupted\n\r");\r
805         }\r
806         else {\r
807             TRACE_INFO("Test passed\n\r");\r
808         }\r
809     }\r
810 #endif // AT91C_BASE_CAN1\r
811 \r
812   return;\r
813 }\r
814 \r
815 \r
816 //------------------------------------------------------------------------------\r
817 /// Disable CAN and enter in low power\r
818 //------------------------------------------------------------------------------\r
819 void CAN_disable( void )\r
820 {\r
821     // Disable the interrupt on the interrupt controller\r
822     AIC_DisableIT(AT91C_ID_CAN0);\r
823     // disable all IT\r
824     AT91C_BASE_CAN0->CAN_IDR = 0x1FFFFFFF;\r
825 #if defined AT91C_BASE_CAN1\r
826     AIC_DisableIT(AT91C_ID_CAN1);\r
827     // disable all IT\r
828     AT91C_BASE_CAN1->CAN_IDR = 0x1FFFFFFF;\r
829 #endif\r
830 \r
831     // Enable Low Power mode\r
832     AT91C_BASE_CAN0->CAN_MR |= AT91C_CAN_LPM;\r
833 \r
834     // Disable CANs Transceivers\r
835     // Enter standby mode\r
836     PIO_Set(&pin_can_transceiver_rs);\r
837 #if defined (PIN_CAN_TRANSCEIVER_RXEN)\r
838     // Enable ultra Low Power mode\r
839     PIO_Clear(&pin_can_transceiver_rxen);\r
840 #endif\r
841 \r
842     // Disable clock for CAN PIO\r
843 #if defined(AT91C_ID_PIOA)    \r
844     AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_PIOA);\r
845 #elif defined(AT91C_ID_PIOABCD)\r
846     AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_PIOABCD);\r
847 #elif defined(AT91C_ID_PIOABCDE)\r
848     AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_PIOABCDE);\r
849 #endif\r
850     \r
851     // Disable the CAN0 controller peripheral clock\r
852     AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_CAN0);\r
853 \r
854 }\r
855 \r
856 //------------------------------------------------------------------------------\r
857 /// baudrate calcul\r
858 /// \param base_CAN CAN base address\r
859 /// \param baudrate Baudrate value (kB/s)\r
860 ///                 allowed values: 1000, 800, 500, 250, 125, 50, 25, 10\r
861 /// \return return 1 in success, otherwise return 0\r
862 //------------------------------------------------------------------------------\r
863 unsigned char CAN_BaudRateCalculate( AT91PS_CAN   base_CAN, \r
864                                      unsigned int baudrate )\r
865 {\r
866     unsigned int BRP;\r
867     unsigned int PROPAG;\r
868     unsigned int PHASE1;\r
869     unsigned int PHASE2;\r
870     unsigned int SJW;\r
871     unsigned int t1t2;\r
872     unsigned char TimeQuanta;\r
873 \r
874     base_CAN->CAN_BR = 0;\r
875 \r
876     if( baudrate == 1000) {\r
877         TimeQuanta = 8;\r
878     }\r
879     else {\r
880         TimeQuanta = 16;\r
881     }\r
882 \r
883     BRP = (BOARD_MCK / (baudrate*1000*TimeQuanta))-1;\r
884     //TRACE_DEBUG("BRP = 0x%X\n\r", BRP);\r
885     // timing Delay:\r
886     // Delay Bus Driver: 50 ns\r
887     // Delay Receiver:   30 ns\r
888     // Delay Bus Line (20m):  110 ns\r
889     if( (TimeQuanta*baudrate*2*(50+30+110)/1000000) >= 1) {\r
890         PROPAG = (TimeQuanta*baudrate*2*(50+30+110)/1000000)-1;\r
891     }\r
892     else {\r
893         PROPAG = 0;\r
894     }\r
895     //TRACE_DEBUG("PROPAG = 0x%X\n\r", PROPAG);\r
896 \r
897     t1t2 = TimeQuanta-1-(PROPAG+1);\r
898     //TRACE_DEBUG("t1t2 = 0x%X\n\r", t1t2);\r
899 \r
900     if( (t1t2 & 0x01) == 0x01 ) {\r
901         // ODD\r
902         //TRACE_DEBUG("ODD\n\r");\r
903         PHASE1 = ((t1t2-1)/2)-1;\r
904         PHASE2 = PHASE1+1;\r
905     }\r
906     else {\r
907         // EVEN\r
908         //TRACE_DEBUG("EVEN\n\r");\r
909         PHASE1 = (t1t2/2)-1;\r
910         PHASE2 = PHASE1;\r
911     }\r
912     //TRACE_DEBUG("PHASE1 = 0x%X\n\r", PHASE1);\r
913     //TRACE_DEBUG("PHASE2 = 0x%X\n\r", PHASE2);\r
914 \r
915     if( 1 > (4/(PHASE1+1)) ) {\r
916         //TRACE_DEBUG("4*Tcsc\n\r");\r
917         SJW = 3;\r
918     }\r
919     else {\r
920         //TRACE_DEBUG("Tphs1\n\r");\r
921         SJW = PHASE1;\r
922     }\r
923     //TRACE_DEBUG("SJW = 0x%X\n\r", SJW);\r
924     // Verif\r
925     if( BRP == 0 ) {\r
926         TRACE_DEBUG("BRP = 0 is not authorized\n\r");\r
927         return 0;\r
928     }\r
929 \r
930     if( (PROPAG + PHASE1 + PHASE2) != (TimeQuanta-4) ) {\r
931         TRACE_DEBUG("Pb (PROPAG + PHASE1 + PHASE2) = %d\n\r", PROPAG + PHASE1 + PHASE2);\r
932         TRACE_DEBUG("with TimeQuanta-4 = %d\n\r", TimeQuanta-4);\r
933         return 0;\r
934     }\r
935     base_CAN->CAN_BR = (AT91C_CAN_PHASE2 & (PHASE2 <<  0))\r
936                      + (AT91C_CAN_PHASE1 & (PHASE1 <<  4))\r
937                      + (AT91C_CAN_PROPAG & (PROPAG <<  8))\r
938                      + (AT91C_CAN_SYNC   & (SJW << 12))\r
939                      + (AT91C_CAN_BRP    & (BRP << 16))\r
940                      + (AT91C_CAN_SMP    & (0 << 24));\r
941     return 1;\r
942 \r
943 }\r
944 \r
945 //------------------------------------------------------------------------------\r
946 //------------------------------------------------------------------------------\r
947 //------------------------------------------------------------------------------\r
948 /// Init of the CAN peripheral\r
949 /// \param baudrate Baudrate value (kB/s)\r
950 ///                 allowed values: 1000, 800, 500, 250, 125, 50, 25, 10\r
951 /// \param canTransfer0 CAN0 structure transfer\r
952 /// \param canTransfer1 CAN1 structure transfer\r
953 /// \return return 1 if CAN has good baudrate and CAN is synchronized, \r
954 ///         otherwise return 0\r
955 //------------------------------------------------------------------------------\r
956 unsigned char CAN_Init( unsigned int baudrate, \r
957                         CanTransfer *canTransfer0, \r
958                         CanTransfer *canTransfer1 ) \r
959 {\r
960     unsigned char ret;\r
961 \r
962     // CAN Transmit Serial Data\r
963 #if defined (PINS_CAN_TRANSCEIVER_TXD)\r
964     PIO_Configure(pins_can_transceiver_txd, PIO_LISTSIZE(pins_can_transceiver_txd));\r
965 #endif\r
966 #if defined (PINS_CAN_TRANSCEIVER_RXD)\r
967     // CAN Receive Serial Data\r
968     PIO_Configure(pins_can_transceiver_rxd, PIO_LISTSIZE(pins_can_transceiver_rxd));\r
969 #endif\r
970     // CAN RS\r
971     PIO_Configure(&pin_can_transceiver_rs, PIO_LISTSIZE(pin_can_transceiver_rs));\r
972 #if defined (PIN_CAN_TRANSCEIVER_RXEN)\r
973     // CAN RXEN\r
974     PIO_Configure(&pin_can_transceiver_rxen, PIO_LISTSIZE(pin_can_transceiver_rxen));\r
975 #endif\r
976 \r
977     // Enable clock for CAN PIO\r
978 #if defined(AT91C_ID_PIOA)    \r
979     AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA);\r
980 #elif defined(AT91C_ID_PIOABCD)\r
981     AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOABCD);\r
982 #elif defined(AT91C_ID_PIOABCDE)\r
983     AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOABCDE);\r
984 #endif\r
985 \r
986     // Enable the CAN0 controller peripheral clock\r
987     AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_CAN0);\r
988 \r
989     // disable all IT\r
990     AT91C_BASE_CAN0->CAN_IDR = 0x1FFFFFFF;\r
991 \r
992     // Enable CANs Transceivers\r
993 #if defined (PIN_CAN_TRANSCEIVER_RXEN)\r
994     // Disable ultra Low Power mode\r
995     PIO_Set(&pin_can_transceiver_rxen);\r
996 #endif\r
997     // Normal Mode (versus Standby mode)\r
998     PIO_Clear(&pin_can_transceiver_rs);\r
999 \r
1000     // Configure the AIC for CAN interrupts\r
1001     AIC_ConfigureIT(AT91C_ID_CAN0, AT91C_AIC_PRIOR_HIGHEST, CAN0_Handler);\r
1002 \r
1003     // Enable the interrupt on the interrupt controller\r
1004     AIC_EnableIT(AT91C_ID_CAN0);\r
1005 \r
1006     if( CAN_BaudRateCalculate(AT91C_BASE_CAN0, baudrate) == 0 ) {\r
1007         // Baudrate problem\r
1008         TRACE_DEBUG("Baudrate CAN0 problem\n\r");\r
1009         return 0;\r
1010     }\r
1011 \r
1012     pCAN0Transfer = canTransfer0;\r
1013 \r
1014 #if defined AT91C_BASE_CAN1\r
1015     if( canTransfer1 != NULL ) {\r
1016         pCAN1Transfer = canTransfer1;\r
1017         // Enable CAN1 Clocks\r
1018         AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_CAN1);\r
1019 \r
1020         // disable all IT\r
1021         AT91C_BASE_CAN1->CAN_IDR = 0x1FFFFFFF;\r
1022 \r
1023         // Configure the AIC for CAN interrupts\r
1024         AIC_ConfigureIT(AT91C_ID_CAN1, AT91C_AIC_PRIOR_HIGHEST, CAN1_Handler);\r
1025 \r
1026         // Enable the interrupt on the interrupt controller\r
1027         AIC_EnableIT(AT91C_ID_CAN1);\r
1028 \r
1029         if( CAN_BaudRateCalculate(AT91C_BASE_CAN1, baudrate) == 0 ) {\r
1030             // Baudrate problem\r
1031             TRACE_DEBUG("Baudrate CAN1 problem\n\r");\r
1032             return 0;\r
1033         }\r
1034     }\r
1035 #endif\r
1036     // Reset all mailbox\r
1037     CAN_ResetAllMailbox();\r
1038 \r
1039     // Enable the interrupt with all error cases\r
1040     AT91C_BASE_CAN0->CAN_IER =  AT91C_CAN_CERR  // (CAN) CRC Error\r
1041                              |  AT91C_CAN_SERR  // (CAN) Stuffing Error\r
1042                              |  AT91C_CAN_BERR  // (CAN) Bit Error\r
1043                              |  AT91C_CAN_FERR  // (CAN) Form Error\r
1044                              |  AT91C_CAN_AERR; // (CAN) Acknowledgment Error\r
1045 \r
1046 #if defined AT91C_BASE_CAN1\r
1047     if( canTransfer1 != NULL ) {\r
1048         AT91C_BASE_CAN1->CAN_IER =  AT91C_CAN_CERR  // (CAN) CRC Error\r
1049                                  |  AT91C_CAN_SERR  // (CAN) Stuffing Error\r
1050                                  |  AT91C_CAN_BERR  // (CAN) Bit Error\r
1051                                  |  AT91C_CAN_FERR  // (CAN) Form Error\r
1052                                  |  AT91C_CAN_AERR; // (CAN) Acknowledgment Error\r
1053     }\r
1054 #endif\r
1055 \r
1056     // Wait for CAN synchronisation\r
1057     if( CAN_Synchronisation( ) == 1 ) {\r
1058         ret = 1;\r
1059     }\r
1060     else {\r
1061         ret = 0;\r
1062     }\r
1063 \r
1064     return ret;\r
1065 }\r
1066 \r