📄 test_can_sja1000.c
字号:
/* 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 + -