⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_can_sja1000.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* test_can_sja1000.c - Sample application using Windnet 1.4 CAN api */

/* Copyright */ 

/* 
modification history
---------------------
2007.11.20 created by kuangyw ,evoc
*/

/*
DESCRIPTION
This module is a sample application provided with the Windnet CAN api
documentation. The purpose is to demonstrate the use of CAN api, and
the sequence in which they must be called.
INCLUDE FILES:
*/

/* includes */
#include  <vxWorks.h>
#include  <stdio.h>
#include  <errnoLib.h>
#include  <CAN/wnCAN.h>
#include  <CAN/sja1000Offsets.h>
#include  <assert.h>
#include  <logLib.h>

/* defines */
/**************************************************************************/
#define DEMO_BOARD                  WNCAN_ESD_PC104_200
#define DEMO_CTRL0                  0
#define DEMO_CTRL1                  1

#define NUM_CTRLRS                  2

#define DEMO_ID0                    0x180
#define DEMO_ID1                    0x190

#define DEMO_TSEG1                  0xc
#define DEMO_TSEG2                  1
#define DEMO_BAUD_RATE_PRESCALAR    0x42/*3*/
#define DEMO_SJW                    0
#define DEMO_SAMPLES_BOOL           0  
#define DEMO_BAUD_RATE              125000

#define DEMO_PROP_SEG               0 
/**************************************************************************/
/* globals */
struct WNCAN_Device *pDev0=NULL;
struct WNCAN_Device *pDev1=NULL;

int flagAwake0;
ULONG id0[100];
BOOL extFlag0[100];

char recData[8];
char recvBuf[200];
 int recvLen = 0;

int ArrayIndex0;

int flagAwake1;
ULONG id1[100];
BOOL extFlag1[100];
int ArrayIndex1;

char can_send[]="abcdefgh"; 
int fd_can=0;

int can_open=0;

SEM_ID canRecvTaskSemId;

/* forward declarations */
void test_isr0(struct WNCAN_Device *pDev1, WNCAN_IntType intstatus,
               UCHAR channelNum);
void test_isr1(struct WNCAN_Device *pDev1, WNCAN_IntType intStatus,
               UCHAR channelNum);
int releaseNode(int);

