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

📄 sja1000.c

📁 CANopen源代码
💻 C
字号:
/********************************************************* *                                                       * *  Advanced Ring Buffer Redundant Application for CAN   * *                                                       * ********************************************************* *                      ArbraCan.c                       * ********************************************************* * This program is free software; you can redistribute   * * it and/or modify it under the terms of the GNU General* * Public License as published by the Free Software      * * Foundation; either version 2 of the License, or (at   * * your option) any later version.                       * *                                                       * * This program is distributed in the hope that it will  * * be useful, but WITHOUT ANY WARRANTY; without even the * * implied warranty of MERCHANTABILITY or FITNESS FOR A  * * PARTICULAR PURPOSE.  See the GNU General Public       * * License for more details.                             * *                                                       * * You should have received a copy of the GNU General    * * Public License along with this program; if not, write * * to 	The Free Software Foundation, Inc.               * *	675 Mass Ave                                     * *	Cambridge                                        * *	MA 02139                                         * * 	USA.                                             * ********************************************************* *                                                       * *      Author: Edouard TISSERANT                        * *      Contact: edouard.tisserant@esstin.u-nancy.fr     * *      Version: 1.0                                     * *      Modification date:                               * *      Description:                                     * *-------------------------------------------------------* * Hardware dependant function for SJA1000 philips CAN   * * controler. For use with ArbraCan                      * *                                                       * *********************************************************/#include <linux/version.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/pci.h>#include <asm/io.h>#include <can.h>#include <sja1000.h>#include <arbraCan.h>//#define DEBUG#ifdef DEBUGstatic char can_debug = 1;#define MSGK(string, args...) printk("%s:%d:",__FILE__,__LINE__);printk(string, ##args)#else#define MSGK(string, args...)#endifunsigned int PLX_9050_BASE;unsigned int SJA_BASE[CAN_BUS_COUNT];// initialisation de la carte PCI 7841 qui contient le SJA1000int initBoardSJA1000(struct pci_dev *dev){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)	PLX_9050_BASE = dev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK;#else	PLX_9050_BASE = dev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK;#endif	if(check_region(PLX_9050_BASE, 80)) {		MSGK("Check region failure\n");		return EBUSY;	}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)	SJA_BASE[0] = dev->resource[2].start & PCI_BASE_ADDRESS_IO_MASK;#else	SJA_BASE[0] = dev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK;#endif	SJA_BASE[1] = SJA_BASE[0] + 128;	if(check_region(SJA_BASE[0], 32)) {		MSGK("Check region failure\n");		return EBUSY;	}	if(check_region(SJA_BASE[1], 32)) {		MSGK("Check region failure\n");		return EBUSY;	}	request_region(PLX_9050_BASE, 80, "PCI7841/PLX9050");	request_region(SJA_BASE[0], 32, "PCI7841/SJA1000(1)"); 	request_region(SJA_BASE[1], 32, "PCI7841/SJA1000(2)"); 		return 0;}void closeBoardSJA1000(){	release_region(PLX_9050_BASE, 80);	release_region(SJA_BASE[0], 32);	release_region(SJA_BASE[1], 32);}// Initialisation du SJA10000void initSJA1000(	int bus_nb,				// numero du port	unsigned char acc_code,			// acceptance code	unsigned char acc_mask,			// acceptance mask	int overrun_it,				// activation IT overrun	int error_it,				// activation IT error	int transmit_it,			// activation IT transmit	int receive_it,				// activation IT receive	int rate,	int silent){	unsigned char it;	unsigned int SJA = SJA_BASE[bus_nb];	// on passe en mode reset en desactivant toutes les it	outb(RESET_MODE, CONTROL);		// on force le mode BasicCAN	outb(0x48, CLOCK_DIVIDER);		// Identification du node and timing fixing	outb(acc_code, ACCEPTANCE_CODE);	outb(acc_mask, ACCEPTANCE_MASK);	if(silent)		outb(0x02, OUTPUT_CONTROL);	else		outb(0xFA, OUTPUT_CONTROL);       	        switch (rate) {                case 1000: {		  /* time quanta (tq) per bit : 8; *//* 		  sync = 1tq, seg1 = 5tq, tseg2 = 2tq *//* 		  conformance with Canopen DS301 recommandation *//* 		  added by francis.dupin@inrets.fr. 2004 */                        MSGK("Setting 1000 kbps.\n");                        outb(0x00,BUS_TIMING_0);                        outb(0x14,BUS_TIMING_1);                        break;                }                case 500: {		  /* time quanta (tq) per bit : 16; *//* 		  sync = 1tq, seg1 = 13tq, tseg2 = 2tq *//* 		  conformance with Canopen DS301 recommandation *//* 		  added by francis.dupin@inrets.fr. 2004 */                        MSGK("Setting 500 kbps.\n");                        outb(0x40,BUS_TIMING_0);                        outb(0x1C,BUS_TIMING_1);                        break;                }                case 250: {		  /* time quanta (tq) per bit : 16; *//* 		  sync = 1tq, seg1 = 13tq, tseg2 = 2tq *//* 		  conformance with Canopen DS301 recommandation *//* 		  added by francis.dupin@inrets.fr. 2004 */		  MSGK("Setting 250 kbps.\n");                        outb(0x41,BUS_TIMING_0);                        outb(0x1C,BUS_TIMING_1);			break;                }                case 125: {		  /* time quanta (tq) per bit : 16; *//* 		  sync = 1tq, seg1 = 13tq, tseg2 = 2tq *//* 		  conformance with Canopen DS301 recommandation *//* 		  added by francis.dupin@inrets.fr. 2004 */                        MSGK("Setting 125 kbps.\n");                        outb(0x43,BUS_TIMING_0);                        outb(0x1C,BUS_TIMING_1);                        break;                }                case 100: {                        MSGK("Setting 100 kbps.\n");                        outb(0x83,BUS_TIMING_0);                        outb(0x4d,BUS_TIMING_1);                        break;                }	case 50: {// Does not work                        MSGK("Setting 50 kbps.\n");                        outb(0x18,BUS_TIMING_0);                        outb(0x1C,BUS_TIMING_1);                        break;                }                case 25: {                        MSGK("Setting 25 kbps.\n");                        outb(0x8f,BUS_TIMING_0);                        outb(0x4d,BUS_TIMING_1);                        break;                }                case 10: {                        MSGK("Setting 10 kbps.\n");                        outb(0xa7,BUS_TIMING_0);                        outb(0x4d,BUS_TIMING_1);                        break;                }                default: {                        MSGK("Baud rate not supported default to 1000.\n");                        outb(0x00,BUS_TIMING_0);                        outb(0x14,BUS_TIMING_1);                }        }	it = 	(overrun_it<<4) +		(error_it<<3) +		(transmit_it<<2) + 		(receive_it << 1);				// switch to operating mode and activate irq's	outb(it, CONTROL);}// envoi d'une trameMessage* sja1000_send_frame(int bus_nb, Message *mes){	int dlc, i;	unsigned int SJA = SJA_BASE[bus_nb];	// bytes number	dlc = mes->len & 0x0f;	// COB_ID, RTR and DLC	outb((((mes->cob_id.w >> 8) & 0x07) << 5) | ((mes->cob_id.w & 0xf8) >>3) , TRANSMIT_ID_0);	outb(((mes->cob_id.w & 0x07) << 5) | ((mes->rtr & 0x01) << 4) | dlc , TRANSMIT_ID_1);	// fill transmit buffer	for(i=0; i < dlc; i++) {		outb(mes->data[i], TRANSMIT_DATA+i);	}		// send	outb(TRANS_REQUEST, COMMAND);	return mes;}// reception d'une trameMessage* sja1000_rcv_frame(int bus_nb, Message *mes) {	int i;	char b0, b1;	unsigned int SJA = SJA_BASE[bus_nb];		b0 = inb(RECEIVE_ID_0);	b1 = inb(RECEIVE_ID_1);	mes->cob_id.w = ((((b0 & 0xe0) >> 5) << 8) & 0xFF00) |    //MSB	        ((((b0 & 0x1f) << 3) | ((b1 & 0xe0) >> 5)) & 0x00FF);  //LSB	mes->rtr = b1 & 0x10 ? 0x01 : 0x00;	mes->len = b1 & 0x0f;		for(i=0; i < mes->len; i++) {		mes->data[i] = inb(RECEIVE_DATA+i);	}		// on acquitte la reception	outb(RELEASE_RCV_BUFFER, COMMAND);		return mes;}char	sja1000_status(int bus_nb){	unsigned int SJA = SJA_BASE[bus_nb];	return inb(STATUS);}char	sja1000_ir(int bus_nb){	unsigned int SJA = SJA_BASE[bus_nb];	return inb(INTERRUPT);}char	plx_9050_ir(){	return inb(PLX_INTCSR);}

⌨️ 快捷键说明

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