void ring_buffer_read(ring_buffer* ring, uint8_t* buffer, uint16_t size) {
  uint16_t i;
  
  // TODO can be optimized
  for(i = 0; i < size; i++) {
    buffer[i] = ring_buffer_read_byte(ring);
  }
}
/* _____LOCAL FUNCTIONS______________________________________________________ */
static void usart0_interrupt(void)
{
    u8_t data;

    // Read status register
    u32_t csr = AT91C_BASE_US0->US_CSR;

    // See if a receive error was detected
    if(csr & (AT91C_US_RXBRK | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE))
    {
        // Reset status bits
        AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA;
        return;
    }

    // See if a character has been received
    if(csr & AT91C_US_RXRDY)
    {
        // Read character and buffer it
        data = (char)(AT91C_BASE_US0->US_RHR);
        ring_buffer_write_byte(&usart0_rx_ring_buffer, data);
    }

    // See if the transmitter is ready
    if(csr & AT91C_US_TXRDY)
    {
        // See if there is more data to be sent
        if(ring_buffer_read_byte(&usart0_tx_ring_buffer,&data))
        {
            // Clear flag to indicate that transmission is busy
            usart0_tx_finished_flag = FALSE;
            // Buffer data to be transmitted
            AT91C_BASE_US0->US_THR = data;            
        }
        else
        {
            // Disable transmit ready interrupt
            AT91C_BASE_US0->US_IDR = AT91C_US_TXRDY;
            // Enable transmit empty interrupt
            AT91C_BASE_US0->US_IER = AT91C_US_TXEMPTY;
        }
    }

    // See if the transmitter is finished
    if(csr & AT91C_US_TXEMPTY)
    {
        // Set flag to indicate that transmission is finished
        usart0_tx_finished_flag = TRUE;
        // Disable transmit empty interrupt
        AT91C_BASE_US0->US_IDR = AT91C_US_TXEMPTY;
    }
}
bool_t usart0_get_rx_byte(u8_t* data)
{
    return ring_buffer_read_byte(&usart0_rx_ring_buffer,data);
}