/**************************************************************************
* 
* setupNode - Set up CAN ctrlr. 
*
* This routine does the following:
* 1. Get device pointer.
* 2. Initialize CAN controller.
* 3. Set bit timing values to enable baud rate of 125K
* 4. Set interrupt mask to enable all interrupts.
* 5. Enable Interrupts.
* 6. Set global receive filter to receive all standard identifiers.
* 7. Assign a channel for reception.
* 8. Set local filter for channel number 0 (channels numbered 0 to 1)
*    to receive all extended identifiers
* 9. Enable channel 0 for reception of extended identifiers.
* 10.Exit without bringing CAN controller online.
*
* RETURNS: OK or ERROR
*
* ERRNO:   N/A
*   
*/
int setupNode
(
 int ctrlr,int rate
 )
{
    struct WNCAN_Device *pDev;    
    ULONG testBaudRate;
    UINT  samplePoint;
    STATUS retCode = OK;
    UCHAR channelRx;

	int tseg1 = 0;
	int tseg2 = 0;
	int baud_rate_prescalar = 0;
    
    /*default settings*/    
    if(ctrlr == 1)
    {
        pDev1 = CAN_Open(DEMO_BOARD, 0, DEMO_CTRL1);   
        assert(pDev1);
        CAN_InstallISRCallback(pDev1, test_isr1);
        pDev = pDev1;
        ArrayIndex1 = 0;
        
    }
    else
    {
        pDev0 = CAN_Open(DEMO_BOARD, 0, DEMO_CTRL0);
        assert(pDev0);
        CAN_InstallISRCallback(pDev0, test_isr0);
        pDev = pDev0;
        ArrayIndex0 = 0;
        
    }

	printf("pDev0 = 0x%x\n",pDev0);
    
	switch(rate)
	{
		case 10:
			tseg1 = 0xc;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x65;
			break;
		case 20:
			tseg1 = 0xc;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x52;
			break;
		case 50:
			tseg1 = 0xc;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x47;
			break;
		case 100:
			tseg1 = 0xc;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x43;
			break;
		case 125:
			tseg1 = 0xc;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x42;
			break;
		case 250:
			tseg1 = 0xc;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x41;
			break;
		case 500:
			tseg1 = 0xc;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x40;
			break;
		case 800:
			tseg1 = 0x6;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x40;
			break;
		case 1000:
			tseg1 = 0x4;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x40;
			break;
        default:  
     			tseg1 = 0xc;
			tseg2 = 0x1;
			baud_rate_prescalar = 0x42;

			
	}

	pDev->pCtrl->brp = baud_rate_prescalar/*3*/;       
	pDev->pCtrl->sjw = DEMO_SJW;  
	pDev->pCtrl->tseg1 = tseg1;
	pDev->pCtrl->tseg2 = tseg2;
	pDev->pCtrl->samples = DEMO_SAMPLES_BOOL;
/*
        CAN_SetBitTiming(pDev, tseg1, tseg2, baud_rate_prescalar, 
            DEMO_SJW, DEMO_SAMPLES_BOOL);
*/
    CAN_Init(pDev);

    testBaudRate = CAN_GetBaudRate(pDev, &samplePoint);

	printf("testBaudRate = %d\n",testBaudRate);
	
#if 0    
    if(testBaudRate != rate*1000/*DEMO_BAUD_RATE*/)
    {
        logMsg("Resetting baud to %d\n", DEMO_BAUD_RATE,0,0,0,0,0);
        
        
        CAN_SetBitTiming(pDev, tseg1, tseg2, baud_rate_prescalar, 
            DEMO_SJW, DEMO_SAMPLES_BOOL);
        
        testBaudRate = CAN_GetBaudRate(pDev, &samplePoint);
        
        if(testBaudRate != rate/*DEMO_BAUD_RATE*/)
        {
			logMsg("**Unable to set %d baud with selected bit timing parameters \
					\n", DEMO_BAUD_RATE,0,0,0,0,0);

            logMsg("**If baud rate is off by a factor of 2, check the UMCR \
                    HSPEED bit setting\n",0,0,0,0,0,0);
			
			logMsg("**Adjust macro DEMO_BAUD_RATE_PRESCALAR defined at the \
                    begining of this file accordingly\n",0,0,0,0,0,0);
            
			releaseNode(ctrlr);
            
			return ERROR;            
        }
    }
#endif

    /* Enable interrupts */      
    CAN_SetIntMask(pDev, WNCAN_INT_ALL);
    CAN_EnableInt(pDev);    
    
    /* Set up global filter to receive all standard messages */
    retCode = CAN_SetGlobalRxFilter(pDev, 0, FALSE);
    if(retCode != OK)
        logMsg("Error: Set Global filter failed \n",0,0,0,0,0,0);
    
    
    /* Set up receive message buffer */
    CAN_GetRxChannel(pDev, &channelRx); 
	
    	printf("channelRx = %d\n",channelRx);

    /*
    * If set global filter failed, perhaps this controller has a local filter
    * that we could use.
    */
    if (retCode != OK)
        CAN_SetLocalMsgFilter(pDev, channelRx, 0, FALSE);   
    
    
    retCode = CAN_WriteID(pDev, channelRx, 0, FALSE);
    if(retCode != OK)   
    {
        logMsg("Error: Write ID failed on channel %d \n",channelRx,0,0,0,0,0);
        return ERROR;
    }
    
    CAN_EnableChannel(pDev, channelRx, WNCAN_INT_RX);
	
	CAN_Start(pDev);
     can_open = 1;
    return OK;
    
 }
 

 /**************************************************************************
 * 
 * transmitMsg - Transmit message using CAN_TxMsg
 * 
 * This function gets transmit channel and transmits message with standard
 * id 0x180, with eight data bytes.
 *
 * RETURNS: OK or ERROR
 *
 * ERRNO:   N/A
 *
 */
 int transmitMsg
     (
     int ctrlr,int id,int ext
     )
 {
     struct WNCAN_Device *pDev;
     /*ULONG id=DEMO_ID0; */
     STATUS retCode;
     UCHAR channelTx;    
     /*UCHAR data[8]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};  */ 
     
     if(ctrlr == 1)
     {
         pDev = pDev1; 
         /*id = DEMO_ID1;*/ 
     }
     else
         pDev = pDev0;   
     
     /*Check if pDev is valid*/     
     if(NULL==pDev){
         logMsg("Call setupNode first \n",0,0,0,0,0,0);
         return ERROR;
     }
     
     retCode = CAN_GetTxChannel(pDev, &channelTx);
	 
 	/*printf("channelTx = %d\n",channelTx);*/

     if(retCode != OK)
     {
         logMsg("Transmitter not available\n",0,0,0,0,0,0);         
         return ERROR;
     }
     
     CAN_EnableChannel(pDev, channelTx, WNCAN_INT_TX);
     
     retCode = CAN_TxMsg(pDev, channelTx, id, ext, can_send, 8);
	 
     if(retCode != OK)
     {
         logMsg("error in tx msg setup \n",0,0,0,0,0,0);
         return ERROR;
     }
     
     return OK;
     
 }

