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

📄 sja1000.c

📁 在linux2.6.14下的can的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
		{
			sja1000_WriteRegisterRR(pSja1000Par,addresse,value);
			ret = 0;
		}
		else if((addresse >= 0) && (addresse <= 0x7f))
		{
			sja1000_WriteRegister(pSja1000Par,addresse,value);
			ret = 0;
		}
		else		// todo: error number if out of addresse range
		{
			ret = 0;
		}

		// todo: error number if out of addresse range
	}
	return ret;
}

/***************************************************************************************/
int sja1000_get_register(struct sja1000_admin *pSja1000Par, int addresse, int *value)
{
	int ret = -ENOSYS;

	/* The SJA1000 has 128 normal register and 128 'reset mode' register (in PELICAN mode) 
	 * To get a hardware abstraction in above layers, this function accepts following
	 * addresses:
	 * 0...7f = normal mode registers
	 * 80..ff = reset mode register 0...7f
	 */
	if(pSja1000Par && value)
	{
		if((addresse >= 0x80) && (addresse <= 0xff)) // RESET Mode ?
		{
			*value = sja1000_ReadRegisterRR(pSja1000Par,addresse);
			ret = 0;
		}
		else if((addresse >= 0) && (addresse <= 0x7f))
		{
			*value = sja1000_ReadRegister(pSja1000Par,addresse);
			ret = 0;
		}
		else		// todo: error number if out of addresse range
		{
			*value = 0;
			ret = 0;
		}

	}
	return ret;
}

/***************************************************************************************/
int sja1000_set_can_mode(struct sja1000_admin *pSja1000Par, int can_2b)
{
 	if(!pSja1000Par)
 		return -ENODEV;
 
 	if((can_2b == 1) && !(pSja1000Par->access.bCanChipsetFlags & CANBUS_CFS_CAN_2_0_B))
  	{
 		pSja1000Par->bCan_2B = 0;
  		sja1000_init_device(pSja1000Par);
 		return -EINVAL;
  	}
 
 	pSja1000Par->bCan_2B = can_2b;
 	sja1000_init_device(pSja1000Par);
 	return 0;
}

/***************************************************************************************/
int sja1000_set_baudrate_by_constant(struct sja1000_admin *pSja1000Par, unsigned long constant)
{
	/* This function is only implemented for test and demonstration. A (chipset) driver
	 * usually implement only one function: xyz_set_baudrate() or xyz_set_baudrate_by_constant()
	 * but not both functions.
	 */
	if (constant >= sizeof(baudrate_list)/sizeof(unsigned long))
		return -ENODEV;
		
	return sja1000_set_baudrate(pSja1000Par, baudrate_list[constant]);
}

/***************************************************************************************/
int sja1000_set_acceptance_filter(struct sja1000_admin *pSja1000Par, struct canbus_acceptance_filter *filter)
{
 	unsigned long code = filter->code;
 	unsigned long mask = filter->mask;
 	SJA1000_TEST_DECLCHIP(pSja1000Par);
 
 	if (pSja1000Par->bCan_2B)
 	{
 		sja1000_WriteRegisterRR(pSja1000Par, 16, (u8) (code >> 24) );		// ACC
 		sja1000_WriteRegisterRR(pSja1000Par, 17, (u8) (code >> 16) );		// ACC
 		sja1000_WriteRegisterRR(pSja1000Par, 18, (u8) (code >>  8) );		// ACC
 		sja1000_WriteRegisterRR(pSja1000Par, 19, (u8)  code        );		// ACC
 		sja1000_WriteRegisterRR(pSja1000Par, 20, (u8) (mask >> 24) );		// Mask
 		sja1000_WriteRegisterRR(pSja1000Par, 21, (u8) (mask >> 16) );		// Mask
 		sja1000_WriteRegisterRR(pSja1000Par, 22, (u8) (mask >>  8) );		// Mask
 		sja1000_WriteRegisterRR(pSja1000Par, 23, (u8)  mask        );		// Mask
 	}
 	else
  	{
 		sja1000_WriteRegisterRR(pSja1000Par,  4, (u8) (code>>3));	// Acceptance Code schreiben
 		sja1000_WriteRegisterRR(pSja1000Par,  5, (u8) (mask>>3));	// Acceptance Mask schreiben
  	}
 
 	return 0;
}

