diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-01-10 22:29:39 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-01-10 22:29:39 +0000 |
commit | 2878c08369c4ac8819e0f6530784f22509bcab92 (patch) | |
tree | 92567fed48fbb8c44552b220ab80d17ec19cfba0 /nuttx/drivers | |
parent | b45972d006d34d588ef0bde2ebffb2de5843b0fa (diff) | |
download | px4-nuttx-2878c08369c4ac8819e0f6530784f22509bcab92.tar.gz px4-nuttx-2878c08369c4ac8819e0f6530784f22509bcab92.tar.bz2 px4-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')
-rw-r--r-- | nuttx/drivers/can.c | 26 |
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); } |