summaryrefslogtreecommitdiff
path: root/nuttx/drivers/can.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-01-10 22:29:39 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-01-10 22:29:39 +0000
commit2878c08369c4ac8819e0f6530784f22509bcab92 (patch)
tree92567fed48fbb8c44552b220ab80d17ec19cfba0 /nuttx/drivers/can.c
parentb45972d006d34d588ef0bde2ebffb2de5843b0fa (diff)
downloadnuttx-2878c08369c4ac8819e0f6530784f22509bcab92.tar.gz
nuttx-2878c08369c4ac8819e0f6530784f22509bcab92.tar.bz2
nuttx-2878c08369c4ac8819e0f6530784f22509bcab92.zip
Fix LPC17 CAN driver; TX must be interrupt driven
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4290 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/drivers/can.c')
-rw-r--r--nuttx/drivers/can.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/nuttx/drivers/can.c b/nuttx/drivers/can.c
index 40c179e1c..6928fbd1f 100644
--- a/nuttx/drivers/can.c
+++ b/nuttx/drivers/can.c
@@ -375,9 +375,11 @@ static int can_xmit(FAR struct can_dev_s *dev)
canllvdbg("xmit head: %d tail: %d\n", dev->cd_xmit.cf_head, dev->cd_xmit.cf_tail);
- /* Check if the xmit FIFO is empty */
+ /* Check if the xmit FIFO is not empty and the CAN hardware is ready to accept
+ * more data.
+ */
- if (dev->cd_xmit.cf_head != dev->cd_xmit.cf_tail)
+ if (dev->cd_xmit.cf_head != dev->cd_xmit.cf_tail && dev_txready(dev))
{
/* Send the next message at the head of the FIFO */
@@ -401,7 +403,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, size_t
FAR struct can_dev_s *dev = inode->i_private;
FAR struct can_fifo_s *fifo = &dev->cd_xmit;
FAR struct can_msg_s *msg;
- bool empty = false;
+ bool inactive;
ssize_t nsent = 0;
irqstate_t flags;
int nexttail;
@@ -414,11 +416,12 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, size_t
flags = irqsave();
- /* Check if the TX FIFO was empty when we started. That is a clue that we have
- * to kick off a new TX sequence.
+ /* Check if the TX is inactive when we started. In certain race conditionas, there
+ * may be a pending interrupt to kick things back off, but we will here that there
+ * is not. That the hardware is IDLE and will need to be kick-started.
*/
- empty = (fifo->cf_head == fifo->cf_tail);
+ inactive = dev_txempty(dev);
/* Add the messages to the FIFO. Ignore any trailing messages that are
* shorter than the minimum.
@@ -455,11 +458,12 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, size_t
goto return_with_irqdisabled;
}
- /* If the FIFO was empty when we started, then we will have
- * start the XMIT sequence to clear the FIFO.
+ /* If the TX hardware was inactive when we started, then we will have
+ * start the XMIT sequence generate the TX done interrrupts needed
+ * to clear the FIFO.
*/
- if (empty)
+ if (inactive)
{
can_xmit(dev);
}
@@ -483,7 +487,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, size_t
/* Re-check the FIFO state */
- empty = (fifo->cf_head == fifo->cf_tail);
+ inactive = dev_txempty(dev);
}
/* We get here if there is space at the end of the FIFO. Add the new
@@ -507,7 +511,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, size_t
* we need to kick of the XMIT sequence.
*/
- if (empty)
+ if (inactive)
{
can_xmit(dev);
}