/**
* \file
*
* \brief megaAVR STK600 AVR libc setbaud Example
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/**
* \mainpage
* \section board STK600 development board
* \section intro Introduction
* This example demonstrates how to use the avr libc utility setbaud to find
* the correct settings for the UART baudrate registers.
*
* \section files Files:
* - mega_setbaud_example.c: megaAVR STK600 setbaud example application
*
* \section exampledescription Brief description of the example application
* This application will set up the UART according to the settings in the
* conf_uart.h file, baudrate is calculated using the avr libc setbaud utility.
* When initialization of the UART is done the application sends the letter 'A'
* on the UART and expect to receive the same letter, hence the hardware must
* be set up so that the TX and RX pin is shorted to create a loop back.
*
* The util/setbaud tool is a tool offered by the avr libc library, and is
* a function for compile time calculation of the baudrate register of values.
* In application where run-time baudrate change is not needed this is a tool
* which easily calculates the best baudrate register settings while keeping the
* flash footprint at a minimum.
*
* A common way of using the setbaud tool is:
* \code
// Define the CPU clock frequency, e.g. 1MHz
#define F_CPU 1000000UL
// Define the target baudrate, e.g. 9600bps
#define BAUD 9600
// Set the accepted tolerance, e.g. 2%
#define BAUD_TOL 2
// Load the calculated values into the correct registers
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
//Then we need to take into account that we may need to set the 2X bit in
//the UART control register to achieve the correct baudrate.
#ifdef USE_2X
UCSR0A |= (1 << U2X0);
#endif
// The last thing that needs to be done is to enable output on the TX pin,
// input on the RX pin and enable the RX and TX in the UART itself. In
// addition to setting the correct mode and bit length, parity and stop-bits.
\endcode
*
* \section compinfo Compilation Info
* This software was written for the GNU GCC
* for AVR. \n
* Other compilers may or may not work.
*
* \section contactinfo Contact Information
* For further information, visit
* Atmel.\n
*/
/*
* Support and FAQ: visit Atmel Support
*/
#define _ASSERT_ENABLE_
#include "compiler.h"
#define TIMEOUT 250
// Set the correct BAUD and F_CPU defines before including setbaud.h
#include "conf_clock.h"
#include "conf_uart.h"
#include
/**
* \brief Initialize the uart with correct baud rate settings
*
* This function will initialize the UART baud rate registers with the correct
* values using the AVR libc setbaud utility. In addition set the UART to 8-bit,
* 1 stop and no parity.
*/
static void uart_init(void)
{
#if defined UBRR0H
/* These values are calculated by the setbaud tool based on the values
defined in conf_clock.h and conf_uart.h. The only thing that the application
need to do is to load these values into the correct registers.*/
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#else
#error "Device is not supported by the driver"
#endif
/* Check if the setbaud tool require that the 2x speed bit has to be set in
order to reach the specified baudrate. */
#if USE_2X
UCSR0A |= (1 << U2X0);
#endif
// Enable RX and TX and set up port
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
// Set the TX pin as output
UART_PORT_DDR |= (1 << UART_TX_PIN);
// Set the RX pin as input
UART_PORT_DDR &= ~(1 << UART_RX_PIN);
// 8-bit, 1 stop bit, no parity, asynchronous UART
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00) | (0 << USBS0) |
(0 << UPM01) | (0 << UPM00) | (0 << UMSEL01) |
(0 << UMSEL00);
}
/**
* \brief Function for sending a char over the UART
*
* \param data the data to send over UART
*/
static void uart_putchar(uint8_t data)
{
// Make sure that the UART buffer is empty
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = data;
}
/**
* \brief Function for getting a char from the UART
*
* \note This function is blocking and will expect to receive something
* on the UART.
*
* \retval uint8_t the data received from the UART
* \retval 0 if timeout
*/
static uint8_t uart_getchar(void)
{
uint8_t timeout = TIMEOUT;
// Wait for RX to complete
while ((!(UCSR0A & (1 << RXC0))) && timeout) {
timeout--;
}
if (timeout) {
return UDR0;
} else {
// No data, timeout
return 0;
}
}
/**
* \brief Example application on how to use the libc setbaud utility.
*
* This application shows how to use the avr libc setbaud utility to get the
* correct values for the baud rate registers. It also performs a test where
* it sends a character on the UART and check if the same char is received
* back.
*
* \note This application assumes that the TX and RX pins have been externally
* shorted to create a loop back.
*/
int main(void)
{
// Set up baud rate registers
uart_init();
// Write a set of letters to the UART
uart_putchar('A');
// Check to see if send and receive works.
Assert(uart_getchar() == 'A');
while (true);
}