/* setbaud.h - HCS12 SCI baud rate value calculator.
 * Copyright 2008 Colin D. Bennett <colin@gibibit.com>.
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * This utility header calculates the proper value of the SCIBR
 * register for the HCS12 CPU's serial communication interface (SCI) module.
 *
 * You must define the following two preprocessor macros before including
 * this header file:
 *  - F_CPU: the SCI module clock rate (same as CPU clock rate), in Hz
 *  - UART_BAUD: the desired UART baud rate
 *
 * After the file has been included, the following macros are defined for 
 * use by the including compilation unit:
 *  - SCIBR_VALUE: the value for the BR register (12-bit value)
 *  - SCIBDL_VALUE: the low byte of SCIBR_VALUE.
 *  - SCIBDH_VALUE: the high byte of SCIBR_VALUE (only lower 4 bits are used).
 *
 * Example of usage:
 *       #define UART_BAUD 9600
 *       #define F_CPU 8000000
 *       #include "hc12/setbaud.h"
 *       SCI0BDH = SCIBDH_VALUE;
 *       SCI0BDL = SCIBDL_VALUE;
 *
 * Note that it is probably better to set the UART_BAUD and F_CPU macros
 * through your build system (Makefile, etc.) and the -DUART_BAUD=9600
 * C compiler options. By so doing, the source code becomes more about
 * defining behavior and allows the configuration details to be extracted
 * to the configuration/build system.
 */

/* Perform some sanity checks to save users from headaches. */

#ifndef UART_BAUD
#  error You must define the UART_BAUD macro to set the baud rate.
#endif

#if !(UART_BAUD >= 300)
#  error UART_BAUD is probably wrong: should be a constant expression, \
	the bit rate in bits/s.
#endif

#ifndef F_CPU
#  error You must define F_CPU as the CPU clock frequency in Hz.
#endif

#if !(F_CPU > 100000UL)
#  error F_CPU is probably wrong: it should be a constant expression, \
	the CPU freqency **in Hz**.
#endif

/* Baud rate register calculations
 * -------------------------------
 *  SCI baud rate = SCI module clock / (16 x BR)
 *   baud = clk / (16 * BR) 
 *   => 16 * BR * baud = clk
 *   => BR = (clk / 16) / baud
 * NOTE: The maximum divider rate is 8191 */

/* Calculate the SCIBR values for the HCS12 SCI module. */
#undef SCIBR_VALUE
#define SCIBR_VALUE ((F_CPU) / 16UL / (UART_BAUD))

#if SCIBR_VALUE > 8192
#  error Invalid HCS12 SCIBR value; must be less than 8192.
#endif
#if SCIBR_VALUE < 1
#  error Invalid HCS12 SCIBR value; must be greater than 1.
#endif

#undef SCIBDL_VALUE
#undef SCIBDH_VALUE
/* Define the value for the baud rate register, low byte. */
#define SCIBDL_VALUE (SCIBR_VALUE & 0xFF)
/* Define the value for the baud rate register, high byte. */
#define SCIBDH_VALUE (SCIBR_VALUE >> 8)

