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