#include <windows.h>
#include <bsp.h>
#include <dbgserial.h>



#define rCLK_IP3       (*(volatile unsigned *)(BASE_REG_PA_CMU_CLK+0x46C))

#define rGPA1CON       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0x20))
#define rGPA1DAT       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0x24))
#define rGPA1PUD       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0x28))

#define TEST_ZP
#ifdef TEST_ZP

// added by terry 20120614 for test
#define rGPJ0CON       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0x240))
#define rGPJ0DAT       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0x244))
#define rGPJ0PUD       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0x248))

#else
#define rGPH2CON       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0xC40))
#define rGPH2DAT       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0xC44))
#define rGPH2PUD       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0xC48))


#endif

// added by terry 20120614 for test

#define rGPH0CON       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0xC00))
#define rGPH0DAT       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0xC04))
#define rGPH0PUD       (*(volatile unsigned *)(BASE_REG_PA_GPIO+0xC08))


#define rULCON3         (*(volatile unsigned *)(BASE_REG_PA_UART3+0x00))
#define rUCON3          (*(volatile unsigned *)(BASE_REG_PA_UART3+0x04))
#define rUFCON3         (*(volatile unsigned *)(BASE_REG_PA_UART3+0x08))
#define rUTRSTAT3       (*(volatile unsigned *)(BASE_REG_PA_UART3+0x10))
#define rUTXH3          (*(volatile unsigned *)(BASE_REG_PA_UART3+0x20))
#define rUBRDIV3        (*(volatile unsigned *)(BASE_REG_PA_UART3+0x28))
#define rUDIVSLOT3      (*(volatile unsigned *)(BASE_REG_PA_UART3+0x2C))
#define WrUTXH3(ch)     (*(volatile unsigned char *)(BASE_REG_PA_UART3+0x20))=(unsigned char)(ch)	


void POWER_LOCK_GPH00_HIGH(void)
{
    rGPH0CON = (rGPH0CON & ~(0xf<<0)) | (0x1<<0);   // GPH0[0] : Output
    rGPH0PUD = rGPH0PUD & ~(0x3<<0);     
    rGPH0DAT = (rGPH0DAT |(0x1<<0));
}


void Port_Init(void)
{
#ifdef TEST_ZP

	// GPJ01[5:3] for LED
	//
	rGPJ0CON = (rGPJ0CON & ~(0xffff<<12)) | (0x1111<<12);	// GPJ0[5:3] : Output
	rGPJ0PUD = rGPJ0PUD & ~(0xff<<6);	
#else
    // GPH1[7:4] for LED
    //
    rGPH2CON = (rGPH2CON & ~(0xffff<<16)) | (0x1111<<16);   // GPH2[7:4] : Output
    rGPH2PUD = rGPH2PUD & ~(0xff<<8);                       // GPH2[7:4] : Disables Pull-up/down
					// GPJ0[5:3] : Disables Pull-up/down
#endif	

//POWER_LOCK_GPH00_HIGH();


}

#ifdef TEST_ZP

void Led_Display(int data)
{
    UINT8 temp = 0;
    // Active is low.(LED On)
    // GPJ0_5   GPJ0_4  GPJ0_3  
    // nLED_3   nLED_2  nLED_1  nLED_4
    //

    temp = ((data & 0x1)<<3)|(((data & (0x2))>>1)<<2)|(((data & (0x4))>>2)<<1)|(((data & (0x8))>>3)<<0);

	rGPJ0DAT = (rGPJ0DAT & ~(0x7<<3)) |((temp & 0x7<<3)) ;  
}


#else

void Led_Display(int data)
{
    UINT8 temp = 0;
    // Active is low.(LED On)
    // GPH2_4   GPH2_5  GPH2_6  GPH2_7
    // nLED_6   nLED_7  nLED_8  nLED_9
    //

    temp = ((data & 0x1)<<3)|(((data & (0x2))>>1)<<2)|(((data & (0x4))>>2)<<1)|(((data & (0x8))>>3)<<0);
    rGPH2DAT = (rGPH2DAT & ~(0xf<<4)) | ((temp & 0xf)<<4);
	
}
#endif




static void Delay(void)
{
    volatile int i;

    for(i=0 ; i < 1000 ; i++)
    {
    }
}

const UINT32 aSlotTable[16] =
{
    0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4a52, 0x54aa,
    0x5555, 0xd555, 0xd5d5, 0xddd5, 0xdddd, 0xdfdd, 0xdfdf, 0xffdf
};

void Uart_Init(void)
{
    UINT32 DivSlot;
    float Div;

    rCLK_IP3 |= (1<<BP_CLK_IP_UART3);
    // V210 Eboot uses UART 3.

    // UART I/O port initialize
    rGPA1CON = (rGPA1CON & ~(0xff<<8)) | (0x22<<8);
    rGPA1PUD = (rGPA1PUD & ~(0xf<<4)) | (0x1<<4);   // RXD3: Pull-down, TXD3: pull up/down disable

    // Initialize UART Ch3
    Div = (float)((float)PCLKPSYS/(16.0*(float)DEFAULT_DEBUG_BAUDRATE)) - 1;
    rUFCON3 = DEBUG_UART_UFCON;
    rULCON3 = DEBUG_UART_ULCON;
    rUCON3 = DEBUG_UART_UCON;
    rUBRDIV3 = (UINT32)Div;

    DivSlot = (UINT32)(((Div-(int)Div)*16)+0.5);
    rUDIVSLOT3 = aSlotTable[DivSlot];

}

void Uart_SendByte(int data)
{
    if(data=='\n')
    {
        while(!(rUTRSTAT3 & 0x2));
        Delay();                 //because the slow response of hyper_terminal
        WrUTXH3('\r');
    }

    while(!(rUTRSTAT3 & 0x2));   //Wait until THR is empty.
    Delay();
    WrUTXH3(data);
}

void Uart_SendString(char *pt)
{
    while(*pt)
        Uart_SendByte(*pt++);
}

void Uart_SendDWORD(DWORD d, BOOL cr)
{
/*
    Uart_SendString("0x");
    Uart_SendString(hex2char((d & 0xf0000000) >> 28));
    Uart_SendString(hex2char((d & 0x0f000000) >> 24));
    Uart_SendString(hex2char((d & 0x00f00000) >> 20));
    Uart_SendString(hex2char((d & 0x000f0000) >> 16));
    Uart_SendString(hex2char((d & 0x0000f000) >> 12));
    Uart_SendString(hex2char((d & 0x00000f00) >> 8));
    Uart_SendString(hex2char((d & 0x000000f0) >> 4));
    Uart_SendString(hex2char((d & 0x0000000f) >> 0));
    if (cr)
        Uart_SendString("\n");
*/        
}

void Uart_SendBYTE(BYTE d, BOOL cr)
{
/*
    //Uart_SendString("0x");
    Uart_SendString(hex2char((d & 0x000000f0) >> 4));
    Uart_SendString(hex2char((d & 0x0000000f) >> 0));
    Uart_SendString(" ");
    if (cr)
        Uart_SendString("\n");
*/        
}
/*
char *hex2char(unsigned int val)
{
    static char str[2];

    str[1]='\0';

    if(val<=9)
        str[0]='0'+val;
    else
        str[0]=('a'+val-10);

    return str;
}

void CDataAbortHandler(DWORD r0, DWORD r1, DWORD r2, DWORD r3)
{
    Uart_SendString(hex2char(r0));
    Uart_SendString(hex2char(r1));
    Uart_SendString(hex2char(r2));
    Uart_SendString(hex2char(r3));
}
*/
