/******************************************************************************
 * FileName:   usart.c
 * Overview:   Implementa funciones para el USART0 en modo Asíncrono
 * Processor:  ATmel AVR con USART0
 * Compiler:   IAR-C y AVR-GCC (WinAVR)
 * Author:     Shawn Johnson. http://www.cursomicros.com.
 *
 * Copyright (C) 2008 - 2012 Shawn Johnson. All rights reserved.
 *
 * License:    Se permiten el uso y la redistribución de este código con 
 *             modificaciones o sin ellas, siempre que se mantengan esta 
 *             licencia y las notas de autor y copyright de arriba.
 *****************************************************************************/

#include "usart.h"

//****************************************************************************
// Inicializa el USART0.
//****************************************************************************
void usart_init(void)
{
    /* Configurar baud rate   */
    UCSR0A |= (1<<U2X0);
    UBRR0 = F_CPU/(8*USART_BAUD)-1;
    
    /* Configurar modo de operación Asíncrono y formato de frame a
     * 8 bits de datos, 1 bit de stop y sin bit de paridad.  */
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
    
    /* Habilitar módulos Receptor y Transmisor  */
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);

#if defined( __GNUC__ )
    /* Asociar las funciones 'putchar' y 'getchar' con las funciones de entrada
    * y salida (como printf, scanf, etc.) de la librería 'stdio' de AVR-GCC */
    fdevopen((int (*)(char, FILE*))putchar, (int (*)(FILE*))getchar);
#endif
}

//****************************************************************************
// Transmite el byte bajo de 'dato' por el USART
//****************************************************************************
int putchar(int dato)
{
    /* Esperar a que haya espacio en el buffer de transmisión */
    while ((UCSR0A & (1<<UDRE0)) == 0 );

    /* Colocar dato en el buffer de transmisión */
    UDR0 = dato;
    return dato;
}

//****************************************************************************
// Recibe un byte de dato del USART
//****************************************************************************
int getchar(void)
{
    /* Esperar a que haya al menos un dato en el buffer de recepción */
    while ((UCSR0A & (1<<RXC0)) == 0 );   
    
    /* Leer y retornar el dato menos reciente del buffer de recepción */   
#if defined ( __GETCHAR_ECHO__ )
    return (putchar(UDR0));
#else
    return UDR0;
#endif
}