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

📄 sja1000.c

📁 在linux2.6.14下的can的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
 		TRACE("Error Warning IRQ");
 		//sja1000_WriteRegister(pSja1000Par, 1,0x0e);                 // Release Receive Buffer + ClearDataOverrun + AbortTransmission (danach erfolgt ein Transmit-IRQ)
 		//sja1000_WriteRegister(pSja1000Par, 0, ~0x01 & sja1000_ReadRegister(pSja1000Par,0));       // resetMode l鰏chen
 		ev.event = CANBUS_EVENT_WARNING;
 
 		pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
 	}
 
 	if (irq & 0x08)				// Overrun Interrupt
 	{
 		TRACE("Overrun IRQ");
 		sja1000_WriteRegister(pSja1000Par, 1,0x0c); // Release Receive Buffer + ClearDataOverrun
 		ev.event = CANBUS_EVENT_OVERRUN;
 
 		pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
 	}
 
 	if (irq & 0x10)				// WakeUp Interrupt
 	{
 		TRACE("WakeUp IRQ");
 		ev.event = CANBUS_EVENT_LEAVING_STANDBY;
 
 		pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
  	}
 
 	if (irq & 0x20)				// Error Passive Interrupt
 	{
 		TRACE("Error passive IRQ");
 		ev.event = CANBUS_EVENT_PASSIVE;
 
 		pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
 	}
 
 	if (irq & 0x40)				// Arbitration lost Interrupt
 	{
 		TRACE("Arbitration lost IRQ");
 		ev.event = CANBUS_EVENT_ARBITRATION_LOST;
 
 		pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
 	}
 
 	if (irq & 0x80)				// Error Passive Interrupt
 	{
 		TRACE("Buserror IRQ");
 		sja1000_WriteRegister(pSja1000Par, 1,0x0e);                 // Release Receive Buffer + ClearDataOverrun + AbortTransmission (danach erfolgt ein Transmit-IRQ)
 		sja1000_WriteRegister(pSja1000Par, 0, ~0x01 & sja1000_ReadRegister(pSja1000Par,0));       // resetMode l鰏chen
 		ev.event = CANBUS_EVENT_BUS_ERROR;
 
 		pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
 	}
 
 	return 1;		// TRUE = IRQ wurde bedient
}

