/* ---------------------------------------------------------------------------- | |
* ATMEL Microcontroller Software Support | |
* ---------------------------------------------------------------------------- | |
* Copyright (c) 2008, Atmel Corporation | |
* | |
* All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are met: | |
* | |
* - Redistributions of source code must retain the above copyright notice, | |
* this list of conditions and the disclaimer below. | |
* | |
* Atmel's name may not be used to endorse or promote products derived from | |
* this software without specific prior written permission. | |
* | |
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR | |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | |
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, | |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | |
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | |
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
* ---------------------------------------------------------------------------- | |
*/ | |
//------------------------------------------------------------------------------ | |
// Headers | |
//------------------------------------------------------------------------------ | |
#include <board.h> | |
#include <pio/pio.h> | |
#include <utility/trace.h> | |
#include <aic/aic.h> | |
#include "can.h" | |
//------------------------------------------------------------------------------ | |
// Local definitions | |
//------------------------------------------------------------------------------ | |
// CAN state | |
#define CAN_DISABLED 0 | |
#define CAN_HALTED 1 | |
#define CAN_IDLE 2 | |
#define CAN_SENDING 3 | |
#define CAN_RECEIVING 4 | |
// MOT: Mailbox Object Type | |
#define CAN_MOT_DISABLE 0 // Mailbox is disabled | |
#define CAN_MOT_RECEPT 1 // Reception Mailbox | |
#define CAN_MOT_RECEPT_OW 2 // Reception mailbox with overwrite | |
#define CAN_MOT_TRANSMIT 3 // Transmit mailbox | |
#define CAN_MOT_CONSUMER 4 // Consumer mailbox | |
#define CAN_MOT_PRODUCER 5 // Producer mailbox | |
//------------------------------------------------------------------------------ | |
// Local variables | |
//------------------------------------------------------------------------------ | |
#if defined (PINS_CAN_TRANSCEIVER_TXD) | |
static const Pin pins_can_transceiver_txd[] = {PINS_CAN_TRANSCEIVER_TXD}; | |
#endif | |
#if defined (PINS_CAN_TRANSCEIVER_RXD) | |
static const Pin pins_can_transceiver_rxd[] = {PINS_CAN_TRANSCEIVER_RXD}; | |
#endif | |
static const Pin pin_can_transceiver_rs = PIN_CAN_TRANSCEIVER_RS; | |
#if defined (PIN_CAN_TRANSCEIVER_RXEN) | |
static const Pin pin_can_transceiver_rxen = PIN_CAN_TRANSCEIVER_RXEN; | |
#endif | |
static CanTransfer *pCAN0Transfer=NULL; | |
#ifdef AT91C_BASE_CAN1 | |
static CanTransfer *pCAN1Transfer=NULL; | |
#endif | |
//------------------------------------------------------------------------------ | |
// Local functions | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
/// CAN Error Detection | |
/// \param status error type | |
/// \param can_number can nulber | |
//------------------------------------------------------------------------------ | |
static void CAN_ErrorHandling( unsigned int status, unsigned char can_number) | |
{ | |
if( (status&AT91C_CAN_ERRA) == AT91C_CAN_ERRA) { | |
TRACE_ERROR("(CAN) CAN is in active Error Active mode\n\r"); | |
} | |
else if( (status&AT91C_CAN_ERRP) == AT91C_CAN_ERRP) { | |
TRACE_ERROR("(CAN) CAN is in Error Passive mode\n\r"); | |
} | |
else if( (status&AT91C_CAN_BOFF) == AT91C_CAN_BOFF) { | |
TRACE_ERROR("(CAN) CAN is in Buff Off mode\n\r"); | |
// CAN reset | |
TRACE_ERROR("(CAN) CAN%d reset\n\r", can_number); | |
// CAN Controller Disable | |
if (can_number == 0) { | |
AT91C_BASE_CAN0->CAN_MR &= ~AT91C_CAN_CANEN; | |
// CAN Controller Enable | |
AT91C_BASE_CAN0->CAN_MR |= AT91C_CAN_CANEN; | |
} | |
#ifdef AT91C_BASE_CAN1 | |
else if (can_number == 1) { | |
AT91C_BASE_CAN1->CAN_MR &= ~AT91C_CAN_CANEN; | |
// CAN Controller Enable | |
AT91C_BASE_CAN1->CAN_MR |= AT91C_CAN_CANEN; | |
} | |
#endif | |
} | |
// Error for Frame dataframe | |
// CRC error | |
if( (status&AT91C_CAN_CERR) == AT91C_CAN_CERR) { | |
TRACE_ERROR("(CAN) CRC Error\n\r"); | |
} | |
// Bit-stuffing error | |
else if( (status&AT91C_CAN_SERR) == AT91C_CAN_SERR) { | |
TRACE_ERROR("(CAN) Stuffing Error\n\r"); | |
} | |
// Bit error | |
else if( (status&AT91C_CAN_BERR) == AT91C_CAN_BERR) { | |
TRACE_ERROR("(CAN) Bit Error\n\r"); | |
} | |
// Form error | |
else if( (status&AT91C_CAN_FERR) == AT91C_CAN_FERR) { | |
TRACE_ERROR("(CAN) Form Error\n\r"); | |
} | |
// Acknowledgment error | |
else if( (status&AT91C_CAN_AERR) == AT91C_CAN_AERR) { | |
TRACE_ERROR("(CAN) Acknowledgment Error\n\r"); | |
} | |
// Error interrupt handler | |
// Represent the current status of the CAN bus and are not latched. | |
// See CAN, par. Error Interrupt Handler | |
// AT91C_CAN_WARN | |
// AT91C_CAN_ERRA | |
} | |
//------------------------------------------------------------------------------ | |
// Generic CAN Interrupt handler | |
/// \param can_number can nulber | |
//------------------------------------------------------------------------------ | |
static void CAN_Handler( unsigned char can_number ) | |
{ | |
AT91PS_CAN base_can; | |
AT91PS_CAN_MB CAN_Mailbox; | |
unsigned int status; | |
unsigned int can_msr; | |
unsigned int* pCan_mcr; | |
unsigned int message_mode; | |
unsigned char numMailbox; | |
unsigned char state0=CAN_DISABLED; | |
unsigned char state1=CAN_DISABLED; | |
if( can_number == 0 ) { | |
base_can = AT91C_BASE_CAN0; | |
CAN_Mailbox = AT91C_BASE_CAN0_MB0; | |
state0 = pCAN0Transfer->state; | |
} | |
#ifdef AT91C_BASE_CAN1 | |
else { | |
base_can = AT91C_BASE_CAN1; | |
CAN_Mailbox = AT91C_BASE_CAN1_MB0; | |
state1 = pCAN1Transfer->state; | |
} | |
#endif | |
status = (base_can->CAN_SR) & (base_can->CAN_IMR); | |
base_can->CAN_IDR = status; | |
TRACE_DEBUG("CAN0 status=0x%X\n\r", status); | |
if(status & AT91C_CAN_WAKEUP) { | |
if( can_number == 0 ) { | |
pCAN0Transfer->test_can = AT91C_TEST_OK; | |
pCAN0Transfer->state = CAN_IDLE; | |
} | |
#ifdef AT91C_BASE_CAN1 | |
else { | |
pCAN1Transfer->test_can = AT91C_TEST_OK; | |
pCAN1Transfer->state = CAN_IDLE; | |
} | |
#endif | |
} | |
// Mailbox event ? | |
else if ((status&0x0000FFFF) != 0) { | |
TRACE_DEBUG("Mailbox event\n\r"); | |
// Handle Mailbox interrupts | |
for (numMailbox = 0; numMailbox < NUM_MAILBOX_MAX; numMailbox++) { | |
can_msr = *(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x10+(0x20*numMailbox))); | |
if ((AT91C_CAN_MRDY & can_msr) == AT91C_CAN_MRDY) { | |
// Mailbox object type | |
message_mode = ((*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x00+(0x20*numMailbox))))>>24)&0x7; | |
TRACE_DEBUG("message_mode 0x%X\n\r", message_mode); | |
TRACE_DEBUG("numMailbox 0x%X\n\r", numMailbox); | |
if( message_mode == 0 ) { | |
TRACE_ERROR("Error in MOT\n\r"); | |
} | |
else if( ( message_mode == CAN_MOT_RECEPT ) | |
|| ( message_mode == CAN_MOT_RECEPT_OW ) | |
|| ( message_mode == CAN_MOT_PRODUCER ) ) { | |
TRACE_DEBUG("Mailbox is in RECEPTION\n\r"); | |
TRACE_DEBUG("Length 0x%X\n\r", (can_msr>>16)&0xF); | |
TRACE_DEBUG("CAN_MB_MID 0x%X\n\r", ((*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x08+(0x20*numMailbox)))&AT91C_CAN_MIDvA)>>18)); | |
TRACE_DEBUG("can_number %d\n\r", can_number); | |
if( can_number == 0 ) { | |
//CAN_MB_MDLx | |
pCAN0Transfer->data_low_reg = | |
(*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x14+(0x20*numMailbox)))); | |
//CAN_MB_MDHx | |
pCAN0Transfer->data_high_reg = | |
(*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x18+(0x20*numMailbox)))); | |
pCAN0Transfer->size = (can_msr>>16)&0xF; | |
pCAN0Transfer->mailbox_number = numMailbox; | |
state0 = CAN_IDLE; | |
} | |
#ifdef AT91C_BASE_CAN1 | |
else { | |
//CAN_MB_MDLx | |
pCAN1Transfer->data_low_reg = | |
(*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x14+(0x20*numMailbox)))); | |
//CAN_MB_MDHx | |
pCAN1Transfer->data_high_reg = | |
(*(unsigned int*)((unsigned int)CAN_Mailbox+(unsigned int)(0x18+(0x20*numMailbox)))); | |
pCAN1Transfer->size = (can_msr>>16)&0xF; | |
pCAN1Transfer->mailbox_number = numMailbox; | |
state1 = CAN_IDLE; | |
} | |
#endif | |
// Message Data has been received | |
pCan_mcr = (unsigned int*)((unsigned int)CAN_Mailbox+0x1C+(0x20*numMailbox)); | |
*pCan_mcr = AT91C_CAN_MTCR; | |
} | |
else { | |
TRACE_DEBUG("Mailbox is in TRANSMIT\n\r"); | |
TRACE_DEBUG("Length 0x%X\n\r", (can_msr>>16)&0xF); | |
TRACE_DEBUG("can_number %d\n\r", can_number); | |
if( can_number == 0 ) { | |
state0 = CAN_IDLE; | |
} | |
else { | |
state1 = CAN_IDLE; | |
} | |
} | |
} | |
} | |
if( can_number == 0 ) { | |
pCAN0Transfer->state = state0; | |
} | |
#ifdef AT91C_BASE_CAN1 | |
else { | |
pCAN1Transfer->state = state1; | |
} | |
#endif | |
} | |
if ((status&0xFFCF0000) != 0) { | |
CAN_ErrorHandling(status, 0); | |
} | |
} | |
//------------------------------------------------------------------------------ | |
/// CAN 0 Interrupt handler | |
//------------------------------------------------------------------------------ | |
static void CAN0_Handler(void) | |
{ | |
CAN_Handler( 0 ); | |
} | |
//------------------------------------------------------------------------------ | |
/// CAN 1 Interrupt handler | |
//------------------------------------------------------------------------------ | |
#if defined AT91C_BASE_CAN1 | |
static void CAN1_Handler(void) | |
{ | |
CAN_Handler( 1 ); | |
} | |
#endif | |
//------------------------------------------------------------------------------ | |
// Global functions | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
/// Configure the corresponding mailbox | |
/// \param pTransfer can transfer structure | |
//------------------------------------------------------------------------------ | |
void CAN_InitMailboxRegisters( CanTransfer *pTransfer ) | |
{ | |
AT91PS_CAN base_can; | |
AT91PS_CAN_MB CAN_Mailbox; | |
if( pTransfer->can_number == 0 ) { | |
base_can = AT91C_BASE_CAN0; | |
CAN_Mailbox = AT91C_BASE_CAN0_MB0; | |
} | |
#ifdef AT91C_BASE_CAN1 | |
else { | |
base_can = AT91C_BASE_CAN1; | |
CAN_Mailbox = AT91C_BASE_CAN1_MB0; | |
} | |
#endif | |
CAN_Mailbox = (AT91PS_CAN_MB)((unsigned int)CAN_Mailbox+(unsigned int)(0x20*pTransfer->mailbox_number)); | |
pTransfer->mailbox_in_use |= 1<<(pTransfer->mailbox_number); | |
// MailBox Control Register | |
CAN_Mailbox->CAN_MB_MCR = 0x0; | |
// MailBox Mode Register | |
CAN_Mailbox->CAN_MB_MMR = 0x00; | |
// CAN Message Acceptance Mask Register | |
CAN_Mailbox->CAN_MB_MAM = pTransfer->acceptance_mask_reg; | |
// MailBox ID Register | |
// Disable the mailbox before writing to CAN_MIDx registers | |
if( (pTransfer->identifier & AT91C_CAN_MIDE) == AT91C_CAN_MIDE ) { | |
// Extended | |
CAN_Mailbox->CAN_MB_MAM |= AT91C_CAN_MIDE; | |
} | |
else { | |
CAN_Mailbox->CAN_MB_MAM &= ~AT91C_CAN_MIDE; | |
} | |
CAN_Mailbox->CAN_MB_MID = pTransfer->identifier; | |
// MailBox Mode Register | |
CAN_Mailbox->CAN_MB_MMR = pTransfer->mode_reg; | |
// MailBox Data Low Register | |
CAN_Mailbox->CAN_MB_MDL = pTransfer->data_low_reg; | |
// MailBox Data High Register | |
CAN_Mailbox->CAN_MB_MDH = pTransfer->data_high_reg; | |
// MailBox Control Register | |
CAN_Mailbox->CAN_MB_MCR = pTransfer->control_reg; | |
} | |
//------------------------------------------------------------------------------ | |
/// Reset the MBx | |
//------------------------------------------------------------------------------ | |
void CAN_ResetAllMailbox( void ) | |
{ | |
unsigned char i; | |
#if defined (AT91C_BASE_CAN0_MB0) | |
CAN_ResetTransfer( pCAN0Transfer ); | |
for( i=0; i<8; i++ ) { | |
pCAN0Transfer->can_number = 0; | |
pCAN0Transfer->mailbox_number = i; | |
pCAN0Transfer->mode_reg = AT91C_CAN_MOT_DIS; | |
pCAN0Transfer->acceptance_mask_reg = 0; | |
pCAN0Transfer->identifier = 0; | |
pCAN0Transfer->data_low_reg = 0x00000000; | |
pCAN0Transfer->data_high_reg = 0x00000000; | |
pCAN0Transfer->control_reg = 0x00000000; | |
CAN_InitMailboxRegisters( pCAN0Transfer ); | |
} | |
#endif | |
#if defined (AT91C_BASE_CAN0_MB8) | |
for( i=0; i<8; i++ ) { | |
pCAN0Transfer->can_number = 0; | |
pCAN0Transfer->mailbox_number = i+8; | |
pCAN0Transfer->mode_reg = AT91C_CAN_MOT_DIS; | |
pCAN0Transfer->acceptance_mask_reg = 0; | |
pCAN0Transfer->identifier = 0; | |
pCAN0Transfer->data_low_reg = 0x00000000; | |
pCAN0Transfer->data_high_reg = 0x00000000; | |
pCAN0Transfer->control_reg = 0x00000000; | |
CAN_InitMailboxRegisters( pCAN0Transfer ); | |
} | |
#endif | |
#if defined (AT91C_BASE_CAN1_MB0) | |
if( pCAN1Transfer != NULL ) { | |
CAN_ResetTransfer( pCAN1Transfer ); | |
for( i=0; i<8; i++ ) { | |
pCAN1Transfer->can_number = 1; | |
pCAN1Transfer->mailbox_number = i; | |
pCAN1Transfer->mode_reg = AT91C_CAN_MOT_DIS; | |
pCAN1Transfer->acceptance_mask_reg = 0; | |
pCAN1Transfer->identifier = 0; | |
pCAN1Transfer->data_low_reg = 0x00000000; | |
pCAN1Transfer->data_high_reg = 0x00000000; | |
pCAN1Transfer->control_reg = 0x00000000; | |
CAN_InitMailboxRegisters( pCAN1Transfer ); | |
} | |
} | |
#endif | |
#if defined (AT91C_BASE_CAN1_MB8) | |
if( pCAN1Transfer != NULL ) { | |
for( i=0; i<8; i++ ) { | |
pCAN1Transfer->can_number = 1; | |
pCAN1Transfer->mailbox_number = i+8; | |
pCAN1Transfer->mode_reg = AT91C_CAN_MOT_DIS; | |
pCAN1Transfer->acceptance_mask_reg = 0; | |
pCAN1Transfer->identifier = 0; | |
pCAN1Transfer->data_low_reg = 0x00000000; | |
pCAN1Transfer->data_high_reg = 0x00000000; | |
pCAN1Transfer->control_reg = 0x00000000; | |
CAN_InitMailboxRegisters( pCAN1Transfer ); | |
} | |
} | |
#endif | |
} | |
//------------------------------------------------------------------------------ | |
/// CAN reset Transfer descriptor | |
/// \param pTransfer can transfer structure | |
//------------------------------------------------------------------------------ | |
void CAN_ResetTransfer( CanTransfer *pTransfer ) | |
{ | |
pTransfer->state = CAN_IDLE; | |
pTransfer->can_number = 0; | |
pTransfer->mailbox_number = 0; | |
pTransfer->test_can = 0; | |
pTransfer->mode_reg = 0; | |
pTransfer->acceptance_mask_reg = 0; | |
pTransfer->identifier = 0; | |
pTransfer->data_low_reg = 0; | |
pTransfer->data_high_reg = 0; | |
pTransfer->control_reg = 0; | |
pTransfer->mailbox_in_use = 0; | |
pTransfer->size = 0; | |
} | |
//------------------------------------------------------------------------------ | |
/// Wait for CAN synchronisation | |
/// \return return 1 for good initialisation, otherwise return 0 | |
//------------------------------------------------------------------------------ | |
static unsigned char CAN_Synchronisation( void ) | |
{ | |
unsigned int tick=0; | |
TRACE_INFO("CAN_Synchronisation\n\r"); | |
pCAN0Transfer->test_can = AT91C_TEST_NOK; | |
#ifdef AT91C_BASE_CAN1 | |
if( pCAN1Transfer != NULL ) { | |
pCAN1Transfer->test_can = AT91C_TEST_NOK; | |
} | |
#endif | |
// Enable CAN and Wait for WakeUp Interrupt | |
AT91C_BASE_CAN0->CAN_IER = AT91C_CAN_WAKEUP; | |
// CAN Controller Enable | |
AT91C_BASE_CAN0->CAN_MR = AT91C_CAN_CANEN; | |
// Enable Autobaud/Listen mode | |
// dangerous, CAN not answer in this mode | |
while( (pCAN0Transfer->test_can != AT91C_TEST_OK) | |
&& (tick < AT91C_CAN_TIMEOUT) ) { | |
tick++; | |
} | |
if (tick == AT91C_CAN_TIMEOUT) { | |
TRACE_ERROR("CAN0 Initialisations FAILED\n\r"); | |
return 0; | |
} else { | |
TRACE_INFO("CAN0 Initialisations Completed\n\r"); | |
} | |
#if defined AT91C_BASE_CAN1 | |
if( pCAN1Transfer != NULL ) { | |
AT91C_BASE_CAN1->CAN_IER = AT91C_CAN_WAKEUP; | |
// CAN Controller Enable | |
AT91C_BASE_CAN1->CAN_MR = AT91C_CAN_CANEN; | |
tick = 0; | |
// Wait for WAKEUP flag raising <=> 11-recessive-bit were scanned by the transceiver | |
while( ((pCAN1Transfer->test_can != AT91C_TEST_OK)) | |
&& (tick < AT91C_CAN_TIMEOUT) ) { | |
tick++; | |
} | |
if (tick == AT91C_CAN_TIMEOUT) { | |
TRACE_ERROR("CAN1 Initialisations FAILED\n\r"); | |
return 0; | |
} else { | |
TRACE_INFO("CAN1 Initialisations Completed\n\r"); | |
} | |
} | |
#endif | |
return 1; | |
} | |
//------------------------------------------------------------------------------ | |
/// Write a CAN transfer | |
/// \param pTransfer can transfer structure | |
/// \return return CAN_STATUS_SUCCESS if command passed, otherwise | |
/// return CAN_STATUS_LOCKED | |
//------------------------------------------------------------------------------ | |
unsigned char CAN_Write( CanTransfer *pTransfer ) | |
{ | |
AT91PS_CAN base_can; | |
if (pTransfer->state == CAN_RECEIVING) { | |
pTransfer->state = CAN_IDLE; | |
} | |
if (pTransfer->state != CAN_IDLE) { | |
return CAN_STATUS_LOCKED; | |
} | |
TRACE_DEBUG("CAN_Write\n\r"); | |
pTransfer->state = CAN_SENDING; | |
if( pTransfer->can_number == 0 ) { | |
base_can = AT91C_BASE_CAN0; | |
} | |
#ifdef AT91C_BASE_CAN1 | |
else { | |
base_can = AT91C_BASE_CAN1; | |
} | |
#endif | |
base_can->CAN_TCR = pTransfer->mailbox_in_use; | |
base_can->CAN_IER = pTransfer->mailbox_in_use; | |
return CAN_STATUS_SUCCESS; | |
} | |
//------------------------------------------------------------------------------ | |
/// Read a CAN transfer | |
/// \param pTransfer can transfer structure | |
/// \return return CAN_STATUS_SUCCESS if command passed, otherwise | |
/// return CAN_STATUS_LOCKED | |
//------------------------------------------------------------------------------ | |
unsigned char CAN_Read( CanTransfer *pTransfer ) | |
{ | |
AT91PS_CAN base_can; | |
if (pTransfer->state != CAN_IDLE) { | |
return CAN_STATUS_LOCKED; | |
} | |
TRACE_DEBUG("CAN_Read\n\r"); | |
pTransfer->state = CAN_RECEIVING; | |
if( pTransfer->can_number == 0 ) { | |
base_can = AT91C_BASE_CAN0; | |
} | |
#ifdef AT91C_BASE_CAN1 | |
else { | |
base_can = AT91C_BASE_CAN1; | |
} | |
#endif | |
// enable interrupt | |
base_can->CAN_IER = pTransfer->mailbox_in_use; | |
return CAN_STATUS_SUCCESS; | |
} | |
//------------------------------------------------------------------------------ | |
/// Test if CAN is in IDLE state | |
/// \param pTransfer can transfer structure | |
/// \return return 0 if CAN is in IDLE, otherwise return 1 | |
//------------------------------------------------------------------------------ | |
unsigned char CAN_IsInIdle( CanTransfer *pTransfer ) | |
{ | |
return( pTransfer->state != CAN_IDLE ); | |
} | |
//------------------------------------------------------------------------------ | |
/// Basic CAN test without Interrupt | |
//------------------------------------------------------------------------------ | |
void CAN_BasicTestSuiteWithoutInterrupt(void) | |
{ | |
#if defined AT91C_BASE_CAN1 | |
unsigned int status; | |
unsigned int tick=0; | |
TRACE_INFO("Without Interrupt "); | |
TRACE_INFO("CAN0 Mailbox 0 transmitting to CAN1 Mailbox 0\n\r"); | |
// Init CAN0 Mailbox 0, transmit | |
CAN_ResetTransfer( pCAN0Transfer ); | |
pCAN0Transfer->can_number = 0; | |
pCAN0Transfer->mailbox_number = 0; | |
pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR; | |
pCAN0Transfer->acceptance_mask_reg = 0x00000000; | |
pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x07<<18); | |
pCAN0Transfer->data_low_reg = 0x11223344; | |
pCAN0Transfer->data_high_reg = 0x01234567; | |
pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); | |
CAN_InitMailboxRegisters( pCAN0Transfer ); | |
// Init CAN1 Mailbox 0, receive, | |
CAN_ResetTransfer( pCAN1Transfer ); | |
pCAN1Transfer->can_number = 1; | |
pCAN1Transfer->mailbox_number = 0; | |
pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RX; | |
pCAN1Transfer->acceptance_mask_reg = AT91C_CAN_MIDvA | AT91C_CAN_MIDvB; | |
pCAN1Transfer->identifier = AT91C_CAN_MIDvA & (0x07<<18); | |
pCAN1Transfer->data_low_reg = 0x00000000; | |
pCAN1Transfer->data_high_reg = 0x00000000; | |
pCAN1Transfer->control_reg = 0x00000000; | |
CAN_InitMailboxRegisters( pCAN1Transfer ); | |
// Transfer Request for Mailbox 0 | |
AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB0; | |
tick = 0; | |
do { | |
// CAN Message Status Register | |
status = AT91C_BASE_CAN0_MB0->CAN_MB_MSR; | |
} | |
while( !(status & AT91C_CAN_MRDY) && (++tick < AT91C_CAN_TIMEOUT) ); | |
if (tick == AT91C_CAN_TIMEOUT) { | |
TRACE_ERROR("Test FAILED\n\r"); | |
} | |
else { | |
TRACE_DEBUG("Transfer completed: CAN1 Mailbox 0 MRDY flag has raised\n\r"); | |
if( AT91C_BASE_CAN0_MB0->CAN_MB_MDL != AT91C_BASE_CAN1_MB0->CAN_MB_MDL ) { | |
TRACE_ERROR("Data Corrupted\n\r"); | |
} | |
else if( AT91C_BASE_CAN0_MB0->CAN_MB_MDH != AT91C_BASE_CAN1_MB0->CAN_MB_MDH ) { | |
TRACE_ERROR("Data Corrupted\n\r"); | |
} | |
else { | |
TRACE_INFO("Test passed\n\r"); | |
} | |
} | |
CAN_ResetAllMailbox(); | |
TRACE_INFO("Without Interrupt "); | |
TRACE_INFO("CAN0 Mailboxes 1 & 2 transmitting to CAN1 Mailbox 15\n\r"); | |
// Init CAN0 Mailbox 1, transmit | |
CAN_ResetTransfer( pCAN0Transfer ); | |
pCAN0Transfer->can_number = 0; | |
pCAN0Transfer->mailbox_number = 1; | |
pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR; | |
pCAN0Transfer->acceptance_mask_reg = 0x00000000; | |
pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x09<<18); // ID 9 | |
pCAN0Transfer->data_low_reg = 0xAABBCCDD; | |
pCAN0Transfer->data_high_reg = 0xCAFEDECA; | |
pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code | |
CAN_InitMailboxRegisters( pCAN0Transfer ); | |
// Init CAN0 Mailbox 2, transmit | |
pCAN0Transfer->can_number = 0; | |
pCAN0Transfer->mailbox_number = 2; | |
pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | (AT91C_CAN_PRIOR-(1<<16)); | |
pCAN0Transfer->acceptance_mask_reg = 0x00000000; | |
pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0A<<18); // ID 10 | |
pCAN0Transfer->data_low_reg = 0x55667788; | |
pCAN0Transfer->data_high_reg = 0x99AABBCC; | |
pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code | |
CAN_InitMailboxRegisters( pCAN0Transfer ); | |
// Init CAN1 Mailbox 15, reception with overwrite | |
CAN_ResetTransfer( pCAN1Transfer ); | |
pCAN1Transfer->can_number = 1; | |
pCAN1Transfer->mailbox_number = 15; | |
pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RXOVERWRITE; | |
pCAN1Transfer->acceptance_mask_reg = 0; | |
pCAN1Transfer->identifier = 0x0; | |
pCAN1Transfer->data_low_reg = 0x00000000; | |
pCAN1Transfer->data_high_reg = 0x00000000; | |
pCAN1Transfer->control_reg = 0x00000000; | |
CAN_InitMailboxRegisters( pCAN1Transfer ); | |
// Ask Transmissions on Mailbox 1 & 2 --> AT91C_CAN_MRDY & AT91C_CAN_MMI raises for Mailbox 15 CAN_MB_SR | |
AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB1 | AT91C_CAN_MB2; | |
// Wait for Last Transmit Mailbox | |
tick = 0; | |
do { | |
status = AT91C_BASE_CAN1_MB15->CAN_MB_MSR; | |
} | |
while( !(status & AT91C_CAN_MMI) && (++tick < AT91C_CAN_TIMEOUT) ); | |
if (tick == AT91C_CAN_TIMEOUT) { | |
} | |
else { | |
TRACE_DEBUG("Transfer completed: CAN1 Mailbox 15 MRDY and MMI flags have raised\n\r"); | |
if( AT91C_BASE_CAN0_MB1->CAN_MB_MDL != AT91C_BASE_CAN1_MB15->CAN_MB_MDL ) { | |
TRACE_ERROR("Data Corrupted\n\r"); | |
} | |
else if( AT91C_BASE_CAN0_MB1->CAN_MB_MDH != AT91C_BASE_CAN1_MB15->CAN_MB_MDH ) { | |
TRACE_ERROR("Data Corrupted\n\r"); | |
} | |
else { | |
TRACE_INFO("Test passed\n\r"); | |
} | |
} | |
CAN_ResetAllMailbox(); | |
TRACE_INFO("Without Interrupt "); | |
TRACE_INFO("CAN0 Mailboxes 1 & 2 transmitting to CAN1 Mailbox 15\n\r"); | |
// Init CAN0 Mailbox 1, transmit | |
CAN_ResetTransfer( pCAN0Transfer ); | |
pCAN0Transfer->can_number = 0; | |
pCAN0Transfer->mailbox_number = 1; | |
pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR; | |
pCAN0Transfer->acceptance_mask_reg = 0x00000000; | |
pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x09<<18); // ID 9 | |
pCAN0Transfer->data_low_reg = 0xAABBCCDD; | |
pCAN0Transfer->data_high_reg = 0xCAFEDECA; | |
pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code | |
CAN_InitMailboxRegisters( pCAN0Transfer ); | |
// Init CAN0 Mailbox 2, transmit | |
pCAN0Transfer->can_number = 0; | |
pCAN0Transfer->mailbox_number = 2; | |
pCAN0Transfer->mode_reg = AT91C_CAN_MOT_TX | (AT91C_CAN_PRIOR-(1<<16)); | |
pCAN0Transfer->acceptance_mask_reg = 0x00000000; | |
pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0A<<18); // ID 10 | |
pCAN0Transfer->data_low_reg = 0x55667788; | |
pCAN0Transfer->data_high_reg = 0x99AABBCC; | |
pCAN0Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); // Mailbox Data Length Code | |
CAN_InitMailboxRegisters( pCAN0Transfer ); | |
// Init CAN1 Mailbox 15, reception with overwrite | |
CAN_ResetTransfer( pCAN1Transfer ); | |
pCAN1Transfer->can_number = 1; | |
pCAN1Transfer->mailbox_number = 15; | |
pCAN1Transfer->mode_reg = AT91C_CAN_MOT_RX; | |
pCAN1Transfer->acceptance_mask_reg = 0; | |
pCAN1Transfer->identifier = 0x0; | |
pCAN1Transfer->data_low_reg = 0x00000000; | |
pCAN1Transfer->data_high_reg = 0x00000000; | |
pCAN1Transfer->control_reg = 0x00000000; | |
CAN_InitMailboxRegisters( pCAN1Transfer ); | |
// Ask Transmissions on Mailbox 1 & 2 --> AT91C_CAN_MRDY & AT91C_CAN_MMI raises for Mailbox 15 CAN_MB_SR | |
AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB1 | AT91C_CAN_MB2; | |
// Wait for Last Transmit Mailbox | |
tick = 0; | |
do { | |
status = AT91C_BASE_CAN1_MB15->CAN_MB_MSR; | |
} | |
while( !(status & AT91C_CAN_MMI) && (++tick < AT91C_CAN_TIMEOUT) ); | |
if (tick == AT91C_CAN_TIMEOUT) { | |
TRACE_ERROR("Test FAILED\n\r"); | |
} | |
else { | |
TRACE_DEBUG("Transfer completed: CAN1 Mailbox 15 MRDY and MMI flags have raised\n\r"); | |
TRACE_DEBUG("MB_MDL: 0x%X\n\r", AT91C_BASE_CAN1_MB15->CAN_MB_MDL); | |
TRACE_DEBUG("MB_MDLH: 0x%X\n\r", AT91C_BASE_CAN1_MB15->CAN_MB_MDH); | |
if( AT91C_BASE_CAN0_MB2->CAN_MB_MDL != AT91C_BASE_CAN1_MB15->CAN_MB_MDL ) { | |
TRACE_ERROR("Data Corrupted\n\r"); | |
} | |
else if( AT91C_BASE_CAN0_MB2->CAN_MB_MDH != AT91C_BASE_CAN1_MB15->CAN_MB_MDH ) { | |
TRACE_ERROR("Data Corrupted\n\r"); | |
} | |
else { | |
TRACE_INFO("Test passed\n\r"); | |
} | |
} | |
CAN_ResetAllMailbox(); | |
TRACE_INFO("Without Interrupt "); | |
TRACE_INFO("CAN0 Mailbox 3 asking for CAN1 Mailbox 3 transmission\n\r"); | |
// Init CAN0 Mailbox 3, consumer mailbox | |
// Sends a remote frame and waits for an answer | |
CAN_ResetTransfer( pCAN0Transfer ); | |
pCAN0Transfer->can_number = 0; | |
pCAN0Transfer->mailbox_number = 3; | |
pCAN0Transfer->mode_reg = AT91C_CAN_MOT_CONSUMER | AT91C_CAN_PRIOR; | |
pCAN0Transfer->acceptance_mask_reg = AT91C_CAN_MIDvA | AT91C_CAN_MIDvB; | |
pCAN0Transfer->identifier = AT91C_CAN_MIDvA & (0x0B<<18); // ID 11 | |
pCAN0Transfer->data_low_reg = 0x00000000; | |
pCAN0Transfer->data_high_reg = 0x00000000; | |
pCAN0Transfer->control_reg = 0x00000000; | |
CAN_InitMailboxRegisters( pCAN0Transfer ); | |
// Init CAN1 Mailbox 3, porducer mailbox | |
// Waits to receive a Remote Frame before sending its contents | |
CAN_ResetTransfer( pCAN1Transfer ); | |
pCAN1Transfer->can_number = 1; | |
pCAN1Transfer->mailbox_number = 3; | |
pCAN1Transfer->mode_reg = AT91C_CAN_MOT_PRODUCER | AT91C_CAN_PRIOR; | |
pCAN1Transfer->acceptance_mask_reg = 0; | |
pCAN1Transfer->identifier = AT91C_CAN_MIDvA & (0x0B<<18); // ID 11 | |
pCAN1Transfer->data_low_reg = 0xEEDDFF00; | |
pCAN1Transfer->data_high_reg = 0x34560022; | |
pCAN1Transfer->control_reg = (AT91C_CAN_MDLC & (0x8<<16)); | |
CAN_InitMailboxRegisters( pCAN1Transfer ); | |
// Ask Transmissions on Mailbox 3 --> AT91C_CAN_MRDY raises for Mailbox 3 CAN_MB_SR | |
AT91C_BASE_CAN1->CAN_TCR = AT91C_CAN_MB3; | |
AT91C_BASE_CAN0->CAN_TCR = AT91C_CAN_MB3; | |
// Wait for Last Transmit Mailbox | |
tick = 0; | |
do { | |
status = AT91C_BASE_CAN0_MB3->CAN_MB_MSR; | |
} | |
while( !(status & AT91C_CAN_MRDY) && (++tick < AT91C_CAN_TIMEOUT) ); | |
if (tick == AT91C_CAN_TIMEOUT) { | |
TRACE_ERROR("Test FAILED\n\r"); | |
} | |
else { | |
TRACE_DEBUG("Transfer Completed: CAN0 & CAN1 Mailboxes 3 MRDY flags have raised\n\r"); | |
if( AT91C_BASE_CAN0_MB3->CAN_MB_MDL != AT91C_BASE_CAN1_MB3->CAN_MB_MDL ) { | |
TRACE_ERROR("Data Corrupted\n\r"); | |
} | |
else if( AT91C_BASE_CAN0_MB3->CAN_MB_MDH != AT91C_BASE_CAN1_MB3->CAN_MB_MDH ) { | |
TRACE_ERROR("Data Corrupted\n\r"); | |
} | |
else { | |
TRACE_INFO("Test passed\n\r"); | |
} | |
} | |
#endif // AT91C_BASE_CAN1 | |
return; | |
} | |
//------------------------------------------------------------------------------ | |
/// Disable CAN and enter in low power | |
//------------------------------------------------------------------------------ | |
void CAN_disable( void ) | |
{ | |
// Disable the interrupt on the interrupt controller | |
AIC_DisableIT(AT91C_ID_CAN0); | |
// disable all IT | |
AT91C_BASE_CAN0->CAN_IDR = 0x1FFFFFFF; | |
#if defined AT91C_BASE_CAN1 | |
AIC_DisableIT(AT91C_ID_CAN1); | |
// disable all IT | |
AT91C_BASE_CAN1->CAN_IDR = 0x1FFFFFFF; | |
#endif | |
// Enable Low Power mode | |
AT91C_BASE_CAN0->CAN_MR |= AT91C_CAN_LPM; | |
// Disable CANs Transceivers | |
// Enter standby mode | |
PIO_Set(&pin_can_transceiver_rs); | |
#if defined (PIN_CAN_TRANSCEIVER_RXEN) | |
// Enable ultra Low Power mode | |
PIO_Clear(&pin_can_transceiver_rxen); | |
#endif | |
// Disable clock for CAN PIO | |
#if defined(AT91C_ID_PIOA) | |
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_PIOA); | |
#elif defined(AT91C_ID_PIOABCD) | |
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_PIOABCD); | |
#elif defined(AT91C_ID_PIOABCDE) | |
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_PIOABCDE); | |
#endif | |
// Disable the CAN0 controller peripheral clock | |
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_CAN0); | |
} | |
//------------------------------------------------------------------------------ | |
/// baudrate calcul | |
/// \param base_CAN CAN base address | |
/// \param baudrate Baudrate value (kB/s) | |
/// allowed values: 1000, 800, 500, 250, 125, 50, 25, 10 | |
/// \return return 1 in success, otherwise return 0 | |
//------------------------------------------------------------------------------ | |
unsigned char CAN_BaudRateCalculate( AT91PS_CAN base_CAN, | |
unsigned int baudrate ) | |
{ | |
unsigned int BRP; | |
unsigned int PROPAG; | |
unsigned int PHASE1; | |
unsigned int PHASE2; | |
unsigned int SJW; | |
unsigned int t1t2; | |
unsigned char TimeQuanta; | |
base_CAN->CAN_BR = 0; | |
if( baudrate == 1000) { | |
TimeQuanta = 8; | |
} | |
else { | |
TimeQuanta = 16; | |
} | |
BRP = (BOARD_MCK / (baudrate*1000*TimeQuanta))-1; | |
//TRACE_DEBUG("BRP = 0x%X\n\r", BRP); | |
// timing Delay: | |
// Delay Bus Driver: 50 ns | |
// Delay Receiver: 30 ns | |
// Delay Bus Line (20m): 110 ns | |
if( (TimeQuanta*baudrate*2*(50+30+110)/1000000) >= 1) { | |
PROPAG = (TimeQuanta*baudrate*2*(50+30+110)/1000000)-1; | |
} | |
else { | |
PROPAG = 0; | |
} | |
//TRACE_DEBUG("PROPAG = 0x%X\n\r", PROPAG); | |
t1t2 = TimeQuanta-1-(PROPAG+1); | |
//TRACE_DEBUG("t1t2 = 0x%X\n\r", t1t2); | |
if( (t1t2 & 0x01) == 0x01 ) { | |
// ODD | |
//TRACE_DEBUG("ODD\n\r"); | |
PHASE1 = ((t1t2-1)/2)-1; | |
PHASE2 = PHASE1+1; | |
} | |
else { | |
// EVEN | |
//TRACE_DEBUG("EVEN\n\r"); | |
PHASE1 = (t1t2/2)-1; | |
PHASE2 = PHASE1; | |
} | |
//TRACE_DEBUG("PHASE1 = 0x%X\n\r", PHASE1); | |
//TRACE_DEBUG("PHASE2 = 0x%X\n\r", PHASE2); | |
if( 1 > (4/(PHASE1+1)) ) { | |
//TRACE_DEBUG("4*Tcsc\n\r"); | |
SJW = 3; | |
} | |
else { | |
//TRACE_DEBUG("Tphs1\n\r"); | |
SJW = PHASE1; | |
} | |
//TRACE_DEBUG("SJW = 0x%X\n\r", SJW); | |
// Verif | |
if( BRP == 0 ) { | |
TRACE_DEBUG("BRP = 0 is not authorized\n\r"); | |
return 0; | |
} | |
if( (PROPAG + PHASE1 + PHASE2) != (TimeQuanta-4) ) { | |
TRACE_DEBUG("Pb (PROPAG + PHASE1 + PHASE2) = %d\n\r", PROPAG + PHASE1 + PHASE2); | |
TRACE_DEBUG("with TimeQuanta-4 = %d\n\r", TimeQuanta-4); | |
return 0; | |
} | |
base_CAN->CAN_BR = (AT91C_CAN_PHASE2 & (PHASE2 << 0)) | |
+ (AT91C_CAN_PHASE1 & (PHASE1 << 4)) | |
+ (AT91C_CAN_PROPAG & (PROPAG << 8)) | |
+ (AT91C_CAN_SYNC & (SJW << 12)) | |
+ (AT91C_CAN_BRP & (BRP << 16)) | |
+ (AT91C_CAN_SMP & (0 << 24)); | |
return 1; | |
} | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
/// Init of the CAN peripheral | |
/// \param baudrate Baudrate value (kB/s) | |
/// allowed values: 1000, 800, 500, 250, 125, 50, 25, 10 | |
/// \param canTransfer0 CAN0 structure transfer | |
/// \param canTransfer1 CAN1 structure transfer | |
/// \return return 1 if CAN has good baudrate and CAN is synchronized, | |
/// otherwise return 0 | |
//------------------------------------------------------------------------------ | |
unsigned char CAN_Init( unsigned int baudrate, | |
CanTransfer *canTransfer0, | |
CanTransfer *canTransfer1 ) | |
{ | |
unsigned char ret; | |
// CAN Transmit Serial Data | |
#if defined (PINS_CAN_TRANSCEIVER_TXD) | |
PIO_Configure(pins_can_transceiver_txd, PIO_LISTSIZE(pins_can_transceiver_txd)); | |
#endif | |
#if defined (PINS_CAN_TRANSCEIVER_RXD) | |
// CAN Receive Serial Data | |
PIO_Configure(pins_can_transceiver_rxd, PIO_LISTSIZE(pins_can_transceiver_rxd)); | |
#endif | |
// CAN RS | |
PIO_Configure(&pin_can_transceiver_rs, PIO_LISTSIZE(pin_can_transceiver_rs)); | |
#if defined (PIN_CAN_TRANSCEIVER_RXEN) | |
// CAN RXEN | |
PIO_Configure(&pin_can_transceiver_rxen, PIO_LISTSIZE(pin_can_transceiver_rxen)); | |
#endif | |
// Enable clock for CAN PIO | |
#if defined(AT91C_ID_PIOA) | |
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA); | |
#elif defined(AT91C_ID_PIOABCD) | |
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOABCD); | |
#elif defined(AT91C_ID_PIOABCDE) | |
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOABCDE); | |
#endif | |
// Enable the CAN0 controller peripheral clock | |
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_CAN0); | |
// disable all IT | |
AT91C_BASE_CAN0->CAN_IDR = 0x1FFFFFFF; | |
// Enable CANs Transceivers | |
#if defined (PIN_CAN_TRANSCEIVER_RXEN) | |
// Disable ultra Low Power mode | |
PIO_Set(&pin_can_transceiver_rxen); | |
#endif | |
// Normal Mode (versus Standby mode) | |
PIO_Clear(&pin_can_transceiver_rs); | |
// Configure the AIC for CAN interrupts | |
AIC_ConfigureIT(AT91C_ID_CAN0, AT91C_AIC_PRIOR_HIGHEST, CAN0_Handler); | |
// Enable the interrupt on the interrupt controller | |
AIC_EnableIT(AT91C_ID_CAN0); | |
if( CAN_BaudRateCalculate(AT91C_BASE_CAN0, baudrate) == 0 ) { | |
// Baudrate problem | |
TRACE_DEBUG("Baudrate CAN0 problem\n\r"); | |
return 0; | |
} | |
pCAN0Transfer = canTransfer0; | |
#if defined AT91C_BASE_CAN1 | |
if( canTransfer1 != NULL ) { | |
pCAN1Transfer = canTransfer1; | |
// Enable CAN1 Clocks | |
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_CAN1); | |
// disable all IT | |
AT91C_BASE_CAN1->CAN_IDR = 0x1FFFFFFF; | |
// Configure the AIC for CAN interrupts | |
AIC_ConfigureIT(AT91C_ID_CAN1, AT91C_AIC_PRIOR_HIGHEST, CAN1_Handler); | |
// Enable the interrupt on the interrupt controller | |
AIC_EnableIT(AT91C_ID_CAN1); | |
if( CAN_BaudRateCalculate(AT91C_BASE_CAN1, baudrate) == 0 ) { | |
// Baudrate problem | |
TRACE_DEBUG("Baudrate CAN1 problem\n\r"); | |
return 0; | |
} | |
} | |
#endif | |
// Reset all mailbox | |
CAN_ResetAllMailbox(); | |
// Enable the interrupt with all error cases | |
AT91C_BASE_CAN0->CAN_IER = AT91C_CAN_CERR // (CAN) CRC Error | |
| AT91C_CAN_SERR // (CAN) Stuffing Error | |
| AT91C_CAN_BERR // (CAN) Bit Error | |
| AT91C_CAN_FERR // (CAN) Form Error | |
| AT91C_CAN_AERR; // (CAN) Acknowledgment Error | |
#if defined AT91C_BASE_CAN1 | |
if( canTransfer1 != NULL ) { | |
AT91C_BASE_CAN1->CAN_IER = AT91C_CAN_CERR // (CAN) CRC Error | |
| AT91C_CAN_SERR // (CAN) Stuffing Error | |
| AT91C_CAN_BERR // (CAN) Bit Error | |
| AT91C_CAN_FERR // (CAN) Form Error | |
| AT91C_CAN_AERR; // (CAN) Acknowledgment Error | |
} | |
#endif | |
// Wait for CAN synchronisation | |
if( CAN_Synchronisation( ) == 1 ) { | |
ret = 1; | |
} | |
else { | |
ret = 0; | |
} | |
return ret; | |
} | |