Eralt / arduino

Automatically exported from code.google.com/p/arduino
0 stars 0 forks source link

Serial.available() needs cast to make modulo into an AND #56

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
uint8_t HardwareSerial::available(void)
{
  return (RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) %
RX_BUFFER_SIZE;
}

needs to be:

uint8_t HardwareSerial::available(void)
{
  return ((uint8_t)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail))
% RX_BUFFER_SIZE;
}

Original issue reported on code.google.com by gabebear@gmail.com on 15 Jul 2009 at 2:08

GoogleCodeExporter commented 9 years ago
I guess the ring_buffer needs changed as well.

struct ring_buffer {
  unsigned char buffer[RX_BUFFER_SIZE];
  int head;
  int tail;
};

really should be 

struct ring_buffer {
  unsigned char buffer[RX_BUFFER_SIZE];
  uint8_t head;
  uint8_t tail;
};

Original comment by gabebear@gmail.com on 15 Jul 2009 at 2:14

GoogleCodeExporter commented 9 years ago
oops, one more; the store_char() functino in HardwareSerial.cpp needs a cast

inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
  int i = ((uint8_t)(rx_buffer->head + 1)) % RX_BUFFER_SIZE;

  // if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != rx_buffer->tail) {
    rx_buffer->buffer[rx_buffer->head] = c;
    rx_buffer->head = i;
  }
}

Original comment by gabebear@gmail.com on 15 Jul 2009 at 4:11

GoogleCodeExporter commented 9 years ago
Bleck, one more in read()

int HardwareSerial::read(void)
{
  // if the head isn't ahead of the tail, we don't have any characters
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
    _rx_buffer->tail = ((uint8_t)(_rx_buffer->tail + 1)) % RX_BUFFER_SIZE;
    return c;
  }
}

Original comment by gabebear@gmail.com on 15 Jul 2009 at 4:16

GoogleCodeExporter commented 9 years ago
Can you attach a patch?  (Against the code in the processing-5503 branch.)

Original comment by dmel...@gmail.com on 15 Jul 2009 at 6:25

GoogleCodeExporter commented 9 years ago
After looking through everything. Only available() really had the issue after
changing the definition of "struct ring_buffer".

To completely get rid of modulus/division, you need to inline begin(). Inlining
begin() allows all the baud rate calculations to be done at compile-time, which 
is a
HUGE win.

This patch
  - removes modulus from available()
  - changes the definition of "struct ring_buffer" so other functions
     don't need change to be fixed.
  - moves begin() to an inline function to remove modulus
      (unless you don't use a constant to set baud-rate)

Original comment by gabebear@gmail.com on 16 Jul 2009 at 8:02

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I checked out "svn/branches/processing-5503/hardware/cores/arduino" to 
"arduino-5503/"

So you will probably need to change all instances of "arduino-5503" to whatever 
you
check that directory out to for the last patch, here is one with references 
back to
the http server... don't know if your svn client works with that or not

made with:
svn diff
--old=http://arduino.googlecode.com/svn/branches/processing-5503/hardware/cores/
ardui
--new=arduino-5503/ > a.diff

Original comment by gabebear@gmail.com on 16 Jul 2009 at 8:18

Attachments:

GoogleCodeExporter commented 9 years ago
This seems to be fixed in current versions (1.0 and later, at least.)
At least, there is no longer a division call.

Original comment by wes...@gmail.com on 30 Aug 2012 at 4:25