📄 can.c
字号:
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -