// Copyright (c) 2001-20045 Rowley Associates Limited.
//
// This file may be distributed under the terms of the License Agreement
// provided with this software.
//
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
//
//                    Freescale MC9328MXL - UART Example
//
// Description
// -----------
// This example demonstrates configuring and writing to a UART. It also 
// demonstrates how to get printf output over the UART by implementing 
// __putchar.
//
// To see output:
//   - Connect serial cable from UART1 connector on your target board to your
//     host computer.
//   - Open CrossStudio's "Terminal Emulator Window". Configure it to 9600 baud, 
//     8 data bits, no parity, 1 stop bits. Click "Connect" to start the
//     terminal emulator window.
//
////////////////////////////////////////////////////////////////////////////////

#include <targets/MC9328MXL.h>

#define PERCLK1_FREQUENCY 96000000
#define UART_CLOCK_FREQUENCY (PERCLK1_FREQUENCY / 6)

static void
UARTInitialize(unsigned int baud)
{
  GPIO_GIUS_C &= ~0x00001E00; /* PC9/UART1_CTS, PC10/UART1_RTS, PC11/UART1_TXD, PC12/UART1_RXD used for multiplex function */
  GPIO_GPR_C &= ~0x00001E00; /* PC9/UART1_CTS, PC10/UART1_RTS, PC11/UART1_TXD, PC12/UART1_RXD used for primary pin function */

  UART1_CR1 &= ~0x00000001; /* Disable UART */

  UART1_CR2 = 0x00000020; /* 8 bit, 1 stop bit, no parity*/
  UART1_CR2 |=  0x000004000; /* Ignore RTS */
  UART1_CR2 |= 0x00001000; /* Active CTS*/

  UART1_CR3 &= ~0x0000000C; /* 25Mhz and 30Mhz reference clock not used */
  UART1_CR4 |= 0x00000040; /* 16Mhz reference clock used */

  UART1_FCR = 0x00000801; /* Divide input clock by 6 */

  UART1_BIR = (baud * 16 / (UART_CLOCK_FREQUENCY / 10000)) - 1;
  UART1_BMR = 9999;

  UART1_CR1 |=  0x00000005; /* Enable UART */
  UART1_CR2 |=  0x00000006; /* Enable TX and RX */
}

static void
UARTWriteChar(unsigned char ch)
{
  while (!(UART1_SR1 & 0x2000));
  UART1_TX0D = ch;
}

static unsigned char
UARTReadChar(void)
{
  while ((UART1_SR1 & 0x200) == 0);
  return UART1_RX0D;
}

static int
UARTReadAvailable(void)
{
  return UART1_SR1 & 0x200;
}

void 
__putchar(int ch)
{
  if (ch == '\n')
    UARTWriteChar('\r');
  UARTWriteChar(ch);
}

int
main(void)
{
  int i;
  UARTInitialize(9600);
  for (i = 0; ; ++i)
    {
      printf("Hello World (%d)\n", i);
      if (UARTReadAvailable())
        {
          char ch = UARTReadChar();
          if (ch == 'q' || ch == 'Q')
            break;
          printf("Key \'%c\' pressed\n", ch);
        }
    }
  printf("Quit\n");
  return 0;
}

