OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_AT91SAM3U256_IAR/] [AT91Lib/] [peripherals/] [can/] [can.c] - Blame information for rev 763

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.