?? pelican.c
字號:
/*----------------------------------------------------------------------------
* PeliCAN.c -
*
* Author : redsea_li
* Version : 1.1
* Created : 2009-03-03 20:50:36
* Last Modified: 2009-03-18 22:03:54
* Copyright ECI
*----------------------------------------------------------------------------*/
#include "PeliCAN.h"
//#include "PeliCanDef.h"
#include "winpciConfigLib.h"
#include "io.h"
#define logMsg DbgPrint
int int_lvl;
UINT32_T iobase_adr;
UINT8_T UrgBuf[13];
UINT8_T BTR0,BTR1;
UINT8_T ACR0,ACR1,ACR2,ACR3;
UINT8_T AMR0,AMR1,AMR2,AMR3;
#define INT_NUM_IRQ 0X20 /* vector number for PIC IRQ0 */
#define INUM_TO_IVEC(intNum) ((VOIDFUNCPTR *) ((intNum) << 3))
#define INT_NUM_COM (INT_NUM_IRQ + int_lvl)
typedef struct /* BAUD */
{
int rate; /* a baud rate */
int btr0;
int btr1;
} BAUD;
BAUD baudTable [] =
{
{20, 0x53,0x2f}, {40, 0x87,0xff}, {50, 0x47,0x2f}, {80, 0x83,0xff}, {100, 0x43,0x2f},
{125, 0x03,0x1c}, {200, 0x81,0xfa}, {250, 0x01,0x1c}, {400, 0x80,0xfa}, {500, 0x0,0x1c},
{666,0x80,0xb6}, {800, 0x0,0x16}, {1000,0x0,0x14}
};
PFUNC p = NULL;
/*interrupt register function*/
void registerFunc(PFUNC func)
{
p = func;
}
/*time-lapse function*/
void delay(UINT32_T t)
{
UINT32_T td;
for(td = 0; td <t; td++)
;
return;
}
/*interrupt ID setup function*/
void can_set_urg(UINT8_T channel, char *ACK)
{
int i;
UINT8_T BegWrt,EndWrt,BegRd;
char rdbck;
switch(channel) {
case 0:
BegWrt = 0x01;
EndWrt = 0x00;
BegRd = 0x02;
break;
case 1:
BegWrt = 0x04;
EndWrt = 0x00;
BegRd = 0x08;
break;
case 2:
BegWrt = 0x10;
EndWrt = 0x00;
BegRd = 0x20;
break;
case 3:
BegWrt = 0x40;
EndWrt = 0x00;
BegRd = 0x80;
break;
default:
break;
}
sysOutByte(iobase_adr + 0x13, BegWrt);
for(i = 0; i < 4; i++) {
sysOutByte(iobase_adr + 0x14, ACK[i]);
debug_printf("\nACK %d = %2x\n",i,(UINT8_T)ACK[i]);
}
sysOutByte(iobase_adr + 0x13, EndWrt);
sysOutByte(iobase_adr + 0x13, BegRd);
for(i = 0; i < 4; i++) {
rdbck = sysInByte(iobase_adr + 0x14);
debug_printf("\n rdbck = %2x\n",(UINT8_T)rdbck);
}
sysOutByte(iobase_adr + 0x13, EndWrt);
return;
}
/*readback interrupt ID set before*/
void can_rdurg(UINT8_T channel)
{
int i;
UINT8_T EndRd,BegRd;
char rdbck;
switch(channel) {
case 0:
EndRd = 0x00;
BegRd = 0x02;
break;
case 1:
EndRd = 0x00;
BegRd = 0x08;
break;
case 2:
EndRd = 0x00;
BegRd = 0x20;
break;
case 3:
EndRd = 0x00;
BegRd = 0x80;
break;
default:
break;
}
sysOutByte(iobase_adr + 0x13, BegRd);
for(i = 0; i < 4; i++) {
rdbck = sysInByte(iobase_adr + 0x14);
debug_printf("\n rdbck = %2x\n",(UINT8_T)rdbck);
}
sysOutByte(iobase_adr + 0x13, EndRd);
return;
}
/*write registers of sja1000 not have to fill iobase_adr + 0x10 with 0x0f*/
void can_write(UINT8_T channel, UINT8_T sja_reg, char data)
{
UINT32_T sja_adr;
sja_adr = iobase_adr + 4 * channel;
sysOutByte(sja_adr , sja_reg);
sysOutByte(sja_adr + 1,data);
return;
}
/*read registers of sja1000 not have to fill iobase_adr + 0x10 with 0x0f*/
char can_read(UINT8_T channel, UINT8_T sja_reg)
{
char data;
UINT32_T sja_adr;
sja_adr = iobase_adr + 4 * channel;
sysOutByte(sja_adr , sja_reg);
data = sysInByte(sja_adr+ 1);
return data;
}
/*write registers of sja1000, used by can_int function*/
void wrt_reg(UINT8_T channel, UINT8_T sja_reg, char data)
{
UINT8_T bgn_wrt, end_wrt, wrt_jdg;
UINT8_T reg_value, prp_res, c, c1, c2;
UINT32_T sja_adr;
sja_adr = iobase_adr + 4 * channel;
switch(channel) {
case 0:
bgn_wrt = 0x01;
end_wrt = 0x03;
prp_res = 0xfc;
break;
case 1:
bgn_wrt = 0x04;
end_wrt = 0x0c;
prp_res = 0xf3;
break;
case 2:
bgn_wrt = 0x10;
end_wrt = 0x30;
prp_res = 0xcf;
break;
case 3:
bgn_wrt = 0x40;
end_wrt = 0xc0;
prp_res = 0x3f;
break;
default:
break;
}
c = sysInByte(iobase_adr + 0x1a);
c1 = (c & prp_res) | bgn_wrt;
sysOutByte(iobase_adr + 0x1a, c1);
sysOutByte(sja_adr, sja_reg);
sysOutByte(sja_adr + 1, data);
c = sysInByte(iobase_adr + 0x1a);
c1 = (c & prp_res) | end_wrt;
sysOutByte(iobase_adr + 0x1a, c1);
c2 = sysInByte(iobase_adr + 0x1a);
do {
reg_value = sysInByte(iobase_adr + 0x1a);
}
while (0x0 != (reg_value&0x03));
return;
}
/*read registers of sja1000, used by can_int function*/
UINT8_T rd_reg(UINT8_T channel, UINT8_T sja_reg)
{
UINT8_T c, rd_jdg, prp_rd, end_prp, bgn_rd, end_rd;
UINT8_T c0, c1;
UINT32_T sja_adr;
sja_adr = iobase_adr + 4 * channel;
switch(channel) {
case 0:
prp_rd = 0x01;
end_prp = 0x03;
bgn_rd = 0x02;
end_rd = 0xfc;
break;
case 1:
prp_rd = 0x04;
end_prp = 0x0c;
bgn_rd = 0x08;
end_rd = 0xf3;
break;
case 2:
prp_rd = 0x10;
end_prp = 0x30;
bgn_rd = 0x20;
end_rd = 0xcf;
break;
case 3:
prp_rd = 0x40;
end_prp = 0xc0;
bgn_rd = 0x80;
end_rd = 0x3f;
break;
default:
break;
}
c0 = sysInByte(iobase_adr + 0x18);
c1 = (c0&end_rd) | prp_rd;
sysOutByte(iobase_adr + 0x18, c1);
sysOutByte(sja_adr, sja_reg);
c0 = sysInByte(iobase_adr + 0x18);
c1 = (c0&end_rd) | end_prp;
sysOutByte(iobase_adr + 0x18, c1);
do {
rd_jdg = sysInByte(iobase_adr + 0x18);
} while((rd_jdg&end_prp) != 0x0);
if (0x0 == (rd_jdg&end_prp))
{
c0 = sysInByte(iobase_adr + 0x18);
c1 = (c0&end_rd) | bgn_rd;
sysOutByte(iobase_adr + 0x18, c1);
c = sysInByte(sja_adr + 1);
c0 = sysInByte(iobase_adr + 0x18);
c1 = (c0&end_rd) | end_rd;
sysOutByte(iobase_adr + 0x18, c1);
}
else {
logMsg("can_rst:read reg faild!\n", 0, 0, 0, 0, 0, 0);
return ERROR;
}
return c;
}
/*send data frames to CANBUS*/
void can_transmit(UINT8_T channel, unsigned char *txdata)
{
int i;
int intLockT;
UINT32_T mem_adr;
mem_adr = iobase_adr + 4 * channel + 2;
// intLockT = intLock();
sysOutByte(mem_adr + 1,0x1a);
for(i = 0; i < 13; i++) {
sysOutByte(mem_adr, txdata[i]);
}
sysOutByte(mem_adr + 1, 0x18);
debug_printf("\nChannel is :%d\n", channel);
debug_printf("\nThe Data is :%x %x %x %x %x %x %x %x %x %x %x %x %x\n", txdata[0],txdata[1],txdata[2],txdata[3],txdata[4],txdata[5],txdata[6],txdata[7],txdata[8],txdata[9],txdata[10],txdata[11],txdata[12]);
// intUnlock(intLockT);
}
/*send urgency frames to CANBUS*/
void can_TrnUrg(UINT8_T channel, char *txdata)
{
int i;
UINT32_T mem_adr;
char c;
mem_adr = iobase_adr + 4 * channel + 2;
sysOutByte(mem_adr + 1,0xba);
for(i = 0; i < 13; i++) {
sysOutByte(mem_adr, txdata[i]);
c = txdata[i];
}
sysOutByte(mem_adr + 1, 0xb8);
return;
}
/*receive data frames CANBUS*/
int can_receive(UINT8_T channel,unsigned char *rxdata)
{
UINT8_T st,recv_st;
int i,intLockR;
UINT32_T mem_adr;
mem_adr = iobase_adr + 4 * channel + 2;
debug_printf("in the function: can_receive\n");
debug_printf("can_receive channel = %d\n", channel);
switch(channel) {
case 0:
st = sysInByte(iobase_adr + 0x12);
if ((st&0x01) == 0x0)
{ debug_printf("channel 0 receive error\n");
return ERROR;
}
recv_st = 0x01;
break;
case 1:
st = sysInByte(iobase_adr + 0x12);
if ((st&0x02) == 0x0)
{
debug_printf("in the function: case 1 error!\n");
return ERROR;
}
recv_st = 0x02;
break;
case 2:
st = sysInByte(iobase_adr + 0x12);
if ((st&0x04) == 0x0)
{
debug_printf("channel 2 receive error\n");
return ERROR;
}
recv_st = 0x04;
break;
case 3:
st = sysInByte(iobase_adr + 0x12);
if ((st&0x08) == 0x0)
return ERROR;
recv_st = 0x08;
break;
default:
break;
}
if (st&recv_st)
{
debug_printf("receive data correct!\n");
//intLockR = intLock();
sysOutByte(mem_adr + 1, 0x46);
for (i = 0; i <13; i++) {
rxdata[i] = sysInByte(mem_adr);
}
sysOutByte(mem_adr +1, 0x44);
debug_printf("\nThe Data is :%x %x %x %x %x %x %x %x %x %x %x %x %x\n" ,rxdata[0],rxdata[1],rxdata[2],rxdata[3],rxdata[4],rxdata[5],rxdata[6],rxdata[7],rxdata[8],rxdata[9],rxdata[10],rxdata[11],rxdata[12]);
//intUnlock(intLockR);
return OK;
}
else
{
debug_printf("receive data error!\n");
return ERROR;
}
}
/*read data frames from transmit memory*/
int can_rd_trn(UINT8_T channel, char *rxdata)
{
int i;
UINT32_T mem_adr;
mem_adr = iobase_adr + 4 * channel + 2;
sysOutByte(mem_adr + 1, 0x26);
for (i = 0; i <13; i++) {
rxdata[i] = sysInByte(mem_adr);
}
sysOutByte(mem_adr + 1, 0x24);
return OK;
}
/*write data frames to receive memory*/
void can_wrt_recv(UINT8_T channel, char *txdata)
{
int i;
UINT32_T mem_adr;
mem_adr = iobase_adr + 4 * channel + 2;
sysOutByte(mem_adr + 1, 0x8a);
for (i = 0; i <13; i++) {
sysOutByte(mem_adr, txdata[i]);
}
sysOutByte(mem_adr + 1, 0x88);
return;
}
/*readout the length of data frames from receive memory*/
UINT32_T can_RcvLngth(UINT8_T channel)
{
UINT32_T mem_adr;
UINT32_T RcvLngth1,RcvLngth2;
UINT32_T c,c1,c2;
if (0 == channel) {
RcvLngth1 = 0x0;
RcvLngth2 = 0x01;
} else if (1 == channel) {
RcvLngth1 = 0x04;
RcvLngth2 = 0x05;
} else if (2 == channel) {
RcvLngth1 = 0x08;
RcvLngth2 = 0x09;
} else if (3 == channel) {
RcvLngth1 = 0x0c;
RcvLngth2 = 0x0d;
} else
return ERROR;
sysOutByte(iobase_adr + 0x1d, RcvLngth1);
c1 = sysInByte(iobase_adr + 0x1d);
sysOutByte(iobase_adr + 0x1d, RcvLngth2);
c2 = sysInByte(iobase_adr + 0x1d);
c = 256 * c2 + c1;
return c;
}
/*readout the length of data frames from transmit memory*/
UINT32_T can_TrsmtLngth(UINT8_T channel)
{
UINT32_T mem_adr;
UINT32_T TrsmtLngth1,TrsmtLngth2;
UINT32_T c,c1,c2;
if (0 == channel) {
TrsmtLngth1 = 0x02;
TrsmtLngth2 = 0x03;
} else if (1 == channel) {
TrsmtLngth1 = 0x06;
TrsmtLngth2 = 0x07;
} else if (2 == channel) {
TrsmtLngth1 = 0x0a;
TrsmtLngth2 = 0x0b;
} else if (3 == channel) {
TrsmtLngth1 = 0x0e;
TrsmtLngth2 = 0x0f;
} else
return ERROR;
sysOutByte(iobase_adr + 0x1d, TrsmtLngth1);
c1 = sysInByte(iobase_adr + 0x1d);
sysOutByte(iobase_adr + 0x1d, TrsmtLngth2);
c2 = sysInByte(iobase_adr + 0x1d);
c = 256 * c2 + c1;
return c;
}
/*ISR of sja1000 */
void CanRecvInt()
{
int i, oldLvl;
UINT8_T c, IntSrc;
//oldLvl = intLock();
IntSrc = sysInByte(iobase_adr + 0x17);
if ((IntSrc & 0x03) == 0x01)
{
sysOutByte(iobase_adr + 0x03, 0xf6);
for (i = 0; i < 13; i++) {
c = sysInByte(iobase_adr + 0x02);
UrgBuf[i] = c;
}
sysOutByte(iobase_adr + 0x03, 0x00);
if(p!=NULL)
p( 0x0 );
} else if ((IntSrc & 0x0c) == 0x04) {
sysOutByte(iobase_adr + 0x07, 0xf6);
for (i = 0; i < 13; i++) {
c = sysInByte(iobase_adr + 0x06);
UrgBuf[i] = c;
}
sysOutByte(iobase_adr + 0x07, 0x00);
if(p!=NULL)
p( 0x1 );
} else if ((IntSrc & 0x30) == 0x10) {
sysOutByte(iobase_adr + 0x0b, 0xf6);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -