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

📄 can.c

📁 DSP56F807的CAN通讯程序,可用于多子板互连、也可作为开发的原型程序
💻 C
字号:
#include "can.h"
#include "dsp56f805_io.h"

#define CAN_BUFFER_LNG 64

/* done by William Jiang (a13984@motorola.com) */

/* Vesion 2.0 */

static int rx_buffer[CAN_BUFFER_LNG];
static int *volatile rx_iptr;
static int *rx_sptr; 			/* iptr belongs to ISR, sptr to SW */

void can_rx_isr(void) {
#pragma interrupt	saveall warn
	int i;
	for (i=0;i<((io.can.rb.idr[1]&0x0008)?4:2);i++) { /* IDR1 bit 3 = 1 --> 29-bit ID, otherwise 11-bit ID */
		*(rx_iptr++)=io.can.rb.idr[i];
		if (rx_iptr>=(rx_buffer+CAN_BUFFER_LNG)) rx_iptr=rx_buffer;
	}
	*(rx_iptr++)= (io.can.rb.dlr & 0x000f);
	if (rx_iptr>=(rx_buffer+CAN_BUFFER_LNG)) rx_iptr=rx_buffer;
	for (i=0;i<(io.can.rb.dlr & 0x000f);i++) {
		*(rx_iptr++)=io.can.rb.sdr[i];
		if (rx_iptr>=(rx_buffer+CAN_BUFFER_LNG)) rx_iptr=rx_buffer;
	}
	io.can.rflg=0x0001;			/*clear receive interrupt flag */	
}

void can_init_hw(struct can_config *config) {
	io.can.ctl0=0x0001;							/* soft reset mode */
	io.can.btr0=(*config).timing & 0x00ff;
	io.can.btr1=((*config).timing & 0xff00)>>8;
	io.can.idac=((*config).filters & 0x0003)<<5;
	io.can.dar0=(*config).acceptance0.f8b.filter0;
	io.can.dar1=(*config).acceptance0.f8b.filter1;
	io.can.dar2=(*config).acceptance0.f8b.filter2;
	io.can.dar3=(*config).acceptance0.f8b.filter3;
	io.can.dmr0=(*config).mask0.f8b.filter0;
	io.can.dmr1=(*config).mask0.f8b.filter1;
	io.can.dmr2=(*config).mask0.f8b.filter2;
	io.can.dmr3=(*config).mask0.f8b.filter3;
	io.can.dar4=(*config).acceptance1.f8b.filter0;
	io.can.dar5=(*config).acceptance1.f8b.filter1;
	io.can.dar6=(*config).acceptance1.f8b.filter2;
	io.can.dar7=(*config).acceptance1.f8b.filter3;
	io.can.dmr4=(*config).mask1.f8b.filter0;
	io.can.dmr5=(*config).mask1.f8b.filter1;
	io.can.dmr6=(*config).mask1.f8b.filter2;
	io.can.dmr7=(*config).mask1.f8b.filter3;
#if 0
	// 0.5Mbps ok
	io.can.ctl1=0x0080;							/* enable can, clock from EXTAL */
#else
	// 0.5Mbps for config.timing=0x1409
	io.can.ctl1=0x0081;							/* enable can, clock from IP bus */
#endif
//	io.can.ctl1=0x0084;							/* the same in loop test mode */
	io.can.ctl0=0;
	io.can.rier=0x0001;							/* enable Rx interrupt */
	io.can.tcr=0;								/* disable Tx interrupts */
	cr.ipr|=0x8000;								/* enable level 1 interrupts */
	asm	{bfset	#0x0100,sr}						/* enable maskable interrupts */
	asm {bfclr	#0x0200,sr}
	io.ictn.gpr[3]|=0x1100;						/* assign IRQs 14,15 to group 1 */
}

void can_init(struct can_config *config) {
	rx_iptr=rx_sptr=rx_buffer;
	can_init_hw(config);
}

int can_rxstat(void) {
	return(rx_iptr-rx_sptr);
}

int can_tx(int buffer, struct can_frame *data) {
	unsigned int *tx_buffer_base;
	unsigned int mask;
	int i;
	if ((buffer>-1)&&(buffer<3)) mask=(1>>buffer); else mask=7;
	while (!(io.can.tflg&mask)); 			/* wait for buffer to become free */
	mask=io.can.tflg&mask;
	mask=(mask&0x0001)?1:((mask&0x0002)?2:4);
	tx_buffer_base=(unsigned int*)&io.can.tb[mask>>1];
	for (i=0;i<14;i++) *(tx_buffer_base+i)=*(((int *)(data))+i);
	io.can.tflg=mask;
	return(mask>>1);
}

int can_rx(struct can_frame *data) {
	int i;
	for (i=0;i<2;i++) {								/* receive standard header */
		data->id[i]=*(rx_sptr++);
		if (rx_sptr>=(rx_buffer+CAN_BUFFER_LNG)) rx_sptr=rx_buffer;
	}
	if (data->id[1]&0x0008) for (i=2;i<4;i++) {		/* if IDE==1, receive rest of 32-bit header */
		data->id[i]=*(rx_sptr++);
		if (rx_sptr>=(rx_buffer+CAN_BUFFER_LNG)) rx_sptr=rx_buffer;
	}
	data->length=*(rx_sptr++);						/* length */
	if (rx_sptr>=(rx_buffer+CAN_BUFFER_LNG)) rx_sptr=rx_buffer;
	for (i=0;i<data->length;i++) {					/* data */
		data->data[i]=*(rx_sptr++);
		if (rx_sptr>=(rx_buffer+CAN_BUFFER_LNG)) rx_sptr=rx_buffer;
	}
}


short	can_rxflag(void)
{
	return (io.can.rflg);
}

void can_clr_rxflag(short flag)
{
	io.can.rflg |= flag;
}

⌨️ 快捷键说明

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