#include<defBF548.h>


#define SystemCLK	 100000		//Value in KHz
#define VCO_CoreCLK  1			//Value of VCO/CCLK - value can be 1, 2, 4, 8
#define VCO			 500000		//Value in KHz
#define CLKin		 25000

//write data in location 0xFF900060 for the Host to read data.
//For Host write operations, look for data in location 0xFF900060
.section program;

.global _main;

_main:
	
	CALL ConfigurePLL;
	CALL SetUpPortMuxing;
	CALL SetUpInterrupts;
	CALL SetupandEnableHostPort;
	
	loop_here:
	JUMP loop_here;
	
_main.END:

ConfigurePLL:
	P0.H = hi(SIC_IWR0);
	P0.L = lo(SIC_IWR0);
	R0 = 0x1;
	[P0] = R0;
	
	P0.H = hi(PLL_CTL);
	P0.L = lo(PLL_CTL);
	R0.L = SET_MSEL(VCO / CLKin);
	W[P0] = R0.L;
		
	ssync;
	idle;
	
	P0.H = hi(PLL_DIV);
	P0.L = lo(PLL_DIV);
	R0.L = SET_SSEL(VCO / SystemCLK) | ((VCO_CoreCLK)&0x30);
	W[P0] = R0.L;
	ssync;
	
	RTS;
ConfigurePLL.END:
	
SetUpPortMuxing:
	P0.H = hi(PORTD_FER);
	P0.L = lo(PORTD_FER);
	R0.L = 0xFFFF;
	W[P0] = R0.L;
	
	P0.H = hi(PORTD_MUX);
	P0.L = lo(PORTD_MUX);
	R0.L = 0x5555;
	R0.H = 0x5555;
	[P0] = R0;
	
	P0.H = hi(PORTG_FER);
	P0.L = lo(PORTG_FER);
	R0.L = 0xE0;
	W[P0] = R0.L;
	
	P0.H = hi(PORTG_MUX);
	P0.L = lo(PORTG_MUX);
	R0.L = 0x5400;
	R0.H = 0;
	[P0] = R0;
	
	P0.H = hi(PORTH_FER);
	P0.L = lo(PORTH_FER);
	R0.L = 0x18;
	W[P0] = R0.L;
	
	P0.H = hi(PORTH_MUX);
	P0.L = lo(PORTH_MUX);
	R0 = 0;
	[P0] = R0;
	
	RTS;
	
SetUpPortMuxing.END:

SetUpInterrupts:
	P0.H = hi(IMASK);
	P0.L = lo(IMASK);
	R0 = EVT_IVG9;
	[P0] = R0;
	
	P0.H = hi(EVT9);
	P0.L = lo(EVT9);
	P1.H = hi(HostDMA);
	P1.L = lo(HostDMA);
	[P0] = P1;
	
	P0.H = hi(SIC_IMASK1);
	P0.L = lo(SIC_IMASK1);
	R0 = [P0];
	R1 = 0x40;
	R0 = R0 | R1;
	[P0] = R0;
	
	RTS;
SetUpInterrupts.END:

SetupandEnableHostPort:
	P0.H = hi(HOST_CONTROL);
	P0.L = lo(HOST_CONTROL);
	R0.L = EHR | EHW | 0x4 | 0x1;	//Enable Host Reads, Enable Host Writes, Data Size = 16, Host Port Enable
	W[P0] = R0.L;
	
	RTS;
SetupandEnableHostPort.END:

HostDMA:
	P0.H = hi(DMA14_IRQ_STATUS);
	P0.L = lo(DMA14_IRQ_STATUS);
	R0.L = W[P0];
	R0.H = 0;
	R1 = 1;
	R0 = R0 | R1;
	W[P0] = R0;
	ssync;
	
	P0.H = hi(HOST_STATUS);
	P0.L = lo(HOST_STATUS);
	R0 = 0x8;
	W[P0] = R0.L;
	
	RTI;
HostDMA.END:
