* sja1000 BasicCAN mode
@ 2011-11-14 17:08 Yuriy Kiselev
0 siblings, 0 replies; 3+ messages in thread
From: Yuriy Kiselev @ 2011-11-14 17:08 UTC (permalink / raw)
To: socketcan-users-0fE9KPoRgkgATYTw5x5z8w; +Cc: linux-can-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1.1: Type: text/plain, Size: 277 bytes --]
Hello!
Implementation of BasicCAN mode for SJA1000 is in attachment.
Now SJA1000_PELICAN_MODE macros in sja1000.h is used for definition PeliCAN
or BasicCAN mode. It would be nice to create some menuconfig-wrapper, I
think.
I use this code for a few weeks and it looks stable.
[-- Attachment #1.2: Type: text/html, Size: 325 bytes --]
[-- Attachment #2: socketcan_sja1000_basicmod_impl.patch --]
[-- Type: application/octet-stream, Size: 11279 bytes --]
diff -ru trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.c trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.c
--- trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.c 2011-11-14 20:46:35.074737955 +0400
+++ trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.c 2011-11-14 20:56:00.083183431 +0400
@@ -117,22 +117,43 @@
static void set_reset_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
unsigned char status = priv->read_reg(priv, REG_MOD);
+#else
+ unsigned char status = priv->read_reg(priv, REG_CR);
+#endif
int i;
/* disable interrupts */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_IER, IRQ_OFF);
+#else
+ priv->write_reg(priv, REG_CR, status & IRQ_OFF);
+#endif
for (i = 0; i < 100; i++) {
- /* check reset bit */
+ // check reset bit
+#ifdef SJA1000_PELICAN_MODE
if (status & MOD_RM) {
+#else
+ if (status & CR_RRQ) {
+#endif
priv->can.state = CAN_STATE_STOPPED;
return;
}
- priv->write_reg(priv, REG_MOD, MOD_RM); /* reset chip */
+ /* reset chip */
+#ifdef SJA1000_PELICAN_MODE
+ priv->write_reg(priv, REG_MOD, MOD_RM);
+#else
+ priv->write_reg(priv, REG_CR, CR_RRQ);
+#endif
udelay(10);
+#ifdef SJA1000_PELICAN_MODE
status = priv->read_reg(priv, REG_MOD);
+#else
+ status = priv->read_reg(priv, REG_CR);
+#endif
}
dev_err(ND2D(dev), "setting SJA1000 into reset mode failed!\n");
@@ -141,26 +162,50 @@
static void set_normal_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
unsigned char status = priv->read_reg(priv, REG_MOD);
+#else
+ unsigned char status = priv->read_reg(priv, REG_CR);
+#endif
int i;
for (i = 0; i < 100; i++) {
/* check reset bit */
+#ifdef SJA1000_PELICAN_MODE
if ((status & MOD_RM) == 0) {
+#else
+ if ((status & CR_RRQ) == 0) {
+#endif
priv->can.state = CAN_STATE_ERROR_ACTIVE;
/* enable interrupts */
+#ifdef SJA1000_PELICAN_MODE
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
priv->write_reg(priv, REG_IER, IRQ_ALL);
+
else
priv->write_reg(priv, REG_IER,
IRQ_ALL & ~IRQ_BEI);
return;
+#else
+ priv->write_reg(priv, REG_CR, status | IRQ_ALL);
+ return;
+#endif
}
+
/* set chip to normal mode */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_MOD, 0x00);
+#else
+ //status = priv->read_reg(priv, REG_CR);
+ priv->write_reg(priv, REG_CR, status & ~CR_RRQ);
+#endif
udelay(10);
+#ifdef SJA1000_PELICAN_MODE
status = priv->read_reg(priv, REG_MOD);
+#else
+ status = priv->read_reg(priv, REG_CR);
+#endif
}
dev_err(ND2D(dev), "setting SJA1000 into normal mode failed!\n");
@@ -175,9 +220,11 @@
set_reset_mode(dev);
/* Clear error counters and error code capture */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_TXERR, 0x0);
priv->write_reg(priv, REG_RXERR, 0x0);
priv->read_reg(priv, REG_ECC);
+#endif
/* leave reset mode */
set_normal_mode(dev);
@@ -230,8 +277,13 @@
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
bec->txerr = priv->read_reg(priv, REG_TXERR);
bec->rxerr = priv->read_reg(priv, REG_RXERR);
+#else
+ bec->txerr = 0;
+ bec->rxerr = 0;
+#endif
return 0;
}
@@ -247,11 +299,17 @@
static void chipset_init(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+ struct can_bittiming bt;
/* set clock divider and output control register */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_CDR, priv->cdr | CDR_PELICAN);
+#else
+ priv->write_reg(priv, REG_CDR, priv->cdr);
+#endif
/* set acceptance filter (accept all) */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_ACCC0, 0x00);
priv->write_reg(priv, REG_ACCC1, 0x00);
priv->write_reg(priv, REG_ACCC2, 0x00);
@@ -261,6 +319,11 @@
priv->write_reg(priv, REG_ACCM1, 0xFF);
priv->write_reg(priv, REG_ACCM2, 0xFF);
priv->write_reg(priv, REG_ACCM3, 0xFF);
+#else
+ priv->write_reg(priv, REG_AC, 0x00);
+ priv->write_reg(priv, REG_AM, 0xFF);
+
+#endif
priv->write_reg(priv, REG_OCR, priv->ocr | OCR_MODE_NORMAL);
}
@@ -298,6 +361,8 @@
fi |= FI_RTR;
if (id & CAN_EFF_FLAG) {
+ /* Extended frame. Not available in BasicCAN mode. */
+#ifdef SJA1000_PELICAN_MODE
fi |= FI_FF;
dreg = EFF_BUF;
priv->write_reg(priv, REG_FI, fi);
@@ -305,15 +370,26 @@
priv->write_reg(priv, REG_ID2, (id & 0x001fe000) >> (5 + 8));
priv->write_reg(priv, REG_ID3, (id & 0x00001fe0) >> 5);
priv->write_reg(priv, REG_ID4, (id & 0x0000001f) << 3);
+#endif
} else {
+ /* Standard frame */
+#ifdef SJA1000_PELICAN_MODE
dreg = SFF_BUF;
priv->write_reg(priv, REG_FI, fi);
priv->write_reg(priv, REG_ID1, (id & 0x000007f8) >> 3);
priv->write_reg(priv, REG_ID2, (id & 0x00000007) << 5);
+#else
+ priv->write_reg(priv, REG_TXB, (id & 0x000007f8) >> 3);
+ priv->write_reg(priv, REG_TXB + 1, ((id & 0x00000007) << 5) | fi);
+#endif
}
for (i = 0; i < dlc; i++)
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, dreg++, cf->data[i]);
+#else
+ priv->write_reg(priv, REG_TXB + 2 + i, cf->data[i]);
+#endif
dev->trans_start = jiffies;
@@ -344,8 +420,14 @@
if (skb == NULL)
return;
+#ifdef SJA1000_PELICAN_MODE
fi = priv->read_reg(priv, REG_FI);
+#else
+ /* Read RTR & DLC */
+ fi = priv->read_reg(priv, REG_RXB + 1) & 0x1F;
+#endif
+#ifdef SJA1000_PELICAN_MODE
if (fi & FI_FF) {
/* extended frame format (EFF) */
dreg = EFF_BUF;
@@ -360,13 +442,22 @@
id = (priv->read_reg(priv, REG_ID1) << 3)
| (priv->read_reg(priv, REG_ID2) >> 5);
}
+#else
+ id = (priv->read_reg(priv, REG_RXB) << 3)
+ | ((priv->read_reg(priv, REG_RXB + 1) & 0xE0) >> 5);
+#endif
if (fi & FI_RTR) {
id |= CAN_RTR_FLAG;
} else {
+ /* DLC field is same in TXB/RXB (basiccan) and FI (pelican) registers */
cf->can_dlc = get_can_dlc(fi & 0x0F);
for (i = 0; i < cf->can_dlc; i++)
+#ifdef SJA1000_PELICAN_MODE
cf->data[i] = priv->read_reg(priv, dreg++);
+#else
+ cf->data[i] = priv->read_reg(priv, REG_RXB + 2 + i);
+#endif
}
cf->can_id = id;
@@ -423,6 +514,7 @@
} else
state = CAN_STATE_ERROR_ACTIVE;
}
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Bus Error Interrupt */
if (isrc & IRQ_BEI) {
/* bus error interrupt */
priv->can.can_stats.bus_error++;
@@ -451,6 +543,9 @@
if ((ecc & ECC_DIR) == 0)
cf->data[2] |= CAN_ERR_PROT_TX;
}
+#endif
+
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Error Passive Interrupt */
if (isrc & IRQ_EPI) {
/* error passive interrupt */
dev_dbg(ND2D(dev), "error passive interrupt\n");
@@ -459,6 +554,9 @@
else
state = CAN_STATE_ERROR_ACTIVE;
}
+#endif
+
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Arbitration Lost Interrupt */
if (isrc & IRQ_ALI) {
/* arbitration lost interrupt */
dev_dbg(ND2D(dev), "arbitration lost interrupt\n");
@@ -468,11 +566,18 @@
cf->can_id |= CAN_ERR_LOSTARB;
cf->data[0] = alc & 0x1f;
}
+#endif
if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
state == CAN_STATE_ERROR_PASSIVE)) {
+#ifdef SJA1000_PELICAN_MODE
uint8_t rxerr = priv->read_reg(priv, REG_RXERR);
uint8_t txerr = priv->read_reg(priv, REG_TXERR);
+#else
+ uint8_t rxerr = 0;
+ uint8_t txerr = 0;
+#endif
+
cf->can_id |= CAN_ERR_CRTL;
if (state == CAN_STATE_ERROR_WARNING) {
priv->can.can_stats.error_warning++;
@@ -519,7 +624,11 @@
int n = 0;
/* Shared interrupts and IRQ off? */
+#ifdef SJA1000_PELICAN_MODE
if (priv->read_reg(priv, REG_IER) == IRQ_OFF)
+#else
+ if ((priv->read_reg(priv, REG_CR) & IRQ_ALL) == 0)
+#endif
return IRQ_NONE;
if (priv->pre_irq)
@@ -534,7 +643,11 @@
if (isrc & IRQ_TI) {
/* transmission complete interrupt */
- stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xf;
+#ifdef SJA1000_PELICAN_MODE
+ stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xF;
+#else
+ stats->tx_bytes += priv->read_reg(priv, REG_TXB + 1) & 0xF;
+#endif
stats->tx_packets++;
can_get_echo_skb(dev, 0);
netif_wake_queue(dev);
@@ -546,7 +659,11 @@
status = priv->read_reg(priv, REG_SR);
}
}
+#ifdef SJA1000_PELICAN_MODE
if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
+#else
+ if (isrc & (IRQ_DOI | IRQ_EI)) {
+#endif
/* error interrupt */
if (sja1000_err(dev, isrc, status))
break;
diff -ru trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.h trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.h
--- trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.h 2011-11-14 20:49:44.526408577 +0400
+++ trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.h 2011-11-14 20:50:20.813395105 +0400
@@ -50,10 +50,14 @@
#include <socketcan/can/dev.h>
#include <socketcan/can/platform/sja1000.h>
+#define SJA1000_PELICAN_MODE /* BasicCAN accepted if not defined */
+
#define SJA1000_ECHO_SKB_MAX 1 /* the SJA1000 has one TX buffer object */
#define SJA1000_MAX_IRQ 20 /* max. number of interrupts handled in ISR */
+#ifdef SJA1000_PELICAN_MODE
+
/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
#define REG_MOD 0x00
#define REG_CMR 0x01
@@ -76,19 +80,10 @@
#define REG_RMC 0x1D
#define REG_RBSA 0x1E
-/* Common registers - manual section 6.5 */
-#define REG_BTR0 0x06
-#define REG_BTR1 0x07
-#define REG_OCR 0x08
-#define REG_CDR 0x1F
-
#define REG_FI 0x10
#define SFF_BUF 0x13
#define EFF_BUF 0x15
-#define FI_FF 0x80
-#define FI_RTR 0x40
-
#define REG_ID1 0x11
#define REG_ID2 0x12
#define REG_ID3 0x13
@@ -96,6 +91,27 @@
#define CAN_RAM 0x20
+#else /* SJA1000_PELICAN_MODE */
+
+/* SJA1000 registers - manual section 6.3 (Basiccan Mode) */
+#define REG_CR 0x00
+#define REG_CMR 0x01
+#define REG_SR 0x02
+#define REG_IR 0x03
+#define REG_AC 0x04
+#define REG_AM 0x05
+#define REG_TXB 0x0A
+#define REG_RXB 0x14
+
+#endif /* SJA1000_PELICAN_MODE */
+
+/* Common registers - manual section 6.5 */
+#define REG_BTR0 0x06
+#define REG_BTR1 0x07
+#define REG_OCR 0x08
+#define REG_CDR 0x1F
+
+#ifdef SJA1000_PELICAN_MODE
/* mode register */
#define MOD_RM 0x01
#define MOD_LOM 0x02
@@ -137,11 +153,53 @@
/* ECC register */
#define ECC_SEG 0x1F
#define ECC_DIR 0x20
-#define ECC_ERR 6
+#define ECC_ERR 0x06
#define ECC_BIT 0x00
#define ECC_FORM 0x40
#define ECC_STUFF 0x80
-#define ECC_MASK 0xc0
+#define ECC_MASK 0xC0
+
+#define FI_FF 0x80
+#define FI_RTR 0x40
+
+#else /* SJA1000_PELICAN_MODE */
+
+/* control register */
+#define CR_RRQ 0x01
+#define CR_RIE 0x02
+#define CR_TIE 0x04
+#define CR_EIE 0x08
+#define CR_OIE 0x10
+#define IRQ_OFF CR_RRQ
+#define IRQ_ALL (CR_RIE | CR_TIE | CR_EIE | CR_OIE)
+
+/* command register */
+#define CMD_TR 0x01
+#define CMD_AT 0x02
+#define CMD_RRB 0x04
+#define CMD_CDO 0x08
+#define CMD_GTS 0x10
+
+/* status register */
+#define SR_RBS 0x01
+#define SR_DOS 0x02
+#define SR_TBS 0x04
+#define SR_TCS 0x08
+#define SR_RS 0x10
+#define SR_TS 0x20
+#define SR_ES 0x40
+#define SR_BS 0x80
+
+/* interrupt sources */
+#define IRQ_RI 0x01
+#define IRQ_TI 0x02
+#define IRQ_EI 0x04
+#define IRQ_DOI 0x08
+#define IRQ_WUI 0x10
+
+#define FI_RTR 0x10
+
+#endif /* SJA1000_PELICAN_MODE */
/*
* Flags for sja1000priv.flags
[-- Attachment #3: Type: text/plain, Size: 191 bytes --]
_______________________________________________
Socketcan-users mailing list
Socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-users
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: sja1000 BasicCAN mode
@ 2011-11-14 18:03 Oliver Hartkopp
[not found] ` <CAF8b2jLH8CTOU5ZBTdH7yFhhb0=QmP2Y_Lkom80Bxfw0AvjA6g@mail.gmail.com>
0 siblings, 1 reply; 3+ messages in thread
From: Oliver Hartkopp @ 2011-11-14 18:03 UTC (permalink / raw)
To: Yuriy Kiselev; +Cc: socketcan-users, linux-can-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 12486 bytes --]
Hello Yuriy,
what's your motivation for the BasicCAN mode support?
My biggest concern is that you leave the driver as a #ifdef hell ...
The second thing, is that you urge all CAN interfaces in the system to be
BasicCAN *or* PeliCAN mode. No chance to mix the hardware and to have a
per-device setting.
If such a functionality is to be implemented (and you have a good reason for
BasicCAN mode), this could be done by creating a new per-device flag.
E.g.
#define SJA1000_BASIC_CAN 0x02
for sja1000priv.flags
Regards,
Oliver
ps. pls send patches always inline for a review
pps. and no html mails %-)
-------- Original Message --------
Subject: [Socketcan-users] sja1000 BasicCAN mode
Date: Mon, 14 Nov 2011 21:08:29 +0400
From: Yuriy Kiselev <kiselev.yuriy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
CC: linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Hello!
Implementation of BasicCAN mode for SJA1000 is in attachment.
Now SJA1000_PELICAN_MODE macros in sja1000.h is used for definition PeliCAN or
BasicCAN mode. It would be nice to create some menuconfig-wrapper, I think.
I use this code for a few weeks and it looks stable.
diff -ru trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.c trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.c
--- trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.c 2011-11-14 20:46:35.074737955 +0400
+++ trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.c 2011-11-14 20:56:00.083183431 +0400
@@ -117,22 +117,43 @@
static void set_reset_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
unsigned char status = priv->read_reg(priv, REG_MOD);
+#else
+ unsigned char status = priv->read_reg(priv, REG_CR);
+#endif
int i;
/* disable interrupts */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_IER, IRQ_OFF);
+#else
+ priv->write_reg(priv, REG_CR, status & IRQ_OFF);
+#endif
for (i = 0; i < 100; i++) {
- /* check reset bit */
+ // check reset bit
+#ifdef SJA1000_PELICAN_MODE
if (status & MOD_RM) {
+#else
+ if (status & CR_RRQ) {
+#endif
priv->can.state = CAN_STATE_STOPPED;
return;
}
- priv->write_reg(priv, REG_MOD, MOD_RM); /* reset chip */
+ /* reset chip */
+#ifdef SJA1000_PELICAN_MODE
+ priv->write_reg(priv, REG_MOD, MOD_RM);
+#else
+ priv->write_reg(priv, REG_CR, CR_RRQ);
+#endif
udelay(10);
+#ifdef SJA1000_PELICAN_MODE
status = priv->read_reg(priv, REG_MOD);
+#else
+ status = priv->read_reg(priv, REG_CR);
+#endif
}
dev_err(ND2D(dev), "setting SJA1000 into reset mode failed!\n");
@@ -141,26 +162,50 @@
static void set_normal_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
unsigned char status = priv->read_reg(priv, REG_MOD);
+#else
+ unsigned char status = priv->read_reg(priv, REG_CR);
+#endif
int i;
for (i = 0; i < 100; i++) {
/* check reset bit */
+#ifdef SJA1000_PELICAN_MODE
if ((status & MOD_RM) == 0) {
+#else
+ if ((status & CR_RRQ) == 0) {
+#endif
priv->can.state = CAN_STATE_ERROR_ACTIVE;
/* enable interrupts */
+#ifdef SJA1000_PELICAN_MODE
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
priv->write_reg(priv, REG_IER, IRQ_ALL);
+
else
priv->write_reg(priv, REG_IER,
IRQ_ALL & ~IRQ_BEI);
return;
+#else
+ priv->write_reg(priv, REG_CR, status | IRQ_ALL);
+ return;
+#endif
}
+
/* set chip to normal mode */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_MOD, 0x00);
+#else
+ //status = priv->read_reg(priv, REG_CR);
+ priv->write_reg(priv, REG_CR, status & ~CR_RRQ);
+#endif
udelay(10);
+#ifdef SJA1000_PELICAN_MODE
status = priv->read_reg(priv, REG_MOD);
+#else
+ status = priv->read_reg(priv, REG_CR);
+#endif
}
dev_err(ND2D(dev), "setting SJA1000 into normal mode failed!\n");
@@ -175,9 +220,11 @@
set_reset_mode(dev);
/* Clear error counters and error code capture */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_TXERR, 0x0);
priv->write_reg(priv, REG_RXERR, 0x0);
priv->read_reg(priv, REG_ECC);
+#endif
/* leave reset mode */
set_normal_mode(dev);
@@ -230,8 +277,13 @@
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
bec->txerr = priv->read_reg(priv, REG_TXERR);
bec->rxerr = priv->read_reg(priv, REG_RXERR);
+#else
+ bec->txerr = 0;
+ bec->rxerr = 0;
+#endif
return 0;
}
@@ -247,11 +299,17 @@
static void chipset_init(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+ struct can_bittiming bt;
/* set clock divider and output control register */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_CDR, priv->cdr | CDR_PELICAN);
+#else
+ priv->write_reg(priv, REG_CDR, priv->cdr);
+#endif
/* set acceptance filter (accept all) */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_ACCC0, 0x00);
priv->write_reg(priv, REG_ACCC1, 0x00);
priv->write_reg(priv, REG_ACCC2, 0x00);
@@ -261,6 +319,11 @@
priv->write_reg(priv, REG_ACCM1, 0xFF);
priv->write_reg(priv, REG_ACCM2, 0xFF);
priv->write_reg(priv, REG_ACCM3, 0xFF);
+#else
+ priv->write_reg(priv, REG_AC, 0x00);
+ priv->write_reg(priv, REG_AM, 0xFF);
+
+#endif
priv->write_reg(priv, REG_OCR, priv->ocr | OCR_MODE_NORMAL);
}
@@ -298,6 +361,8 @@
fi |= FI_RTR;
if (id & CAN_EFF_FLAG) {
+ /* Extended frame. Not available in BasicCAN mode. */
+#ifdef SJA1000_PELICAN_MODE
fi |= FI_FF;
dreg = EFF_BUF;
priv->write_reg(priv, REG_FI, fi);
@@ -305,15 +370,26 @@
priv->write_reg(priv, REG_ID2, (id & 0x001fe000) >> (5 + 8));
priv->write_reg(priv, REG_ID3, (id & 0x00001fe0) >> 5);
priv->write_reg(priv, REG_ID4, (id & 0x0000001f) << 3);
+#endif
} else {
+ /* Standard frame */
+#ifdef SJA1000_PELICAN_MODE
dreg = SFF_BUF;
priv->write_reg(priv, REG_FI, fi);
priv->write_reg(priv, REG_ID1, (id & 0x000007f8) >> 3);
priv->write_reg(priv, REG_ID2, (id & 0x00000007) << 5);
+#else
+ priv->write_reg(priv, REG_TXB, (id & 0x000007f8) >> 3);
+ priv->write_reg(priv, REG_TXB + 1, ((id & 0x00000007) << 5) | fi);
+#endif
}
for (i = 0; i < dlc; i++)
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, dreg++, cf->data[i]);
+#else
+ priv->write_reg(priv, REG_TXB + 2 + i, cf->data[i]);
+#endif
dev->trans_start = jiffies;
@@ -344,8 +420,14 @@
if (skb == NULL)
return;
+#ifdef SJA1000_PELICAN_MODE
fi = priv->read_reg(priv, REG_FI);
+#else
+ /* Read RTR & DLC */
+ fi = priv->read_reg(priv, REG_RXB + 1) & 0x1F;
+#endif
+#ifdef SJA1000_PELICAN_MODE
if (fi & FI_FF) {
/* extended frame format (EFF) */
dreg = EFF_BUF;
@@ -360,13 +442,22 @@
id = (priv->read_reg(priv, REG_ID1) << 3)
| (priv->read_reg(priv, REG_ID2) >> 5);
}
+#else
+ id = (priv->read_reg(priv, REG_RXB) << 3)
+ | ((priv->read_reg(priv, REG_RXB + 1) & 0xE0) >> 5);
+#endif
if (fi & FI_RTR) {
id |= CAN_RTR_FLAG;
} else {
+ /* DLC field is same in TXB/RXB (basiccan) and FI (pelican) registers */
cf->can_dlc = get_can_dlc(fi & 0x0F);
for (i = 0; i < cf->can_dlc; i++)
+#ifdef SJA1000_PELICAN_MODE
cf->data[i] = priv->read_reg(priv, dreg++);
+#else
+ cf->data[i] = priv->read_reg(priv, REG_RXB + 2 + i);
+#endif
}
cf->can_id = id;
@@ -423,6 +514,7 @@
} else
state = CAN_STATE_ERROR_ACTIVE;
}
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Bus Error Interrupt */
if (isrc & IRQ_BEI) {
/* bus error interrupt */
priv->can.can_stats.bus_error++;
@@ -451,6 +543,9 @@
if ((ecc & ECC_DIR) == 0)
cf->data[2] |= CAN_ERR_PROT_TX;
}
+#endif
+
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Error Passive Interrupt */
if (isrc & IRQ_EPI) {
/* error passive interrupt */
dev_dbg(ND2D(dev), "error passive interrupt\n");
@@ -459,6 +554,9 @@
else
state = CAN_STATE_ERROR_ACTIVE;
}
+#endif
+
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Arbitration Lost Interrupt */
if (isrc & IRQ_ALI) {
/* arbitration lost interrupt */
dev_dbg(ND2D(dev), "arbitration lost interrupt\n");
@@ -468,11 +566,18 @@
cf->can_id |= CAN_ERR_LOSTARB;
cf->data[0] = alc & 0x1f;
}
+#endif
if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
state == CAN_STATE_ERROR_PASSIVE)) {
+#ifdef SJA1000_PELICAN_MODE
uint8_t rxerr = priv->read_reg(priv, REG_RXERR);
uint8_t txerr = priv->read_reg(priv, REG_TXERR);
+#else
+ uint8_t rxerr = 0;
+ uint8_t txerr = 0;
+#endif
+
cf->can_id |= CAN_ERR_CRTL;
if (state == CAN_STATE_ERROR_WARNING) {
priv->can.can_stats.error_warning++;
@@ -519,7 +624,11 @@
int n = 0;
/* Shared interrupts and IRQ off? */
+#ifdef SJA1000_PELICAN_MODE
if (priv->read_reg(priv, REG_IER) == IRQ_OFF)
+#else
+ if ((priv->read_reg(priv, REG_CR) & IRQ_ALL) == 0)
+#endif
return IRQ_NONE;
if (priv->pre_irq)
@@ -534,7 +643,11 @@
if (isrc & IRQ_TI) {
/* transmission complete interrupt */
- stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xf;
+#ifdef SJA1000_PELICAN_MODE
+ stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xF;
+#else
+ stats->tx_bytes += priv->read_reg(priv, REG_TXB + 1) & 0xF;
+#endif
stats->tx_packets++;
can_get_echo_skb(dev, 0);
netif_wake_queue(dev);
@@ -546,7 +659,11 @@
status = priv->read_reg(priv, REG_SR);
}
}
+#ifdef SJA1000_PELICAN_MODE
if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
+#else
+ if (isrc & (IRQ_DOI | IRQ_EI)) {
+#endif
/* error interrupt */
if (sja1000_err(dev, isrc, status))
break;
diff -ru trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.h trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.h
--- trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.h 2011-11-14 20:49:44.526408577 +0400
+++ trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.h 2011-11-14 20:50:20.813395105 +0400
@@ -50,10 +50,14 @@
#include <socketcan/can/dev.h>
#include <socketcan/can/platform/sja1000.h>
+#define SJA1000_PELICAN_MODE /* BasicCAN accepted if not defined */
+
#define SJA1000_ECHO_SKB_MAX 1 /* the SJA1000 has one TX buffer object */
#define SJA1000_MAX_IRQ 20 /* max. number of interrupts handled in ISR */
+#ifdef SJA1000_PELICAN_MODE
+
/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
#define REG_MOD 0x00
#define REG_CMR 0x01
@@ -76,19 +80,10 @@
#define REG_RMC 0x1D
#define REG_RBSA 0x1E
-/* Common registers - manual section 6.5 */
-#define REG_BTR0 0x06
-#define REG_BTR1 0x07
-#define REG_OCR 0x08
-#define REG_CDR 0x1F
-
#define REG_FI 0x10
#define SFF_BUF 0x13
#define EFF_BUF 0x15
-#define FI_FF 0x80
-#define FI_RTR 0x40
-
#define REG_ID1 0x11
#define REG_ID2 0x12
#define REG_ID3 0x13
@@ -96,6 +91,27 @@
#define CAN_RAM 0x20
+#else /* SJA1000_PELICAN_MODE */
+
+/* SJA1000 registers - manual section 6.3 (Basiccan Mode) */
+#define REG_CR 0x00
+#define REG_CMR 0x01
+#define REG_SR 0x02
+#define REG_IR 0x03
+#define REG_AC 0x04
+#define REG_AM 0x05
+#define REG_TXB 0x0A
+#define REG_RXB 0x14
+
+#endif /* SJA1000_PELICAN_MODE */
+
+/* Common registers - manual section 6.5 */
+#define REG_BTR0 0x06
+#define REG_BTR1 0x07
+#define REG_OCR 0x08
+#define REG_CDR 0x1F
+
+#ifdef SJA1000_PELICAN_MODE
/* mode register */
#define MOD_RM 0x01
#define MOD_LOM 0x02
@@ -137,11 +153,53 @@
/* ECC register */
#define ECC_SEG 0x1F
#define ECC_DIR 0x20
-#define ECC_ERR 6
+#define ECC_ERR 0x06
#define ECC_BIT 0x00
#define ECC_FORM 0x40
#define ECC_STUFF 0x80
-#define ECC_MASK 0xc0
+#define ECC_MASK 0xC0
+
+#define FI_FF 0x80
+#define FI_RTR 0x40
+
+#else /* SJA1000_PELICAN_MODE */
+
+/* control register */
+#define CR_RRQ 0x01
+#define CR_RIE 0x02
+#define CR_TIE 0x04
+#define CR_EIE 0x08
+#define CR_OIE 0x10
+#define IRQ_OFF CR_RRQ
+#define IRQ_ALL (CR_RIE | CR_TIE | CR_EIE | CR_OIE)
+
+/* command register */
+#define CMD_TR 0x01
+#define CMD_AT 0x02
+#define CMD_RRB 0x04
+#define CMD_CDO 0x08
+#define CMD_GTS 0x10
+
+/* status register */
+#define SR_RBS 0x01
+#define SR_DOS 0x02
+#define SR_TBS 0x04
+#define SR_TCS 0x08
+#define SR_RS 0x10
+#define SR_TS 0x20
+#define SR_ES 0x40
+#define SR_BS 0x80
+
+/* interrupt sources */
+#define IRQ_RI 0x01
+#define IRQ_TI 0x02
+#define IRQ_EI 0x04
+#define IRQ_DOI 0x08
+#define IRQ_WUI 0x10
+
+#define FI_RTR 0x10
+
+#endif /* SJA1000_PELICAN_MODE */
/*
* Flags for sja1000priv.flags
[-- Attachment #2: socketcan_sja1000_basicmod_impl.patch --]
[-- Type: application/octet-stream, Size: 11279 bytes --]
diff -ru trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.c trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.c
--- trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.c 2011-11-14 20:46:35.074737955 +0400
+++ trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.c 2011-11-14 20:56:00.083183431 +0400
@@ -117,22 +117,43 @@
static void set_reset_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
unsigned char status = priv->read_reg(priv, REG_MOD);
+#else
+ unsigned char status = priv->read_reg(priv, REG_CR);
+#endif
int i;
/* disable interrupts */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_IER, IRQ_OFF);
+#else
+ priv->write_reg(priv, REG_CR, status & IRQ_OFF);
+#endif
for (i = 0; i < 100; i++) {
- /* check reset bit */
+ // check reset bit
+#ifdef SJA1000_PELICAN_MODE
if (status & MOD_RM) {
+#else
+ if (status & CR_RRQ) {
+#endif
priv->can.state = CAN_STATE_STOPPED;
return;
}
- priv->write_reg(priv, REG_MOD, MOD_RM); /* reset chip */
+ /* reset chip */
+#ifdef SJA1000_PELICAN_MODE
+ priv->write_reg(priv, REG_MOD, MOD_RM);
+#else
+ priv->write_reg(priv, REG_CR, CR_RRQ);
+#endif
udelay(10);
+#ifdef SJA1000_PELICAN_MODE
status = priv->read_reg(priv, REG_MOD);
+#else
+ status = priv->read_reg(priv, REG_CR);
+#endif
}
dev_err(ND2D(dev), "setting SJA1000 into reset mode failed!\n");
@@ -141,26 +162,50 @@
static void set_normal_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
unsigned char status = priv->read_reg(priv, REG_MOD);
+#else
+ unsigned char status = priv->read_reg(priv, REG_CR);
+#endif
int i;
for (i = 0; i < 100; i++) {
/* check reset bit */
+#ifdef SJA1000_PELICAN_MODE
if ((status & MOD_RM) == 0) {
+#else
+ if ((status & CR_RRQ) == 0) {
+#endif
priv->can.state = CAN_STATE_ERROR_ACTIVE;
/* enable interrupts */
+#ifdef SJA1000_PELICAN_MODE
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
priv->write_reg(priv, REG_IER, IRQ_ALL);
+
else
priv->write_reg(priv, REG_IER,
IRQ_ALL & ~IRQ_BEI);
return;
+#else
+ priv->write_reg(priv, REG_CR, status | IRQ_ALL);
+ return;
+#endif
}
+
/* set chip to normal mode */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_MOD, 0x00);
+#else
+ //status = priv->read_reg(priv, REG_CR);
+ priv->write_reg(priv, REG_CR, status & ~CR_RRQ);
+#endif
udelay(10);
+#ifdef SJA1000_PELICAN_MODE
status = priv->read_reg(priv, REG_MOD);
+#else
+ status = priv->read_reg(priv, REG_CR);
+#endif
}
dev_err(ND2D(dev), "setting SJA1000 into normal mode failed!\n");
@@ -175,9 +220,11 @@
set_reset_mode(dev);
/* Clear error counters and error code capture */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_TXERR, 0x0);
priv->write_reg(priv, REG_RXERR, 0x0);
priv->read_reg(priv, REG_ECC);
+#endif
/* leave reset mode */
set_normal_mode(dev);
@@ -230,8 +277,13 @@
{
struct sja1000_priv *priv = netdev_priv(dev);
+#ifdef SJA1000_PELICAN_MODE
bec->txerr = priv->read_reg(priv, REG_TXERR);
bec->rxerr = priv->read_reg(priv, REG_RXERR);
+#else
+ bec->txerr = 0;
+ bec->rxerr = 0;
+#endif
return 0;
}
@@ -247,11 +299,17 @@
static void chipset_init(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
+ struct can_bittiming bt;
/* set clock divider and output control register */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_CDR, priv->cdr | CDR_PELICAN);
+#else
+ priv->write_reg(priv, REG_CDR, priv->cdr);
+#endif
/* set acceptance filter (accept all) */
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, REG_ACCC0, 0x00);
priv->write_reg(priv, REG_ACCC1, 0x00);
priv->write_reg(priv, REG_ACCC2, 0x00);
@@ -261,6 +319,11 @@
priv->write_reg(priv, REG_ACCM1, 0xFF);
priv->write_reg(priv, REG_ACCM2, 0xFF);
priv->write_reg(priv, REG_ACCM3, 0xFF);
+#else
+ priv->write_reg(priv, REG_AC, 0x00);
+ priv->write_reg(priv, REG_AM, 0xFF);
+
+#endif
priv->write_reg(priv, REG_OCR, priv->ocr | OCR_MODE_NORMAL);
}
@@ -298,6 +361,8 @@
fi |= FI_RTR;
if (id & CAN_EFF_FLAG) {
+ /* Extended frame. Not available in BasicCAN mode. */
+#ifdef SJA1000_PELICAN_MODE
fi |= FI_FF;
dreg = EFF_BUF;
priv->write_reg(priv, REG_FI, fi);
@@ -305,15 +370,26 @@
priv->write_reg(priv, REG_ID2, (id & 0x001fe000) >> (5 + 8));
priv->write_reg(priv, REG_ID3, (id & 0x00001fe0) >> 5);
priv->write_reg(priv, REG_ID4, (id & 0x0000001f) << 3);
+#endif
} else {
+ /* Standard frame */
+#ifdef SJA1000_PELICAN_MODE
dreg = SFF_BUF;
priv->write_reg(priv, REG_FI, fi);
priv->write_reg(priv, REG_ID1, (id & 0x000007f8) >> 3);
priv->write_reg(priv, REG_ID2, (id & 0x00000007) << 5);
+#else
+ priv->write_reg(priv, REG_TXB, (id & 0x000007f8) >> 3);
+ priv->write_reg(priv, REG_TXB + 1, ((id & 0x00000007) << 5) | fi);
+#endif
}
for (i = 0; i < dlc; i++)
+#ifdef SJA1000_PELICAN_MODE
priv->write_reg(priv, dreg++, cf->data[i]);
+#else
+ priv->write_reg(priv, REG_TXB + 2 + i, cf->data[i]);
+#endif
dev->trans_start = jiffies;
@@ -344,8 +420,14 @@
if (skb == NULL)
return;
+#ifdef SJA1000_PELICAN_MODE
fi = priv->read_reg(priv, REG_FI);
+#else
+ /* Read RTR & DLC */
+ fi = priv->read_reg(priv, REG_RXB + 1) & 0x1F;
+#endif
+#ifdef SJA1000_PELICAN_MODE
if (fi & FI_FF) {
/* extended frame format (EFF) */
dreg = EFF_BUF;
@@ -360,13 +442,22 @@
id = (priv->read_reg(priv, REG_ID1) << 3)
| (priv->read_reg(priv, REG_ID2) >> 5);
}
+#else
+ id = (priv->read_reg(priv, REG_RXB) << 3)
+ | ((priv->read_reg(priv, REG_RXB + 1) & 0xE0) >> 5);
+#endif
if (fi & FI_RTR) {
id |= CAN_RTR_FLAG;
} else {
+ /* DLC field is same in TXB/RXB (basiccan) and FI (pelican) registers */
cf->can_dlc = get_can_dlc(fi & 0x0F);
for (i = 0; i < cf->can_dlc; i++)
+#ifdef SJA1000_PELICAN_MODE
cf->data[i] = priv->read_reg(priv, dreg++);
+#else
+ cf->data[i] = priv->read_reg(priv, REG_RXB + 2 + i);
+#endif
}
cf->can_id = id;
@@ -423,6 +514,7 @@
} else
state = CAN_STATE_ERROR_ACTIVE;
}
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Bus Error Interrupt */
if (isrc & IRQ_BEI) {
/* bus error interrupt */
priv->can.can_stats.bus_error++;
@@ -451,6 +543,9 @@
if ((ecc & ECC_DIR) == 0)
cf->data[2] |= CAN_ERR_PROT_TX;
}
+#endif
+
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Error Passive Interrupt */
if (isrc & IRQ_EPI) {
/* error passive interrupt */
dev_dbg(ND2D(dev), "error passive interrupt\n");
@@ -459,6 +554,9 @@
else
state = CAN_STATE_ERROR_ACTIVE;
}
+#endif
+
+#ifdef SJA1000_PELICAN_MODE /* BasicCAN mode doesn't support Arbitration Lost Interrupt */
if (isrc & IRQ_ALI) {
/* arbitration lost interrupt */
dev_dbg(ND2D(dev), "arbitration lost interrupt\n");
@@ -468,11 +566,18 @@
cf->can_id |= CAN_ERR_LOSTARB;
cf->data[0] = alc & 0x1f;
}
+#endif
if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
state == CAN_STATE_ERROR_PASSIVE)) {
+#ifdef SJA1000_PELICAN_MODE
uint8_t rxerr = priv->read_reg(priv, REG_RXERR);
uint8_t txerr = priv->read_reg(priv, REG_TXERR);
+#else
+ uint8_t rxerr = 0;
+ uint8_t txerr = 0;
+#endif
+
cf->can_id |= CAN_ERR_CRTL;
if (state == CAN_STATE_ERROR_WARNING) {
priv->can.can_stats.error_warning++;
@@ -519,7 +624,11 @@
int n = 0;
/* Shared interrupts and IRQ off? */
+#ifdef SJA1000_PELICAN_MODE
if (priv->read_reg(priv, REG_IER) == IRQ_OFF)
+#else
+ if ((priv->read_reg(priv, REG_CR) & IRQ_ALL) == 0)
+#endif
return IRQ_NONE;
if (priv->pre_irq)
@@ -534,7 +643,11 @@
if (isrc & IRQ_TI) {
/* transmission complete interrupt */
- stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xf;
+#ifdef SJA1000_PELICAN_MODE
+ stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xF;
+#else
+ stats->tx_bytes += priv->read_reg(priv, REG_TXB + 1) & 0xF;
+#endif
stats->tx_packets++;
can_get_echo_skb(dev, 0);
netif_wake_queue(dev);
@@ -546,7 +659,11 @@
status = priv->read_reg(priv, REG_SR);
}
}
+#ifdef SJA1000_PELICAN_MODE
if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
+#else
+ if (isrc & (IRQ_DOI | IRQ_EI)) {
+#endif
/* error interrupt */
if (sja1000_err(dev, isrc, status))
break;
diff -ru trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.h trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.h
--- trunk.orig/kernel/2.6/drivers/net/can/sja1000/sja1000.h 2011-11-14 20:49:44.526408577 +0400
+++ trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.h 2011-11-14 20:50:20.813395105 +0400
@@ -50,10 +50,14 @@
#include <socketcan/can/dev.h>
#include <socketcan/can/platform/sja1000.h>
+#define SJA1000_PELICAN_MODE /* BasicCAN accepted if not defined */
+
#define SJA1000_ECHO_SKB_MAX 1 /* the SJA1000 has one TX buffer object */
#define SJA1000_MAX_IRQ 20 /* max. number of interrupts handled in ISR */
+#ifdef SJA1000_PELICAN_MODE
+
/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
#define REG_MOD 0x00
#define REG_CMR 0x01
@@ -76,19 +80,10 @@
#define REG_RMC 0x1D
#define REG_RBSA 0x1E
-/* Common registers - manual section 6.5 */
-#define REG_BTR0 0x06
-#define REG_BTR1 0x07
-#define REG_OCR 0x08
-#define REG_CDR 0x1F
-
#define REG_FI 0x10
#define SFF_BUF 0x13
#define EFF_BUF 0x15
-#define FI_FF 0x80
-#define FI_RTR 0x40
-
#define REG_ID1 0x11
#define REG_ID2 0x12
#define REG_ID3 0x13
@@ -96,6 +91,27 @@
#define CAN_RAM 0x20
+#else /* SJA1000_PELICAN_MODE */
+
+/* SJA1000 registers - manual section 6.3 (Basiccan Mode) */
+#define REG_CR 0x00
+#define REG_CMR 0x01
+#define REG_SR 0x02
+#define REG_IR 0x03
+#define REG_AC 0x04
+#define REG_AM 0x05
+#define REG_TXB 0x0A
+#define REG_RXB 0x14
+
+#endif /* SJA1000_PELICAN_MODE */
+
+/* Common registers - manual section 6.5 */
+#define REG_BTR0 0x06
+#define REG_BTR1 0x07
+#define REG_OCR 0x08
+#define REG_CDR 0x1F
+
+#ifdef SJA1000_PELICAN_MODE
/* mode register */
#define MOD_RM 0x01
#define MOD_LOM 0x02
@@ -137,11 +153,53 @@
/* ECC register */
#define ECC_SEG 0x1F
#define ECC_DIR 0x20
-#define ECC_ERR 6
+#define ECC_ERR 0x06
#define ECC_BIT 0x00
#define ECC_FORM 0x40
#define ECC_STUFF 0x80
-#define ECC_MASK 0xc0
+#define ECC_MASK 0xC0
+
+#define FI_FF 0x80
+#define FI_RTR 0x40
+
+#else /* SJA1000_PELICAN_MODE */
+
+/* control register */
+#define CR_RRQ 0x01
+#define CR_RIE 0x02
+#define CR_TIE 0x04
+#define CR_EIE 0x08
+#define CR_OIE 0x10
+#define IRQ_OFF CR_RRQ
+#define IRQ_ALL (CR_RIE | CR_TIE | CR_EIE | CR_OIE)
+
+/* command register */
+#define CMD_TR 0x01
+#define CMD_AT 0x02
+#define CMD_RRB 0x04
+#define CMD_CDO 0x08
+#define CMD_GTS 0x10
+
+/* status register */
+#define SR_RBS 0x01
+#define SR_DOS 0x02
+#define SR_TBS 0x04
+#define SR_TCS 0x08
+#define SR_RS 0x10
+#define SR_TS 0x20
+#define SR_ES 0x40
+#define SR_BS 0x80
+
+/* interrupt sources */
+#define IRQ_RI 0x01
+#define IRQ_TI 0x02
+#define IRQ_EI 0x04
+#define IRQ_DOI 0x08
+#define IRQ_WUI 0x10
+
+#define FI_RTR 0x10
+
+#endif /* SJA1000_PELICAN_MODE */
/*
* Flags for sja1000priv.flags
[-- Attachment #3: Type: text/plain, Size: 191 bytes --]
_______________________________________________
Socketcan-users mailing list
Socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-users
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: sja1000 BasicCAN mode
[not found] ` <CAF8b2jLH8CTOU5ZBTdH7yFhhb0=QmP2Y_Lkom80Bxfw0AvjA6g@mail.gmail.com>
@ 2011-11-14 20:02 ` Oliver Hartkopp
0 siblings, 0 replies; 3+ messages in thread
From: Oliver Hartkopp @ 2011-11-14 20:02 UTC (permalink / raw)
To: Yuriy Kiselev; +Cc: linux-can
>
> what's your motivation for the BasicCAN mode support?
>
> BasicCAN is used for current version of protocol in our network.
Hm, are you sure that you are not mixing up the BasicCAN mode of the SJA1000
controller with standard frame format CAN frames??
BasicCAN/FullCAN is usually a misleading and therefore outdated classification
for CAN controllers having different filter and receive message box layouts.
What kind of SJA1000 CAN controller are you using?
- SJA1000
- 82C200
- FPGA implementaion from opencores
- ???
Regards,
Oliver
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-11-14 20:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-14 18:03 sja1000 BasicCAN mode Oliver Hartkopp
[not found] ` <CAF8b2jLH8CTOU5ZBTdH7yFhhb0=QmP2Y_Lkom80Bxfw0AvjA6g@mail.gmail.com>
2011-11-14 20:02 ` Oliver Hartkopp
-- strict thread matches above, loose matches on Subject: below --
2011-11-14 17:08 Yuriy Kiselev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).