#include "platform.h"
#include "uart.h"
#include "gpio.h"
#include "watchdog.h"
#include "timer.h"
#include "interrupt.h"
#include "ks8695px.h"

void SetupTimersEnableInterrupts(void)
{
	Interrupt::Initialize();
	Interrupt::SetTimersInterruptPriority(Level_14_Priority, LowestPriority);
	Interrupt::Enable(Timer1);
	Timer::Configure(500000, 10);
	Timer::Enable();
	Interrupt::EnableIRQ();	
}

int main( void)
{
	uint32_t i = 0x20;
	
    CPU::InitializeChipSelectZero(
         External_IO_Bank_0_BaseAddress, 
         External_IO_Bank_0_Size,
         HALFWORD,                      // Bus Width
         SEVEN,                         // Clocks OE or WE is asserted
         ONE,                           // Clocks address is held after CS negates
         ONE,                           // Clocks address is valid before CS asserts
         ONE);                          // Clocks address is valid before OE or WE assert

    CPU::InitializeChipSelectOne(
         External_IO_Bank_1_BaseAddress, 
         External_IO_Bank_1_Size,
         HALFWORD,                      // Bus Width
         SEVEN,                         // Clocks OE or WE is asserted
         ONE,                           // Clocks address is held after CS negates
         ONE,                           // Clocks address is valid before CS asserts
         ONE);                          // Clocks address is valid before OE or WE assert

    CPU::InitializeChipSelectTwo(
         External_IO_Bank_2_BaseAddress, 
         External_IO_Bank_2_Size,
         WORD,                          // Bus Width
         SEVEN,                         // Clocks OE or WE is asserted
         TWO,                           // Clocks address is held after CS negates
         TWO,                           // Clocks address is valid before CS asserts
         TWO);                          // Clocks address is valid before OE or WE assert
         
#if 0
	Pins::ConfigureAsOutput(GPIO_15);	
	
    for (;;) {
		Pins::WriteAllPins(0);
		// for (int i = 0; i < 100000; i++) ;
		Pins::WriteAllPins(0x8000);
		//for (int i = 0; i < 100000; i++) ;
    }
#endif

	CPU::SetSystemClockSpeed(MHz_166);
	CPU::EnableICache();
	Watchdog::Initialize();
	//Watchdog::DrugEmDanno(15);
	PolledUart::Initialize();
	Pins::ConfigureAsOutput(GPIO_15);
	SetupTimersEnableInterrupts();
	for (;;) {
		PolledUart::PutString("Hello from the BIOSA CPU board ");
		PolledUart::PutCharacter(i);
		PolledUart::PutString("\n");
		i = (i == 0x80) ? 0x20 : (i + 1);
	}
	PolledUart::PutString("That's all folks\n");
	//Wait for the last few characters to dribble out of the UART
	Timer::PolledWait(100000);
	CPU::Reset();
	return 0;
}
