
#include <stdio.h>
#include <string.h>
#include "lpc_types.h"
#include "lpc_irq_fiq.h"
#include "lpc_arm922t_cp15_driver.h"
#include "lpc313x_chip.h"
#include "ea3141_board.h"
#include "lpc313x_intc_driver.h"
#include "lpc313x_cgu_driver.h"
#include "lpc313x_timer_driver.h"


#define CLOCK_OUT_FRAC_DIV 5


/***********************************************************************
 *
 * Function: c_entry
 *
 * Purpose: Application entry point from the startup code
 *
 * Processing:
 *     See function.
 *
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void c_entry(void)
 {
  CGU_FDIV_SETUP_T   fdiv_cfg;

  /* Disable interrupts in ARM core */
  disable_irq_fiq();

  /* Setup miscellaneous board functions */
  ea3141_board_init();

  /* Set virtual address of MMU table */
  cp15_set_vmmu_addr((void *)ISROM_MMU_TTB_BASE);

  /* Initialize interrupt system */
  int_initialize(0xFFFFFFFF);

  /* Enable IRQ interrupts in the ARM core */
  enable_irq();

  /*
   * By default the main PLL is setup to run at 270 MHz,
   * see ea3141_startup.c -> ea3141_clock_setup.
   *
   * The default values for the clocks are setup in lpc313x_cgu_default.c,
   * variable g_cgu_default_clks. Clock source and fractional dividers are
   * initilized here.
   *
   */


  /* 
   * Set the power control of the CLOCK_OUT to RUN, 
   * disable WAKE_EN and AUTO
   */
  CGU_SB->clk_pcr[CGU_SB_CLOCK_OUT_ID] = CGU_SB_PCR_RUN;
  
  /* select fractional divider */
  CGU_SB->clk_esr[CGU_SB_CLOCK_OUT_ID] = 
    (CGU_SB_ESR_SELECT(CLOCK_OUT_FRAC_DIV) | CGU_SB_ESR_ENABLE); 


  /*
   * Generate ~67 MHz output
   */

  /* set the fractional divider to 1/4 */
  fdiv_cfg.stretch = 1;
  fdiv_cfg.n = 1;
  fdiv_cfg.m = 4;

  cgu_set_subdomain_freq(CGU_SB_CLOCK_OUT_ID, fdiv_cfg);

  timer_wait_ms(TIMER_CNTR0, 10000);

  /*
   * Generate ~60 MHz output
   */

  /* set the fractional divider to 2/9 */
  fdiv_cfg.stretch = 1;
  fdiv_cfg.n = 2;
  fdiv_cfg.m = 9;

  cgu_set_subdomain_freq(CGU_SB_CLOCK_OUT_ID, fdiv_cfg);

  timer_wait_ms(TIMER_CNTR0, 10000);

  /*
   * Change base frequency to use FFAST (12 MHz) and then
   * generate a 6 MHz output
   */ 

  cgu_set_base_freq(CGU_SB_SYS_BASE_ID, CGU_FIN_SELECT_FFAST);

  /* set the fractional divider to 1/2 */
  fdiv_cfg.stretch = 1;
  fdiv_cfg.n = 1;
  fdiv_cfg.m = 2;

  cgu_set_subdomain_freq(CGU_SB_CLOCK_OUT_ID, fdiv_cfg);

  timer_wait_ms(TIMER_CNTR0, 10000);

  /*
   * Generate 100 kHz output
   */

  /* set the fractional divider to 1/120 */
  fdiv_cfg.stretch = 1;
  fdiv_cfg.n = 1;
  fdiv_cfg.m = 120;

  cgu_set_subdomain_freq(CGU_SB_CLOCK_OUT_ID, fdiv_cfg);

  while(1);

}
