📄 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 + -