📄 can_test.c
字号:
/******************************************************************************
** **
** Name: CAN_test.c **
** **
*******************************************************************************
(C) Copyright 2004 - Analog Devices, Inc. All rights reserved.
Date Modified:
Hardware: ADSP-BF538 EZ-KIT Rev. 0.0 Silicon
********************************************************************************/
#include <cdefBF538.h>
#include <ccblkfn.h>
#include <sys/exception.h>
#include <signal.h>
#include "post_common.h"
#include "Pll.h"
#include "Timer_ISR.h"
//--------------------------------------------------------------------------//
// constant defines
//--------------------------------------------------------------------------//
#define CAN_RX_MB_LO 0x00FF // Mailboxes 0-7 are RX, 8 - 15 are TX
#define CAN_RX_MB_HI 0x0000 // Mailboxes 16 - 31 are TX
#define CAN_EN_MB_LO 0x00FF // Mailboxes 0-7 are RX, 8 - 15 are TX
#define CAN_EN_MB_HI 0xFF00 // Mailboxes 16 - 31 are TX
#define BUF_SIZE 1024
//--------------------------------------------------------------------------//
// data typedefs
//--------------------------------------------------------------------------//
typedef struct g_CAN_STAMP_BUF_TAG
{
short zero;
short one;
}g_CAN_STAMP_BUF_type;
//--------------------------------------------------------------------------//
// global data
//--------------------------------------------------------------------------//
short *g_CAN_RX_BUFFER;
g_CAN_STAMP_BUF_type *g_CAN_STAMP_BUF;
volatile unsigned short g_rx_buf_index = 0;
volatile unsigned short g_tx_buf_index = 0;
volatile unsigned short g_TX_Count = 0;
volatile unsigned short g_RX_Count = 0;
volatile unsigned short g_CAN_ERROR_FLAG = 0; // flag that can error isr sets
//--------------------------------------------------------------------------//
// test function prototypes //
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(CAN_RCV_HANDLER);
EX_INTERRUPT_HANDLER(CAN_XMT_HANDLER);
//--------------------------------------------------------------------------//
// Function: Init_CAN_Port //
// //
// Parameters: none //
// //
// Return: none
// //
// Description: sets up the CAN port for the test
// //
//--------------------------------------------------------------------------//
void Init_CAN_Port(void)
{
unsigned int nTimer;
short msgID;
char mbID;
volatile unsigned short *pCAN_Ptr;
*pSIC_IWR |= 0x1; // enable PLL wakeup
*pPLL_CTL = SET_MSEL(18); /* (25MHz Xtal x (MSEL=18))::CCLK=450MHz */
idle();
*pPLL_DIV = SET_SSEL(4); /* (450MHz/(SSEL=4))::SCLK=112.5MHz */
ssync();
*pVR_CTL = 0x04DB;
ssync();
// setup PORTD so that we can read CAN Error
*pPORTDIO_FER = 0x200; // PD9(CAN Error)
*pPORTDIO_INEN = 0x200; // Enable input buffer
*pPORTDIO_DIR &= (~0x200); // Setup port for inputs
// Configure Interrupt Priorities
*pSIC_IAR0 = 0x77777777;
*pSIC_IAR1 = 0x77777777;
*pSIC_IAR2 = 0x77777777;
*pSIC_IAR3 = 0x77777777;
*pSIC_IAR4 = 0x77777777;
*pSIC_IAR5 = 0x77777777;
*pSIC_IAR6 = 0x77777777;
/// init the CAN timing registers
// ===================================================
// BIT TIMING:
//
// CAN_CLOCK : Prescaler (BRP)
// CAN_TIMING : SJW = 3, TSEG2 = 5, TSEG1 = 2
//
// ===================================================
// Set Bit Configuration Registers ...
// ===================================================
*pCAN_TIMING = 0x0352;
*pCAN_CLOCK = 22; // 500kHz CAN Clock :: tBIT = 2us
//
// tBIT = TQ x (1 + (TSEG1 + 1) + (TSEG2 + 1))
// 2e-6 = TQ x (1 + 3 + 6)
// TQ = 2e-7
//
// TQ = (BRP+1) / SCLK
// 2e-7 = (BRP+1) / 112.5e6
// (BRP+1) = 21.6
// BRP = 21.5 = ~22
ssync();
/// init the CAN mail boxes and turn on the can ISR
g_CAN_STAMP_BUF = malloc( (sizeof(g_CAN_STAMP_BUF_type) * BUF_SIZE * 2) );
g_CAN_RX_BUFFER = malloc( (sizeof(short) * BUF_SIZE) );
/////////////////////////////////////////////////////////////////////////////////
// Mailboxes 24-31 are TX Only, They'll Transmit To the RX Only Mailboxes 0-7 //
// Mailbox 24 Transmits ID 0x200
msgID = 0x200;
for (mbID = 24; mbID<32; mbID++)
{
pCAN_Ptr = (unsigned short *)CAN_MB00_DATA0 + (0x10 * mbID);
*(pCAN_Ptr + 0) = msgID; // write msgID to DATA0
*(pCAN_Ptr + 2) = msgID; // write msgID to DATA1
*(pCAN_Ptr + 4) = msgID; // write msgID to DATA2
*(pCAN_Ptr + 6) = msgID; // write msgID to DATA3
*(pCAN_Ptr + 8) = 8; // write 8 to LENGTH
*(pCAN_Ptr + 10) = 0; // write 0 to TIMESTAMP
*(pCAN_Ptr + 12) = 0; // write 0 to ID0
*(pCAN_Ptr + 14) = (msgID << 2); // write msgID to ID1
msgID++; // Bump msgID to match Mailbox
} // end for (init TX mailbox area -- TX Only mailboxes)
/////////////////////////////////////////////////////////////////////////////////
// Mailboxes 0-7 are RX Only, They'll Receive From the TX Only Mailboxes 24-31 //
// Mailbox 0 Receives ID 0x200
msgID = 0x200;
for (mbID = 0; mbID<8; mbID++)
{
pCAN_Ptr = (unsigned short *)CAN_MB00_DATA0 + (0x10 * mbID);
*(pCAN_Ptr + 0) = 0; // write msgID to DATA0
*(pCAN_Ptr + 2) = 0; // write msgID to DATA1
*(pCAN_Ptr + 4) = 0; // write msgID to DATA2
*(pCAN_Ptr + 6) = 0; // write msgID to DATA3
*(pCAN_Ptr + 8) = 8; // write 8 to LENGTH
*(pCAN_Ptr + 10) = 0; // write 0 to TIMESTAMP
*(pCAN_Ptr + 12) = 0; // write 0 to ID0
*(pCAN_Ptr + 14) = (msgID << 2); // write msgID to ID1
msgID ++; // Bump msgID to match Mailbox
} // end for (init RX mailbox area -- RX Only mailboxes)
// enable the CAN and the mailboxes
*pCAN_MD1 = CAN_RX_MB_LO;
*pCAN_MD2 = CAN_RX_MB_HI;
// Enable All Mailboxes
*pCAN_MC1 = CAN_EN_MB_LO; // mailboxes 0-7
*pCAN_MC2 = CAN_EN_MB_HI; // mailboxes 24-31
ssync();
// Exit CAN Configuration Mode (Clear CCR)
*pCAN_CONTROL = 0;
// Wait for CAN Configuration Acknowledge (CCA)
nTimer = SetTimeout(10000);
if( ((unsigned int)-1) != nTimer )
{
do{
asm("nop;");
}while( (*pCAN_STATUS & CCA) && (!IsTimedout(nTimer)) );
}
ClearTimeout(nTimer);
*pCAN_MBIM1 = CAN_EN_MB_LO; // Enable Interrupt for Mailboxes 00-8
*pCAN_MBIM2 = CAN_EN_MB_HI; // Enable Interrupt for Mailboxes 24-31
ssync();
*pCAN_UCCNF = UCE|UC_WDOG; // enable Universal Counter in Watchdog mode
*pCAN_UCRC = 0xABBA; // unique value for timestamp checking
} // End Init_Port ()
//--------------------------------------------------------------------------//
// Function: EX_INTERRUPT_HANDLER(CAN_RCV_HANDLER) //
// //
// Parameters: none //
// //
// Return: none
// //
// Description: handles CAN RX ISR
// //
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(CAN_RCV_HANDLER)
{
unsigned short mbim_status;
unsigned short bit_pos = 0;
char mbID;
volatile unsigned short *pCAN_Ptr;
g_RX_Count++;
mbim_status = *pCAN_MBRIF1;
while (!(mbim_status & 0x8000))
{
mbim_status <<= 1;
bit_pos++;
}
mbID = (15 - bit_pos);
pCAN_Ptr = (unsigned short *)CAN_MB00_DATA0 + (0x10 * mbID);
g_CAN_RX_BUFFER[g_rx_buf_index] = *(pCAN_Ptr + 6);
g_CAN_STAMP_BUF[g_rx_buf_index + g_tx_buf_index].zero = ((*pCAN_Ptr + 8) >> 2);
g_CAN_STAMP_BUF[g_rx_buf_index + g_tx_buf_index].one = bit_pos + 16;
*pCAN_MBRIF1 = (1 << mbID);
ssync();
if(++g_rx_buf_index == BUF_SIZE)
g_rx_buf_index=0;
} // end CAN_RCV_HANDLER
//--------------------------------------------------------------------------//
// Function: EX_INTERRUPT_HANDLER(CAN_XMT_HANDLER) //
// //
// Parameters: none //
// //
// Return: none
// //
// Description: handles CAN TX ISR
// //
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(CAN_XMT_HANDLER)
{
unsigned short mbim_status;
unsigned short bit_pos = 0;
char mbID;
volatile unsigned short *pCAN_Ptr;
g_TX_Count++;
mbim_status = *pCAN_MBTIF2;
while (!(mbim_status & 0x8000))
{
mbim_status <<= 1;
bit_pos++;
}
mbID = (31 - bit_pos);
pCAN_Ptr = (unsigned short *)CAN_MB00_DATA0 + (0x10 * mbID);
g_CAN_STAMP_BUF[g_rx_buf_index + g_tx_buf_index].zero = ((*pCAN_Ptr + 0x0E) >> 2);
g_CAN_STAMP_BUF[g_rx_buf_index + g_tx_buf_index].one = *pCAN_UCCNT;
*pCAN_MBTIF2 = (1 << (15 - bit_pos));
ssync();
if(++g_tx_buf_index == BUF_SIZE)
g_tx_buf_index=0;
} // end CAN_XMT_HANDLER
//--------------------------------------------------------------------------//
// Function: CAN_Transmit //
// //
// Parameters: none //
// //
// Return: 1 if successful 0 if timeout
// //
// Description: Sends out the information in all the TX mail boxes
// //
//--------------------------------------------------------------------------//
int CAN_Transmit(void)
{
int nStatus = 0;
unsigned int delay;
unsigned int nTimer;
// Configure Interrupt Priorities
*pSIC_IAR6 = 0x77777774; // CAN TX IRQ : 4=IVG11
// Register Interrupt Handlers and Enable Core Interrupts
register_handler(ik_ivg11, CAN_XMT_HANDLER);
// Enable SIC Level Interrupts
*pSIC_IMASK1 |= (CAN_TX_IRQ);
nTimer = SetTimeout(0x1f0000);
if( ((unsigned int)-1) != nTimer )
{
do{
//// Set Transmit Requests for All TX Mailboxes
*pCAN_TRS1 = 0;
*pCAN_TRS2 = 0xFF00;
ssync();
if(g_TX_Count >= BUF_SIZE)
{
nStatus = 1;
break;
}
}while( !IsTimedout(nTimer) );
}
ClearTimeout(nTimer);
return nStatus;
} // End CAN_Transmit()
//--------------------------------------------------------------------------//
// Function: CAN_Receive //
// //
// Parameters: none //
// //
// Return: 1 if successful 0 if timeout
// //
// Description: Sends out the information in all the TX mail boxes
// //
//--------------------------------------------------------------------------//
int CAN_Receive(void)
{
int nStatus = 0;
unsigned int nTimer;
// Configure Interrupt Priorities
*pSIC_IAR5 = 0x47777777; // CAN RX IRQ : 4=IVG11
// Register Interrupt Handlers and Enable Core Interrupts
register_handler(ik_ivg11, CAN_RCV_HANDLER);
// Enable SIC Level Interrupts
*pSIC_IMASK1 |= (CAN_RX_IRQ);
nTimer = SetTimeout(0x1f0000); // this takes about 1.25 minutes to timeout
if( ((unsigned int)-1) != nTimer )
{
do{
if(g_RX_Count >= BUF_SIZE)
{
nStatus = 1;
break;
}
}while( !IsTimedout(nTimer) );
}
ClearTimeout(nTimer);
return nStatus;
} // End CAN_Receive()
//--------------------------------------------------------------------------//
// Function: TEST_CAN_RX //
// //
// Parameters: none //
// //
// Return: 1 - pass 0 - fail
// //
// Description: Send and receive data over CAN interface
// //
//--------------------------------------------------------------------------//
int TEST_CAN_RX(void)
{
int iStatus = 0;
int nTimer;
g_rx_buf_index = 0;
g_tx_buf_index = 0;
g_TX_Count = 0;
g_RX_Count = 0;
g_CAN_ERROR_FLAG = 0; // flag that can error isr sets
Init_Timers();
Init_Timer_Interrupts();
Init_CAN_Port();
iStatus = CAN_Receive(); // receive the data
if( 1 == iStatus )
{
nTimer = SetTimeout(0x800);
if( ((unsigned int)-1) != nTimer )
{
do{
asm("nop;");
}while( !IsTimedout(nTimer) );
}
ClearTimeout(nTimer);
iStatus = CAN_Transmit(); // transmit all the TX mailbox responses
}
// turn off interrupts so that the data is stable.
interrupt(ik_ivg11, SIG_IGN);
// disable SIC Level Interrupts
*pSIC_IMASK1 &= (~(CAN_RX_IRQ | CAN_TX_IRQ));
// free the memory allocated
if( NULL != g_CAN_STAMP_BUF )
{
free(g_CAN_STAMP_BUF);
g_CAN_STAMP_BUF = NULL;
}
if( NULL != g_CAN_RX_BUFFER )
{
free(g_CAN_RX_BUFFER);
g_CAN_RX_BUFFER = NULL;
}
if( !(*pPORTDIO & 0x200) )
{ // an error occured in the CAN test
iStatus = 0;
}
return iStatus;
}
//--------------------------------------------------------------------------//
// Function: TEST_CAN //
// //
// Parameters: none //
// //
// Return: 1 - pass 0 - fail
// //
// Description: Send and receive data over CAN interface
// //
//--------------------------------------------------------------------------//
int TEST_CAN_TX(void)
{
int iStatus = 0;
int nTimer;
g_rx_buf_index = 0;
g_tx_buf_index = 0;
g_TX_Count = 0;
g_RX_Count = 0;
g_CAN_ERROR_FLAG = 0; // flag that can error isr sets
Init_Timers();
Init_Timer_Interrupts();
Init_CAN_Port();
iStatus = CAN_Transmit(); // transmit all the TX mailboxes
if( 1 == iStatus )
{
nTimer = SetTimeout(0x800);
if( ((unsigned int)-1) != nTimer )
{
do{
asm("nop;");
}while( !IsTimedout(nTimer) );
}
ClearTimeout(nTimer);
iStatus = CAN_Receive(); // receive the responses
}
// turn off interrupts so that the data is stable.
interrupt(ik_ivg11, SIG_IGN);
// disable SIC Level Interrupts
*pSIC_IMASK1 &= (~(CAN_RX_IRQ | CAN_TX_IRQ));
// free the memory allocated
if( NULL != g_CAN_STAMP_BUF )
{
free(g_CAN_STAMP_BUF);
g_CAN_STAMP_BUF = NULL;
}
if( NULL != g_CAN_RX_BUFFER )
{
free(g_CAN_RX_BUFFER);
g_CAN_RX_BUFFER = NULL;
}
if( !(*pPORTDIO & 0x200) )
{ // an error occured in the CAN test
iStatus = 0;
}
return iStatus;
}
#ifdef _STANDALONE_ // use this to run standalone tests
main()
{
int i = 0;
Init_PLL();
Init_Timers();
Init_Timer_Interrupts();
#ifdef _CAN_TX_
i = TEST_CAN_TX();
#else
i = TEST_CAN_RX();
#endif
asm("nop;");
asm("emuexcpt;");
asm("nop;");
} // end main
#endif // _STANDALONE_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -