flysight/flysight — pull request #21 by willglynn (2014-03-23 02:19:31+00:00)
Title: UART receive buffer is too big

Looking at the linker map from #20, I noticed something that piqued my interest. Relevant code snippets:

/** Size of the circular receive buffer, must be power of 2 */
#ifndef UART_RX_BUFFER_SIZE
#define UART_RX_BUFFER_SIZE 512
#endif

static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];

static volatile unsigned char UART_RxHead;
static volatile unsigned char UART_RxTail;

SIGNAL(UART0_RECEIVE_INTERRUPT)
/*************************************************************************
Function: UART Receive Complete interrupt
Purpose: called when the UART has received a character
**************************************************************************/
{
unsigned char tmphead;
...
/* calculate buffer index */
tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
...
/* store new index */
UART_RxHead = tmphead;
/* store received data in buffer */
UART_RxBuf[tmphead] = data;

`UART_RxBuf` is 512 bytes but all the offsets are `unsigned char`s. I double-checked the disassembly just for good measure:

/* calculate buffer index */
tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
2244:	e0 91 d4 06	lds	r30, 0x06D4
2248:	ef 5f	subi	r30, 0xFF	; 255

`tmphead = UART_RxHead - 255` == `tmphead = UART_RxHead + 1` modulo 256.

The second half of the buffer can never get used. This commit shrinks the receive buffer to 256 bytes, which is the current effective size, freeing 256 bytes of RAM for other purposes.