/***************************************************************************************/
int BasicCanISR(struct sja1000_admin *pSja1000Par)
{
    u8 irq;
	u8 status;
	struct canbus_event ev;
	int   t;

	irq = sja1000_ReadRegister(pSja1000Par, 3);                                                // Interrupt-Register lesen
	TRACE("BasicCan IRQ 0x%x",irq);
	if (!(irq & 0x1f))
		return 0;

	TRACE("IRQ wird bearbeitet");
	if(pSja1000Par->isr)
	{
 		if (irq & 0x01)			// Receive Interrupt
  		{
  			TRACE("Receive IRQ");
  			ev.event = CANBUS_EVENT_RECEIVED;
 			ev.data.identifier = sja1000_ReadRegister(pSja1000Par, 20);
 			status = sja1000_ReadRegister(pSja1000Par, 21);
  			ev.data.fmt = CANBUS_TRANS_FMT_STD;
  			ev.data.identifier = (ev.data.identifier << 3) + ((status & 0xe0)>>5);
  			ev.data.rtr = (status & 0x10) >> 4;
  			ev.data.dlc = (status & 0x0f);
  			for(t=0;(t<8) && (t<ev.data.dlc);t++)
  			{
 				ev.data.msg[t] = sja1000_ReadRegister(pSja1000Par, (u8)22+t);
  			}
 			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 Interrupt
  		{
  			TRACE("Error IRQ");
 			sja1000_WriteRegister(pSja1000Par, 1,0x0e);                 // Release Receive Buffer + ClearDataOverrun + AbortTransmission (danach erfolgt ein Transmit-IRQ)
 			status = sja1000_ReadRegister(pSja1000Par, 0);             // Status einlesen
  			status = status & 0xfe; // ResetMode l鰏chen
 			sja1000_WriteRegister(pSja1000Par, 0,status);       
  			ev.event = CANBUS_EVENT_BUS_ERROR;
 
 			pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
  		}
 
 		if (irq & 0x08)			// Overrun Interrupt
  		{
  			TRACE("Overrun IRQ");
 			sja1000_WriteRegister(pSja1000Par, 1,0x0c); // Release Receive Buffer + ClearDataOverrun
  			ev.event = CANBUS_EVENT_OVERRUN;
 
 			pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
  		}
 
 		if (irq & 0x10)			// WakeUp Interrupt
  		{
  			TRACE("WakeUp IRQ");
  			ev.event = CANBUS_EVENT_LEAVING_STANDBY;
 
 			pSja1000Par->isr(pSja1000Par->pCanBusParm, pSja1000Par->pCanBusParm, &ev);
  		}
  	}
  	else    // Setze nur die Bits zur點k
  	{
 		if (irq & 0x01)				// Receive Interrupt
  		{
 			sja1000_WriteRegister(pSja1000Par, 1,0x04); // ReleaseReceiveBuffer (Rx Buffer wird dadurch ung黮tig)
  		}
 
 		if (irq & 0x04)				// Error Interrupt
  		{
 			sja1000_WriteRegister(pSja1000Par, 1,0x0e);                 // Release Receive Buffer + ClearDataOverrun + AbortTransmission (danach erfolgt ein Transmit-IRQ)
 			status = sja1000_ReadRegister(pSja1000Par, 0);             // read state
  			status = status & 0xfe; // clear ResetMode
 			sja1000_WriteRegister(pSja1000Par, 0,status);       
  		}
 
 		if (irq & 0x08)				// Overrun Interrupt
  		{
 			sja1000_WriteRegister(pSja1000Par, 1,0x0c); // Release Receive Buffer + ClearDataOverrun
  		}
  	}
 
 	return 1;		// TRUE = IRQ was served
}

/***************************************************************************************/
/*
int sja1000_interrupt(void *pSpecificPar, struct sja1000_admin *pSja1000Par)
{
	int ret=0;
	int x=30;

	if(!pSja1000Par)
		return 0;

//  HMM: Rubini's linux device drivers has erroneous statement about spin_trylock return value
//	the right treatment is as follows: 0 - failed, non-0 got lock (rubini: 0 - got lock)
//	see Linux Device Drivers 2nd edition, page 282.


//	XTRACE("InterruptProcedure - before spin_trylock...");

	if (!spin_trylock(&pSja1000Par->irq_lock))	{
//		XTRACE("...xxx");
//		XTRACE("spin_is_locked: %i", spin_is_locked(&pSja1000Par->irq_lock));
		return 0;	// irq handling is disabled for this chip
	}

	TRACE("InterruptProcedure");
	if (pSja1000Par->bCan_2B)
	{
		while(x>0)
		{
			if(PeliCanISR(pSja1000Par))
				ret=1;
			else
				break;
			x--;
		}
	}
	else
	{
		while(x>0)
		{
			if(BasicCanISR(pSja1000Par))
				ret=1;
			else
				break;
			x--;
		}
	}

	spin_unlock(&pSja1000Par->irq_lock);
	return ret;
}
*/
int sja1000_interrupt(void *pSpecificPar, struct sja1000_admin *pSja1000Par)
{
	int ret=0;
	int x=30;

	if(!pSja1000Par)
		return 0;

	TRACE("InterruptProcedure");
	if (pSja1000Par->bCan_2B)
	{
		while(x>0)
		{
			if(PeliCanISR(pSja1000Par))
				ret=1;
			else
				break;
			x--;
		}
	}
	else
	{
		while(x>0)
		{
			if(BasicCanISR(pSja1000Par))
				ret=1;
			else
				break;
			x--;
		}
	}
	return ret;
}

/***************************************************************************************/
int sja1000_register_isr(struct sja1000_admin *pSja1000Par, canbus_isr pIsr, struct canbus_admin *pCanBusPar)
{
	TRACE("registering isr()");
	if(!pSja1000Par)
		return -EINVAL;

	pSja1000Par->isr = pIsr;
	pSja1000Par->pCanBusParm = pCanBusPar;
	return 0;
}

/***************************************************************************************/
int sja1000_unregister_isr(struct sja1000_admin *pSja1000Par)
{
	TRACE("unregistering isr()");
	if(!pSja1000Par)
		return -EINVAL;

	pSja1000Par->isr = 0;
	pSja1000Par->pCanBusParm = NULL;
	return 0;
}
/***************************************************************************************/
int sja1000_register_device(char *name, int version, void *pSpecificPar, struct sja1000_access *access, int prefered_min, int prefered_max)
{
	int t,p;
	char buffer[MAX_DEVICE_NAME_LENGTH*2];
	
	TRACE("registering can device: %s",name);
	for(t=0;t<NUM_SJA1000_DEVICES;t++) // searching a free structure
	{
		if(sja1000_admin[t].in_use == 0)
		{
			struct canbus_access caccess;
			
			memset(&caccess,0,sizeof(caccess));
			memset(&sja1000_admin[t],0,sizeof(struct sja1000_admin));
			memcpy(&sja1000_admin[t].access, access,sizeof(struct sja1000_access));
			strcpy(buffer,name);
			buffer[MAX_DEVICE_NAME_LENGTH-1] = 0;
			strcpy(sja1000_admin[t].cDeviceName,buffer);
			for(p=0;p<strlen(sja1000_admin[t].cDeviceName);p++)
			{
				if(sja1000_admin[t].cDeviceName[p] == '|') // only device name
				{
					sja1000_admin[t].cDeviceName[p] = 0;
					break;
				}
			}
			strcpy(&buffer[strlen(buffer)],"|SJA 1000 Chipset driver");
			sja1000_admin[t].pDeviceParm = pSpecificPar;
			sja1000_admin[t].irq_lock = SPIN_LOCK_UNLOCKED;
			spin_lock_init(&(sja1000_admin[t].irq_lock));
			if (access->pRegisterIsr) 
				(access->pRegisterIsr)(pSpecificPar, sja1000_interrupt, &sja1000_admin[t]);
			sja1000_admin[t].in_use = 1;

 			caccess.pRegisterIsr   = (canbus_registerIsr)	sja1000_register_isr;
 			caccess.pUnregisterIsr = (canbus_unregisterIsr)	sja1000_unregister_isr;
  
 			caccess.pOpen  = (canbus_open_device)  sja1000_open_device;
 			caccess.pClose = (canbus_close_device) sja1000_close_device;
 			caccess.pInit  = (canbus_init_device)  sja1000_init_device;
 
 			caccess.pSetBaudrate  = (canbus_set_baudrate)	sja1000_set_baudrate;
 			caccess.pGetProperty  = (canbus_get_properties)	sja1000_get_properties;
 			caccess.pSetRegister  = (canbus_set_register)	sja1000_set_register;
 			caccess.pGetRegister  = (canbus_get_register)	sja1000_get_register;
 			caccess.pSetCanMode   = (canbus_set_can_mode)	sja1000_set_can_mode;
 			caccess.pSetBaudrateByConstant = (canbus_set_baudrate_by_constant)
 															sja1000_set_baudrate_by_constant;
 			caccess.pSetAcceptanceFilter = (canbus_set_acceptance_filter)
 															sja1000_set_acceptance_filter;
 
 			caccess.pSetCommand   = (canbus_set_command)	sja1000_set_command;
 			caccess.pTransmitData = (canbus_transmit_data)	sja1000_transmit_data;
 			caccess.pTestDevice   = (canbus_test_device)	sja1000_test_device;

			sja1000_admin[t].canbus_admin_number = canbus4linux_register_device(buffer, CANBUS4LINUX_VERSION, &sja1000_admin[t], &caccess, prefered_min, prefered_max);
			TRACE("sja1000_register_device() - finished");
			return t;
		}
	}
	
	return -1;
}

/***************************************************************************************/
int sja1000_unregister_device(int can_num)
{
 	if (sja1000_admin[can_num].in_use == 0)
 		return 0;
 
 	TRACE("unregistering can device: %s",sja1000_admin[can_num].cDeviceName);
 	sja1000_admin[can_num].canbus_admin_number = canbus4linux_unregister_device(sja1000_admin[can_num].canbus_admin_number);
 	if (sja1000_admin[can_num].access.pUnregisterIsr)
 		(sja1000_admin[can_num].access.pUnregisterIsr)(sja1000_admin[can_num].pDeviceParm);
 
 	memset(&sja1000_admin[can_num],0,sizeof(struct sja1000_admin));
	return 0;
}

/***************************************************************************************/
int init_module(void)
{
	TRACE("init_module()");
	memset(sja1000_admin,0,sizeof(sja1000_admin));
  	return 0;
}

/***************************************************************************************/
void cleanup_module(void)
{
  	TRACE("cleanup");
}

/***************************************************************************************/
EXPORT_SYMBOL(sja1000_unregister_device);
EXPORT_SYMBOL(sja1000_register_device);
MODULE_AUTHOR("Juergen Eder  <Juergen.Eder@gmx.de>");
MODULE_DESCRIPTION("SJA1000 chipset driver");

⌨️ 快捷键说明

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