/***************************************************************************************/
int sja1000_set_command(struct sja1000_admin *pSja1000Par, int command)
{
  	struct canbus_event ev;
 	SJA1000_TEST_DECLCHIP(pSja1000Par);
 
 	TRACE("sja1000_set_command CAN 2.0A = %d",pSja1000Par->bCan_2B);
 	if(!pSja1000Par->bCan_2B) switch(command)   // BASIC CAN Modus
  	{
 	case CANBUS_CMD_ENTER_STANDBY:
 		sja1000_WriteRegister(pSja1000Par, 1,0x10);
 		ev.event = CANBUS_EVENT_ENTERING_STANDBY;
 		if(pSja1000Par->isr)
  		{
 			(*pSja1000Par->isr)(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
  		}
 		break;
 
 	case CANBUS_CMD_LEAVE_STANDBY:
 		sja1000_WriteRegister(pSja1000Par, 1,~0x10 & sja1000_ReadRegister(pSja1000Par,1));
 		break;
 
 	case CANBUS_CMD_ABORT_TRANSMISSION:
    	sja1000_WriteRegister(pSja1000Par, 1,0x02);
 		sja1000_ReadRegister(pSja1000Par, 3);
 		break;
 
 	case CANBUS_CMD_CLEAR_OVERRUN:
 		sja1000_WriteRegister(pSja1000Par, 1,0x08);
 		break;
 
 	default:
 		return -EINVAL;
 	}
 	else switch(command)						// Pelican Modus
 	{
 	case CANBUS_CMD_ENTER_STANDBY:
 		sja1000_WriteRegister(pSja1000Par, 0,0x10 |  sja1000_ReadRegister(pSja1000Par,0));
 		ev.event = CANBUS_EVENT_ENTERING_STANDBY;
 		if(pSja1000Par->isr)
 		{
 			(*pSja1000Par->isr)(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
 		}
 		break;
 
 	case CANBUS_CMD_LEAVE_STANDBY:
 		sja1000_WriteRegister(pSja1000Par, 0,~0x10 & sja1000_ReadRegister(pSja1000Par,0));
 		break;
 
 	case CANBUS_CMD_ABORT_TRANSMISSION:
    	sja1000_WriteRegister(pSja1000Par, 1,0x02);
 		sja1000_ReadRegister(pSja1000Par, 3);
 		break;
 
 	case CANBUS_CMD_CLEAR_OVERRUN:
 		sja1000_WriteRegister(pSja1000Par, 1,0x08);
 		break;
 
 	case CANBUS_CMD_SELF_RECEPTION_REQUEST:
 		sja1000_WriteRegister(pSja1000Par, 1,0x10);
 		break;
 
 	case CANBUS_CMD_LISTEN_ON:
 		sja1000_WriteRegisterRR(pSja1000Par, 0,0x02 | sja1000_ReadRegister(pSja1000Par,0));
 		break;
 
 	case CANBUS_CMD_LISTEN_OFF:
 		sja1000_WriteRegisterRR(pSja1000Par, 0,~0x02 & sja1000_ReadRegister(pSja1000Par,0));
 		break;
 
 	default:
 		return -EINVAL;
  	}
 
 	return 0;
}

/***************************************************************************************/
int sja1000_transmit_data(struct sja1000_admin *pSja1000Par, struct canbus_transmit_data *trans)
{
	u8   i1,i2,len;

 	if( !(pSja1000Par && trans && (sja1000_check_chipset(pSja1000Par) >= 0)) )
 		return -ENODEV;
 
 	len= (trans->dlc > 8)?8:trans->dlc;
 
 	// Achtung! Die Routine wird auch aus der IRQ-Routine heraus aufgerufen
 	if (pSja1000Par->bCan_2B)
 	{
 		if (trans->fmt == CANBUS_TRANS_FMT_EXT)		// EFF
 		{
    			TRACE("TransmitToSJA1000 -1-");
 			i1 = len;
 			i1|= trans->rtr?0x40:0x00;
 			i1|= 0x80; // Modus: EFF
 			sja1000_WriteRegister(pSja1000Par, 16,i1);
 			i1 = (u8) ((trans->identifier & 0x1f) << 3);
 			sja1000_WriteRegister(pSja1000Par, 20,i1);
 			i1 = (u8) ((trans->identifier >> 5) & 0xff);
 			sja1000_WriteRegister(pSja1000Par, 19,i1);
 			i1 = (u8) ((trans->identifier >> 13) & 0xff);
 			sja1000_WriteRegister(pSja1000Par, 18,i1);
 			i1 = (u8) ((trans->identifier >> 21) & 0xff);
 			sja1000_WriteRegister(pSja1000Par, 17,i1);
 			
 			for(i1=0;i1<len;i1++)
 				sja1000_WriteRegister(pSja1000Par, (u8)21+i1,trans->msg[i1]);
 
 			sja1000_WriteRegister(pSja1000Par, 1,0x01); // Daten senden (Transmission Request)
 		}
 		else										// SFF
 		{
 			// Identifier begrenzen auf 11 Bit (sonst wird sp鋞er was falsches angezeigt)
    			TRACE("TransmitToSJA1000 -2-");
 			trans->identifier &= 0x7ff;  
 
 			i1 = len;
 			i1|= trans->rtr?0x40:0x00;
 			sja1000_WriteRegister(pSja1000Par, 16,i1);
 			i1 = (u8) ((trans->identifier & 7) << 5);
 			sja1000_WriteRegister(pSja1000Par, 18,i1);
 			i1 = (u8) ((trans->identifier >> 3) & 0xff);
 			sja1000_WriteRegister(pSja1000Par, 17,i1);
 			
 			for(i1=0;i1<len;i1++)
 				sja1000_WriteRegister(pSja1000Par, (u8)19+i1,trans->msg[i1]);
 			sja1000_WriteRegister(pSja1000Par, 1,0x01); // Daten senden (Transmission Request)
 		}
 	}
 	else	// CAN2A
 	{
 		// Identifier begrenzen auf 11 Bit (sonst wird sp鋞er was falsches angezeigt)
    		TRACE("TransmitToSJA1000 -3-");
 		trans->identifier &= 0x7ff;  
 
 		i1 = (u8) ((trans->identifier >> 3) & 0xff);
 		i2 = (u8) (trans->identifier & 0x07) << 5;
 		i2|= trans->rtr?0x10:0x00;
 		i2|= len;
 	
 		sja1000_WriteRegister(pSja1000Par, 10,i1);
 		sja1000_WriteRegister(pSja1000Par, 11,i2);
 	
 		for(i1=0;i1<len;i1++)
 			sja1000_WriteRegister(pSja1000Par, (u8)12+i1,trans->msg[i1]);
 
 		sja1000_WriteRegister(pSja1000Par, 1,0x01); // Daten senden (Transmission Request)
 	}
 
 	return 0;
}

/***************************************************************************************/
int sja1000_test_device(struct sja1000_admin *pSja1000Par)
{
 	SJA1000_TEST_DECLCHIP(pSja1000Par);
 
 	TRACE("sja1000_test_device");

 	// The Bit 0x01 in register 0x00 is never set
 	if (sja1000_ReadRegister(pSja1000Par, 0) & 0x01) 
 	{
 		return 0;
 	}
 
 	return 1;
}
/***************************************************************************************/
int sja1000_check_chipset(struct sja1000_admin *pSja1000Par)
{
 	SJA1000_TEST_DECLCHIP(pSja1000Par);
 
 	TRACE("checkSJA1000");
 	if (sja1000_ReadRegister(pSja1000Par, 0) & 0x01)   // Baustein wurde in der Zwischenzeit r點kgesetzt
 	{
 		sja1000_init_device(pSja1000Par); 
 		return 0;
  	}
 
 	return 1;
}


/***************************************************************************************/
int PeliCanISR(struct sja1000_admin *pSja1000Par)
{                                                       // CSerialPort::HwIntProc
     u8 irq;
 	u8 status;
  	struct canbus_event ev;
  	unsigned long id;
  	int   t;
 
  	TRACE("Pelican IRQ");
 	irq = sja1000_ReadRegister(pSja1000Par, 3); // Interrupt-Register lesen
  	if (!(irq & 0xff))
  		return 0;
  
  	TRACE("IRQ wird bearbeitet");
 	if(!(pSja1000Par->isr))
 		return 1;
 
 	if (irq & 0x01)				// Receive Interrupt
  	{
 		// F黮le Info-Struktur
 		TRACE("Receive IRQ");
 		ev.event = CANBUS_EVENT_RECEIVED;
 		status = sja1000_ReadRegister(pSja1000Par, 16);
 		if (status & 0x80) // Extended Frame Format (EFF)
 		{
 			ev.data.fmt = CANBUS_TRANS_FMT_EXT;
 			id = sja1000_ReadRegister(pSja1000Par, 17);
 			id = (id << 8) + sja1000_ReadRegister(pSja1000Par, 18);
 			id = (id << 8) + sja1000_ReadRegister(pSja1000Par, 19);
 			id = (id << 8) + sja1000_ReadRegister(pSja1000Par, 20);
 			id = id >> 3;
 			for(t=0;t<8;t++)
  			{
 				ev.data.msg[t] = sja1000_ReadRegister(pSja1000Par, 21+t);
  			}
  		}
 		else	// Standard Frame Format (SFF)
  		{
 			ev.data.fmt = CANBUS_TRANS_FMT_STD;
 			id = sja1000_ReadRegister(pSja1000Par, 17);
 			id = (id << 8) + sja1000_ReadRegister(pSja1000Par, 18);
 			id = id >> 5;
 			for(t=0;t<8;t++)
  			{
 				ev.data.msg[t] = sja1000_ReadRegister(pSja1000Par, 19+t);
  			}
  		}
 		ev.data.identifier = id;
 		ev.data.rtr = (status & 0x40) >> 6;
 		ev.data.dlc = (status & 0x0f);
 		sja1000_WriteRegister(pSja1000Par, 1,0x04); // ReleaseReceiveBuffer (Rx Buffer wird dadurch ung黮tig)
 
		pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
 	}
 
 	if (irq & 0x02)				// Transmit Interrupt
 	{
 		TRACE("Transmit IRQ");
 		ev.event = CANBUS_EVENT_TRANSMITTED;
 
 		pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
	}
 
 	if (irq & 0x04)				// Error Warning Interrupt
 	{

⌨️ 快捷键说明

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