📄 sja1000.c
字号:
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 + -