You probably don't want to wrap the head and tail pointers as you are. I think wrapping the head pointer when the buffer is full is what's causing confusion.
In my code to do stuff like this I firstly calculate the new head pointer (current head + 1, wrap if needed), and if it's the same as the tail, I just return - throw the next data byte away without wrapping the pointer, rather than wrapping and overwriting existing un-read data.
Some (AVR) code for an interrupt driven serial input I have looks like this:
Code:
ISR(USART0_RX_vect)
{
uint8_t c, next ;
c = UDR0 ;
next = RX_BUFFER_MASK & (rxBuffer.head + 1) ;
// Discard characters rather than overflow the buffer
if (next != rxBuffer.tail)
{
rxBuffer.buf [rxBuffer.head] = c ;
rxBuffer.head = next ;
}
}
uint8_t serialGetchar (void)
{
uint8_t c ;
// Busy wait until some data
while (rxBuffer.head == rxBuffer.tail)
;
// ... then get the last character out of the buffer
c = rxBuffer.buf [rxBuffer.tail] ;
rxBuffer.tail = RX_BUFFER_MASK & (rxBuffer.tail + 1) ;
return c ;
}
In this instance the buffer size is a power of 2 so the mask and
& to wrap the pointer works.
Code:
# define RX_BUFFER_SIZE 128
# define RX_BUFFER_MASK (RX_BUFFER_SIZE-1)
I also note that in the expect routine, you don't explicitly set
ret when there is nothing in the buffer. This may also be an issue unless you explicitly set it elsewhere.
-Gordon
_________________
--
Gordon Henderson.
See my
Ruby 6502 and 65816 SBC projects here:
https://projects.drogon.net/ruby/