// Init.c

#include "defs.h"
#include "config.h"
#include "rprintf.h"

static void systemInit(void)
{
	// --- enable and connect the PLL (Phase Locked Loop) ---
	// a. set multiplier and divider
	PLLCFG = MSEL | (PSEL1val<<PSEL1) | (PSEL0val<<PSEL0);
	// b. enable PLL
	PLLCON = (1<<PLLE);
	// c. feed sequence
	PLLFEED = PLL_FEED1;
	PLLFEED = PLL_FEED2;
	// d. wait for PLL lock (PLOCK bit is set if locked)
	while (!(PLLSTAT & (1<<PLOCK)));
	// e. connect (and enable) PLL
	PLLCON = (1<<PLLE) | (1<<PLLC);
	// f. feed sequence
	PLLFEED = PLL_FEED1;
	PLLFEED = PLL_FEED2;
	
	// --- setup and enable the MAM (Memory Accelerator Module) ---
	// a. start change by turning of the MAM (redundant)
	MAMCR = 0;	
	// b. set MAM-Fetch cycle to 3 cclk as recommended for >40MHz
	MAMTIM = MAM_FETCH;
	// c. enable MAM 
	MAMCR = MAM_MODE;
	
	// --- set VPB speed ---
	VPBDIV = VPBDIV_VAL;
	
	// --- map INT-vector ---
	#if defined(RAM_RUN)
	  MEMMAP = MEMMAP_USER_RAM_MODE;
	#elif defined(ROM_RUN)
	  MEMMAP = MEMMAP_USER_FLASH_MODE;
	#else
	#error RUN_MODE not defined!
	#endif
}

void InitController(void)
{
  systemInit();

  PINSEL0 = F00 |F01 | F02 | F03 | F04 | F05 | F06 |F07;
  PINSEL1 = F16 |F22 | F25 | F27 | F28 | F29 | F30;

  PINSEL2 &= 0xFFFFFFF0;

  IOSET0 = LED1 | LED2;
  IODIR0 = LED1 | LED2 | WP | CS | CSTART | ENVSS | UNUSED0;
  IODIR1 = ALMYbits | 0xFF000000;

  ADCR = Bit(21) | (0 << 17) | (13 << 8);
}

void InitSPI(void)
{
  S0SPCCR = PCLK/2000000;
  S0SPCR = 0x20;	// Master Mode
}

void InitSerial(void)
{
  PINSEL1 |= 0x2002;		// Capture0.0 | Match0.2
  T0PR = T0Prescaler - 1;
  T0EMR = ClearExtMatch2;
  T0TCR = 0x00000001;		// Enable Timer
  T0CCR = 0x02;				// Capture on falling edge, UART startbit
  IODIR0 |= P016;			// As output for TXEN

  PINSEL0 |= 0x00000005;	// Enable RxD0 and TxD0
  U0LCR = 0x83;				// 8 bits, no Parity, 1 Stop bit

#if PCLK==60000000
  U0DLL = 32;				// 115200 Baud Rate @ 60MHz VPB Clock
#elif PCLK==24000000
  U0DLL = 13;				// 115200 Baud Rate @ 24MHz VPB Clock
#else
#error "Undefined CCLK value in convig.h"
#endif

  U0LCR = 0x03;				// DLAB = 0

  rprintf_devopen(putchar0);
}

#ifdef _WDT
void InitWDT(void)
{
  WDTC = WDT_FEED_VALUE;	// once WDEN is set, the WDT will start after feeding
  WDMOD = WDEN | WDRESET;

  WDFEED = 0xAA;
  WDFEED = 0x55;
}
#else
void InitWDT(void){}
#endif
