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