1 /* Copyright (c) 2007 Cliff Lawson 2 Copyright (c) 2007 Carlos Lamas 3 All rights reserved. 4 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions are met: 7 8 * Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 10 11 * Redistributions in binary form must reproduce the above copyright 12 notice, this list of conditions and the following disclaimer in 13 the documentation and/or other materials provided with the 14 distribution. 15 16 * Neither the name of the copyright holders nor the names of 17 contributors may be used to endorse or promote products derived 18 from this software without specific prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 POSSIBILITY OF SUCH DAMAGE. */ 31 32 /* $Id: setbaud.h 2424 2014-04-29 13:08:15Z pitchumani $ */ 33 34 /** 35 \file 36 */ 37 38 /** 39 \defgroup util_setbaud <util/setbaud.h>: Helper macros for baud rate calculations 40 \code 41 #define F_CPU 11059200 42 #define BAUD 38400 43 #include <util/setbaud.h> 44 \endcode 45 46 This header file requires that on entry values are already defined 47 for F_CPU and BAUD. In addition, the macro BAUD_TOL will define 48 the baud rate tolerance (in percent) that is acceptable during 49 the calculations. The value of BAUD_TOL will default to 2 %. 50 51 This header file defines macros suitable to setup the UART baud 52 rate prescaler registers of an AVR. All calculations are done 53 using the C preprocessor. Including this header file causes no 54 other side effects so it is possible to include this file more than 55 once (supposedly, with different values for the BAUD parameter), 56 possibly even within the same function. 57 58 Assuming that the requested BAUD is valid for the given F_CPU then 59 the macro UBRR_VALUE is set to the required prescaler value. Two 60 additional macros are provided for the low and high bytes of the 61 prescaler, respectively: UBRRL_VALUE is set to the lower byte of 62 the UBRR_VALUE and UBRRH_VALUE is set to the upper byte. An 63 additional macro USE_2X will be defined. Its value is set to 1 if 64 the desired BAUD rate within the given tolerance could only be 65 achieved by setting the U2X bit in the UART configuration. It will 66 be defined to 0 if U2X is not needed. 67 68 Example usage: 69 70 \code 71 #include <avr/io.h> 72 73 #define F_CPU 4000000 74 75 static void 76 uart_9600(void) 77 { 78 #define BAUD 9600 79 #include <util/setbaud.h> 80 UBRRH = UBRRH_VALUE; 81 UBRRL = UBRRL_VALUE; 82 #if USE_2X 83 UCSRA |= (1 << U2X); 84 #else 85 UCSRA &= ~(1 << U2X); 86 #endif 87 } 88 89 static void 90 uart_38400(void) 91 { 92 #undef BAUD // avoid compiler warning 93 #define BAUD 38400 94 #include <util/setbaud.h> 95 UBRRH = UBRRH_VALUE; 96 UBRRL = UBRRL_VALUE; 97 #if USE_2X 98 UCSRA |= (1 << U2X); 99 #else 100 UCSRA &= ~(1 << U2X); 101 #endif 102 } 103 \endcode 104 105 In this example, two functions are defined to setup the UART 106 to run at 9600 Bd, and 38400 Bd, respectively. Using a CPU 107 clock of 4 MHz, 9600 Bd can be achieved with an acceptable 108 tolerance without setting U2X (prescaler 25), while 38400 Bd 109 require U2X to be set (prescaler 12). 110 */ 111 112 #ifndef F_CPU 113 # error "setbaud.h requires F_CPU to be defined" 114 #endif 115 116 #ifndef BAUD 117 # error "setbaud.h requires BAUD to be defined" 118 #endif 119 120 #if !(F_CPU) 121 # error "F_CPU must be a constant value" 122 #endif 123 124 #if !(BAUD) 125 # error "BAUD must be a constant value" 126 #endif 127 128 #if defined(__DOXYGEN__) 129 /** 130 \def BAUD_TOL 131 \ingroup util_setbaud 132 133 Input and output macro for <util/setbaud.h> 134 135 Define the acceptable baud rate tolerance in percent. If not set 136 on entry, it will be set to its default value of 2. 137 */ 138 #define BAUD_TOL 2 139 140 /** 141 \def UBRR_VALUE 142 \ingroup util_setbaud 143 144 Output macro from <util/setbaud.h> 145 146 Contains the calculated baud rate prescaler value for the UBRR 147 register. 148 */ 149 #define UBRR_VALUE 150 151 /** 152 \def UBRRL_VALUE 153 \ingroup util_setbaud 154 155 Output macro from <util/setbaud.h> 156 157 Contains the lower byte of the calculated prescaler value 158 (UBRR_VALUE). 159 */ 160 #define UBRRL_VALUE 161 162 /** 163 \def UBRRH_VALUE 164 \ingroup util_setbaud 165 166 Output macro from <util/setbaud.h> 167 168 Contains the upper byte of the calculated prescaler value 169 (UBRR_VALUE). 170 */ 171 #define UBRRH_VALUE 172 173 /** 174 \def USE_2X 175 \ingroup util_setbaud 176 177 Output macro from <util/setbaud.h> 178 179 Contains the value 1 if the desired baud rate tolerance could only 180 be achieved by setting the U2X bit in the UART configuration. 181 Contains 0 otherwise. 182 */ 183 #define USE_2X 0 184 185 #else /* !__DOXYGEN__ */ 186 187 #undef USE_2X 188 189 /* Baud rate tolerance is 2 % unless previously defined */ 190 #ifndef BAUD_TOL 191 # define BAUD_TOL 2 192 #endif 193 194 #ifdef __ASSEMBLER__ 195 #define UBRR_VALUE (((F_CPU) + 8 * (BAUD)) / (16 * (BAUD)) -1) 196 #else 197 #define UBRR_VALUE (((F_CPU) + 8UL * (BAUD)) / (16UL * (BAUD)) -1UL) 198 #endif 199 200 #if 100 * (F_CPU) > \ 201 (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) + (BAUD) * (BAUD_TOL)) 202 # define USE_2X 1 203 #elif 100 * (F_CPU) < \ 204 (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL)) 205 # define USE_2X 1 206 #else 207 # define USE_2X 0 208 #endif 209 210 #if USE_2X 211 /* U2X required, recalculate */ 212 #undef UBRR_VALUE 213 214 #ifdef __ASSEMBLER__ 215 #define UBRR_VALUE (((F_CPU) + 4 * (BAUD)) / (8 * (BAUD)) -1) 216 #else 217 #define UBRR_VALUE (((F_CPU) + 4UL * (BAUD)) / (8UL * (BAUD)) -1UL) 218 #endif 219 220 #if 100 * (F_CPU) > \ 221 (8 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) + (BAUD) * (BAUD_TOL)) 222 # warning "Baud rate achieved is higher than allowed" 223 #endif 224 225 #if 100 * (F_CPU) < \ 226 (8 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL)) 227 # warning "Baud rate achieved is lower than allowed" 228 #endif 229 230 #endif /* USE_U2X */ 231 232 #ifdef UBRR_VALUE 233 /* Check for overflow */ 234 # if UBRR_VALUE >= (1 << 12) 235 # warning "UBRR value overflow" 236 # endif 237 238 # define UBRRL_VALUE (UBRR_VALUE & 0xff) 239 # define UBRRH_VALUE (UBRR_VALUE >> 8) 240 #endif 241 242 #endif /* __DOXYGEN__ */ 243 /* end of util/setbaud.h */ 244