/*can总线发送函数*/
 void cansend(int rate,int id,int ext,int num)
{
	int  numSend = 0;

	assert((num>0)&&(rate>0));
	if(num > 10000000)
	{
	    printf("Number is too big! <10000000 !\r\n");
		return ERROR;
	}

	if(can_open)
	{
		releaseNode(0);
		setupNode(0,rate);
	}
	else
	{
		setupNode(0,rate);
	}
	
	printf("The send string is \"%s\" \r\n",can_send);
	
	for(numSend=0;numSend<num;numSend++)
	{
		transmitMsg(0,id,ext);

		printf("\r%d", numSend+1);

#if 1
		taskDelay(1);
#endif
	}
	
	releaseNode(0);

}

int canrec(int rate)
{

	int bytes_write=0;
	char buf[8];
	int fd=0;
	
	assert((rate>0));
	
	fd= creat("can_result.txt", O_RDWR);

	if(fd<0)
	{
		logMsg("creat can_result.txt failded!\r\n",0,0,0,0,0,0);
		return ERROR;
	}

	if(can_open)
	{
		releaseNode(0);
		setupNode(0,rate);
	}
	else
	{
		setupNode(0,rate);
	}
	
	for(;;)
	{
			/* wait for somebody to wake us up */

			/*semTake (canRecvTaskSemId, WAIT_FOREVER);*/
		
			if(strlen(recvBuf))
			{
				/* 把结果存入文件中*/
				bytes_write = write(fd,recvBuf,strlen(recvBuf));
				memset(recvBuf,0,strlen(recvBuf));
			}

			if(bytes_write<0)
			{
				printf("write data error \n");
				return ERROR;
			}
	}

	close(fd);

}

 /*can接收*/
void canrecv(int rate)
{
#if 0
     int taskID;
	
    taskID=taskNameToId("canRecvTask");
	
	if(taskID>0)
	{		
	    taskDelete(taskID);
	}

	rtlNetTaskSemId = semBCreate(SEM_Q_FIFO,SEM_EMPTY);

	/* 创建接收任务*/
	taskSpawn("canRecvTask",253,0,4000,(FUNCPTR)canrec,rate,0,0,0,0,0,0,0,0,0);
#endif

	if(can_open)
	{
		releaseNode(0);
		setupNode(0,rate);
	}
	else
	{
		setupNode(0,rate);
	}
	recvLen = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -