From: Benoit <benoit@pouic.eu>
To: linux-can@vger.kernel.org
Subject: mcp251x.c : patch to avoid repeated frame bug
Date: Mon, 27 Aug 2012 15:02:45 +0200 [thread overview]
Message-ID: <503B6FF5.6000800@pouic.eu> (raw)
Hello,
The MCP2515 has a silicon bug causing repeated frame transmission, see
section 5 of MCP2515 Rev. B Silicon Errata Revision G (March 2007).
Basically, setting TXBnCTRL.TXREQ in either SPI mode (00 or 11) will
eventually cause the bug. The workaround proposed by Microchip is to use
mode 00 and send an RTS command on the SPI bus to initiate the
transmission. Accordingly, I have modified the transmission routine as
follows in file mcp251x.c:
--- drivers/net/can/mcp251x.c-original 2012-08-26 15:00:28.000000000 +0200
+++ drivers/net/can/mcp251x.c 2012-08-26 20:42:58.000000000 +0200
@@ -83,6 +83,10 @@
#define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n))
#define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94)
#define INSTRUCTION_RESET 0xC0
+#define RTS_TXB0 0x01
+#define RTS_TXB1 0x02
+#define RTS_TXB2 0x04
+#define INSTRUCTION_RTS(txb) (0x80 | ((txb) & 0x07))
/* MPC251x registers */
#define CANSTAT 0x0e
@@ -394,9 +398,20 @@
}
}
+
+/*
+ * CAN frame is now sent using instruction RTS over SPI to work around
+ * repeated frame problem as per MCP2515 Rev B. Silicon Errata revision G
+ * (March 2007) about repeated frames (see section 5 of document).
+ * Note that repeated frames can still occur if using SPI mode 11. It seems
+ * however that spi mode is forcibly set to 0, so it looks safe.
+ *
+ */
static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
int tx_buf_idx)
{
+ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
+ int ret;
u32 sid, eid, exide, rtr;
u8 buf[SPI_TRANSFER_BUF_LEN];
@@ -418,7 +433,12 @@
buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;
memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);
mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
- mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ);
+
+ priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx);
+ ret = spi_write(spi, priv->spi_tx_buf, 1);
+ if (ret) {
+ dev_err(&spi->dev, "RTS failed: ret = %d\n", ret);
+ }
}
static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
Would it be possible to integrate this patch into mainstream mcp251x.c?
Kind Regards,
Benoît.
next reply other threads:[~2012-08-27 13:12 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-27 13:02 Benoit [this message]
2012-09-03 12:11 ` mcp251x.c : patch to avoid repeated frame bug Marc Kleine-Budde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=503B6FF5.6000800@pouic.eu \
--to=benoit@pouic.eu \
--cc=linux-can@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.