T168_111\core\N32903文件:第41~最后一个文件

wb_adc.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#include "Wblib.h"
#include "W55fa93_adc.h"

// ch_20220316
void ADCReset(void) {
    outp32(REG_ADC_CON, inp32(REG_ADC_CON)    |  (0x01<<16));
    DelayTime(100);
    outp32(REG_ADC_CON, inp32(REG_ADC_CON)    &  ~(0x01<<16));
    DelayTime(100);
}
void ADCNormalMode(void) {
    outp32(REG_ADC_CON, inp32(REG_ADC_CON)    & ~( 0x01<<16));//normal mode
}
VOID ADCEnabled(VOID)
{
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CON_ADC_EN);
}
VOID ADCDisabled(VOID)
{
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) & ~(ADC_CON_ADC_EN));
}
void ADCDeinit(void) {
    sysDisableInterrupt(IRQ_ADC);
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) & ~ADC_CON_ADC_EN);    
    outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) & (~((0x03<<19) | (0x03<<16) | (0x5F<<24))));//UPLL 192/4/2 = 24MHz // ch_20220305
    outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
    outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
    outp32(REG_APBCLK, inp32(REG_APBCLK) & (~ADC_CKE));    
}

void ADCInit(void) {
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) & (~ADC_CON_ADC_EN)); // ch_20220305
    outp32(REG_APBCLK, inp32(REG_APBCLK) & ~ADC_CKE); // ch_20220305
    outp32(REG_APBCLK, inp32(REG_APBCLK) | ADC_CKE);
    outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) & ~((0x03<<19) | (0x03<<16) | (0x5F<<24)));//UPLL 192/4/2 = 24MHz // ch_20220305
    outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) | (0x03<<19) | (0x03<<16) | (0x01<<24));//UPLL 192/4/2 = 24MHz
    outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
    outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
    outp32(REG_ADC_CON, inp32(REG_ADC_CON)    & (~( 0x03 << 14)));//normal mode
    outp32(REG_ADC_DLY, 10/*0x150*/); // ch_20220617 : restored to 10 from 0 cause of CAL not good for some kinds of GAP sensor. // ch_20220616 : changed to 0 from 10.
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CON_ADC_EN);
}

// ch_20220305
void ADCInit4Print(void) {
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) & (~ADC_CON_ADC_EN)); // ch_20220305
    outp32(REG_APBCLK, inp32(REG_APBCLK) & (~ADC_CKE)); // ch_20220305
    outp32(REG_APBCLK, inp32(REG_APBCLK) | ADC_CKE);
    outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) & (~((0x03<<19) | (0x03<<16) | (0x5F<<24))));//UPLL 192/4/2 = 24MHz // ch_20220305    
    outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) | (0x03<<19) | (0x03<<16) | (0x01<<24));//UPLL 192/4/2 = 24MHz
    outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
    outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
    outp32(REG_ADC_CON, inp32(REG_ADC_CON)    & (~( 0x03 << 14)));//normal mode
    //outp32(REG_ADC_DLY, 0x150);
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CON_ADC_EN);

}

// ch_20220305
void ADCInit4Cal(void) {
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) & (~ADC_CON_ADC_EN)); // ch_20220305
    outp32(REG_APBCLK, inp32(REG_APBCLK) & (~ADC_CKE)); // ch_20220305
    outp32(REG_APBCLK, inp32(REG_APBCLK) | ADC_CKE);
    outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) & (~((0x03<<19) | (0x03<<16) | (0x5F<<24))));//UPLL 192/4/2 = 24MHz // ch_20220305    
    outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) | (0x03<<19) | (0x03<<16) | (0x5F<<24));//UPLL 192/4/2 = 24MHz // ch_20220228 : changed to 47 from 1.
    outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
    outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
    outp32(REG_ADC_CON, inp32(REG_ADC_CON)    & (~( 0x03 << 14)));//normal mode
    //outp32(REG_ADC_DLY, 0x150);
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CON_ADC_EN);

}


/**
*    ADCRead
*    channel : 2/3
*/
UINT32 ADCRead(UINT8 channel) {

    outp32(REG_ADC_CON, inp32(REG_ADC_CON) &(~(0x03 << 9))  | (channel << 9));//select channel
    outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CONV);// start convert
    while (!inp32(REG_ADC_CON) & ADC_FINISH);
    return inp32(REG_ADC_XDATA);
}

void ADCTest() {

    UINT32 adc, loop;
    ADCInit();
    while (1) {
        adc = ADCRead(3);
        sysprintf("3:%d\n", adc);
        adc = ADCRead(2);
        sysprintf("2:%d\n", adc);
        for (loop = 0; loop < 40000 * 100; loop ++);

    }
}



wb_aic.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                                                                  *
 * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.                                       *
 *                                                                                                                  *
 ***************************************************************************/
 
/****************************************************************************
* FILENAME
*   wb_aic.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The AIC related functions of Nuvoton ARM9 MCU
*
* HISTORY
*   2008-06-25  Ver 1.0 draft by Min-Nan Cheng
*
* REMARK
*   None
 **************************************************************************/
#include <stdio.h>
#include "wblib.h"
#define WB_MIN_INT_SOURCE  1
#define WB_MAX_INT_SOURCE  31
#define WB_NUM_OF_AICREG   32

/* Global variables */
BOOL volatile _sys_bIsAICInitial = FALSE;
BOOL volatile _sys_bIsHWMode = TRUE;

/* declaration the function prototype */
extern VOID WB_Interrupt_Shell(VOID);

/* SCR and SVR register access function */
#define AIC_REG_OFFSET                            0x4
#define AICRegRead(RegBase, RegNum)                inpw(RegBase+RegNum*AIC_REG_OFFSET)
#define AICRegWrite(RegBase, RegNum, Value)            outpw(RegBase+RegNum*AIC_REG_OFFSET, Value)

/* Interrupt Handler Table */
typedef void (*sys_pvFunPtr)();   /* function pointer */
sys_pvFunPtr sysIrqHandlerTable[] = { 0,                /* 0 */
                                  WB_Interrupt_Shell,    /* 1 */
                                  WB_Interrupt_Shell,    /* 2 */
                                  WB_Interrupt_Shell,    /* 3 */
                                  WB_Interrupt_Shell,    /* 4 */
                                  WB_Interrupt_Shell,    /* 5 */
                                  WB_Interrupt_Shell,    /* 6 */
                                  WB_Interrupt_Shell,    /* 7 */
                                  WB_Interrupt_Shell,    /* 8 */
                                  WB_Interrupt_Shell,    /* 9 */
                                  WB_Interrupt_Shell,    /* 10 */
                                  WB_Interrupt_Shell,    /* 11 */
                                  WB_Interrupt_Shell,    /* 12 */
                                  WB_Interrupt_Shell,    /* 13 */
                                  WB_Interrupt_Shell,    /* 14 */
                                  WB_Interrupt_Shell,    /* 15 */
                                  WB_Interrupt_Shell,    /* 16 */
                                  WB_Interrupt_Shell,    /* 17 */
                                  WB_Interrupt_Shell,    /* 18 */
                                  WB_Interrupt_Shell,    /* 19 */
                                  WB_Interrupt_Shell,    /* 20 */
                                  WB_Interrupt_Shell,    /* 21 */
                                  WB_Interrupt_Shell,    /* 22 */
                                  WB_Interrupt_Shell,    /* 23 */
                                  WB_Interrupt_Shell,    /* 24 */
                                  WB_Interrupt_Shell,    /* 25 */
                                  WB_Interrupt_Shell,    /* 26 */
                                  WB_Interrupt_Shell,    /* 27 */
                                  WB_Interrupt_Shell,    /* 28 */
                                  WB_Interrupt_Shell,    /* 29 */
                                  WB_Interrupt_Shell,    /* 30 */
                                  WB_Interrupt_Shell    /* 31 */
                                };

sys_pvFunPtr sysFiqHandlerTable[] = { 0,
                                  WB_Interrupt_Shell,    /* 1 */
                                  WB_Interrupt_Shell,    /* 2 */
                                  WB_Interrupt_Shell,    /* 3 */
                                  WB_Interrupt_Shell,    /* 4 */
                                  WB_Interrupt_Shell,    /* 5 */
                                  WB_Interrupt_Shell,    /* 6 */
                                  WB_Interrupt_Shell,    /* 7 */
                                  WB_Interrupt_Shell,    /* 8 */
                                  WB_Interrupt_Shell,    /* 9 */
                                  WB_Interrupt_Shell,    /* 10 */
                                  WB_Interrupt_Shell,    /* 11 */
                                  WB_Interrupt_Shell,    /* 12 */
                                  WB_Interrupt_Shell,    /* 13 */
                                  WB_Interrupt_Shell,    /* 14 */
                                  WB_Interrupt_Shell,    /* 15 */
                                  WB_Interrupt_Shell,    /* 16 */
                                  WB_Interrupt_Shell,    /* 17 */
                                  WB_Interrupt_Shell,    /* 18 */
                                  WB_Interrupt_Shell,    /* 19 */
                                  WB_Interrupt_Shell,    /* 20 */
                                  WB_Interrupt_Shell,    /* 21 */
                                  WB_Interrupt_Shell,    /* 22 */
                                  WB_Interrupt_Shell,    /* 23 */
                                  WB_Interrupt_Shell,    /* 24 */
                                  WB_Interrupt_Shell,    /* 25 */
                                  WB_Interrupt_Shell,    /* 26 */
                                  WB_Interrupt_Shell,    /* 27 */
                                  WB_Interrupt_Shell,    /* 28 */
                                  WB_Interrupt_Shell,    /* 29 */
                                  WB_Interrupt_Shell,    /* 30 */
                                  WB_Interrupt_Shell    /* 31 */
                                };

/* Interrupt Handler */
__irq VOID sysIrqHandler()
{
    if (_sys_bIsHWMode)
    {
        UINT32 volatile _mIPER, _mISNR;

        _mIPER = inpw(REG_AIC_IPER) >> 2;
        //outpw(REG_AIC_IPER,0); //For test mode
        
        _mISNR = inpw(REG_AIC_ISNR);
        if (_mISNR != 0)
            if (_mIPER == _mISNR)
                (*sysIrqHandlerTable[_mIPER])();
        outpw(REG_AIC_EOSCR, 1);                    
    }
    else
    {
        UINT32 volatile _mISR, i;

        _mISR = inpw(REG_AIC_ISR);
        for (i=1; i<WB_NUM_OF_AICREG; i++)
            if (_mISR & (1 << i))
                (*sysIrqHandlerTable[i])();
    }
}

__irq VOID sysFiqHandler()
{    
    
    if (_sys_bIsHWMode)
    {
        UINT32 volatile _mIPER, _mISNR;

        _mIPER = inpw(REG_AIC_IPER) >> 2;
        //outpw(REG_AIC_IPER,0); //For test mode
        _mISNR = inpw(REG_AIC_ISNR);
        if (_mISNR != 0)
            if (_mIPER == _mISNR){
                //sysprintf("%d\n", _mIPER);
                (*sysFiqHandlerTable[_mIPER])();
            }
                
        outpw(REG_AIC_EOSCR, 1);    
    }
    else
    {
        UINT32 volatile _mISR, i;

        _mISR = inpw(REG_AIC_ISR);
        for (i=1; i<WB_NUM_OF_AICREG; i++)
            if (_mISR & (1 << i))
                (*sysFiqHandlerTable[i])();
    }
}
VOID WB_Interrupt_Shell()
{

}

VOID sysInitializeAIC()
{
    PVOID _mOldIrqVect, _mOldFiqVect;

    *((unsigned volatile *)0x18) = 0xe59ff018;
    *((unsigned volatile *)0x1C) = 0xe59ff018;   

    _mOldIrqVect = *(PVOID volatile *)0x38;
    *(PVOID volatile *)0x38 = (PVOID volatile)sysIrqHandler;

    _mOldFiqVect = *(PVOID volatile *)0x3C;
    *(PVOID volatile *)0x3C = (PVOID volatile)sysFiqHandler;

    if (sysGetCacheState() == TRUE)
        sysFlushCache(I_CACHE);
}


/* Interrupt library functions */
INT32 sysDisableInterrupt(INT_SOURCE_E eIntNo)
{
    if ((eIntNo > WB_MAX_INT_SOURCE) || (eIntNo < WB_MIN_INT_SOURCE))
          return Fail;

    outpw(REG_AIC_MDCR, (1 << eIntNo));
    return Successful;
}

#if 0
INT32 sysDisableGroupInterrupt(INT_SOURCE_GROUP_E eIntNo)
{
    outpw(REG_AIC_GEN, inpw(REG_AIC_GEN) & ~eIntNo);
    return Successful;
}
#endif

INT32 sysEnableInterrupt(INT_SOURCE_E eIntNo)
{
    if ((eIntNo > WB_MAX_INT_SOURCE) || (eIntNo < WB_MIN_INT_SOURCE))
          return Fail;

//    outpw(REG_AIC_MECR, (1 << eIntNo)); // ch_20220727
    outpw(REG_AIC_MECR, inpw(REG_AIC_MECR)|(1 << eIntNo)); // ch_20220727
    return Successful;
}

#if 0
INT32 sysEnableGroupInterrupt(INT_SOURCE_GROUP_E eIntNo)
{
    outpw(REG_AIC_GEN, inpw(REG_AIC_GEN) | eIntNo);
    return Successful;
}

UINT32 sysGetGroupInterruptStatus()
{
    UINT32 status;

    status = inpw(REG_AIC_GASR);
    return status;
}
#endif

PVOID sysInstallExceptionHandler(INT32 nExceptType, PVOID pvNewHandler)
{
    PVOID _mOldVect;

    switch (nExceptType)
    {
        case WB_SWI:
            _mOldVect = *(PVOID volatile *)0x28;
            *(PVOID volatile *)0x28 = pvNewHandler;
        break;

        case WB_D_ABORT:
            _mOldVect = *(PVOID volatile *)0x30;
            *(PVOID volatile *)0x30 = pvNewHandler;
        break;

        case WB_I_ABORT:
            _mOldVect = *(PVOID volatile *)0x2C;
            *(PVOID volatile *)0x2C = pvNewHandler;
        break;

        case WB_UNDEFINE:
            _mOldVect = *(PVOID volatile *)0x24;
            *(PVOID volatile *)0x24 = pvNewHandler;
        break;

        default:
           ;
    }
    return _mOldVect;
}

PVOID sysInstallFiqHandler(PVOID pvNewISR)
{
    PVOID _mOldVect;

    _mOldVect = *(PVOID volatile *)0x3C;
    *(PVOID volatile *)0x3C = pvNewISR;
    return _mOldVect;
}

PVOID sysInstallIrqHandler(PVOID pvNewISR)
{
    PVOID _mOldVect;

    _mOldVect = *(PVOID volatile *)0x38;
    *(PVOID volatile *)0x38 = pvNewISR;
    return _mOldVect;
}

//OK
PVOID sysInstallISR(INT32 nIntTypeLevel, INT_SOURCE_E eIntNo, PVOID pvNewISR)
{
    PVOID  _mOldVect;
    UINT32 _mRegValue;

    if (!_sys_bIsAICInitial)
    {
        sysInitializeAIC();
        _sys_bIsAICInitial = TRUE;
    }

    _mRegValue = AICRegRead(REG_AIC_SCR1, (eIntNo/4));
    _mRegValue = _mRegValue & ( 0xFFFFFFF8<<((eIntNo%4)*8) | ( (1<<((eIntNo%4)*8))-1 ) );
    _mRegValue = _mRegValue | nIntTypeLevel<<((eIntNo%4)*8);
    AICRegWrite(REG_AIC_SCR1, (eIntNo/4), _mRegValue );

    switch (nIntTypeLevel)
    {
        case FIQ_LEVEL_0:
            _mOldVect = (PVOID) sysFiqHandlerTable[eIntNo];
            sysFiqHandlerTable[eIntNo] = (sys_pvFunPtr)pvNewISR;
        break;

        case IRQ_LEVEL_1:
        case IRQ_LEVEL_2:
        case IRQ_LEVEL_3:
        case IRQ_LEVEL_4:
        case IRQ_LEVEL_5:
        case IRQ_LEVEL_6:
        case IRQ_LEVEL_7:
               _mOldVect = (PVOID) sysIrqHandlerTable[eIntNo];
               sysIrqHandlerTable[eIntNo] = (sys_pvFunPtr)pvNewISR;
        break;

        default:
           ;
    }
    return _mOldVect;    
}
//OK
INT32 sysSetGlobalInterrupt(INT32 nIntState)
{
    switch (nIntState)
    {
        case ENABLE_ALL_INTERRUPTS:
               outpw(REG_AIC_MECR, 0xFFFFFFFF);
        break;

        case DISABLE_ALL_INTERRUPTS:
               outpw(REG_AIC_MDCR, 0xFFFFFFFF);
        break;

        default:
               ;
       }
      return Successful;
}
//OK
INT32 sysSetInterruptPriorityLevel(INT_SOURCE_E eIntNo, UINT32 uIntLevel)
{
    UINT32 _mRegValue;

    if ((eIntNo > WB_MAX_INT_SOURCE) || (eIntNo < WB_MIN_INT_SOURCE))
          return Fail;
    
    _mRegValue = AICRegRead(REG_AIC_SCR1, (eIntNo/4));
    _mRegValue = _mRegValue & ( 0xFFFFFFF8<<((eIntNo%4)*8) | ( (1<<((eIntNo%4)*8))-1 ) );
    _mRegValue = _mRegValue | uIntLevel<<((eIntNo%4)*8);
    AICRegWrite(REG_AIC_SCR1, (eIntNo/4), _mRegValue);

    return Successful;        
}
//OK
/*
typedef enum 
{
    eDRVAIC_LOW_LEVEL, 
    eDRVAIC_HIGH_LEVEL, 
    eDRVAIC_FALLING, 
    eDRVAIC_RISING
}E_DRVAIC_INT_TYPE;
*/
INT32 sysSetInterruptType(INT_SOURCE_E eIntNo, UINT32 uIntSourceType)
{
    UINT32 _mRegValue;

    if ((eIntNo > WB_MAX_INT_SOURCE) || (eIntNo < WB_MIN_INT_SOURCE))
          return Fail;

    _mRegValue = AICRegRead(REG_AIC_SCR1, (eIntNo/4));
    _mRegValue = _mRegValue & ( 0xFFFFFF3F<<((eIntNo & 0x3)*8) | ( (1<<((eIntNo%4)*8))-1 ) );
    _mRegValue = _mRegValue | ( uIntSourceType<<((eIntNo & 0x3)*8 + 6) );
    AICRegWrite(REG_AIC_SCR1, (eIntNo >> 2), _mRegValue );
   
    return Successful;
}
//OK
INT32 sysSetLocalInterrupt(INT32 nIntState)
{
    INT32 temp;

    switch (nIntState)
    {
        case ENABLE_IRQ:
        case ENABLE_FIQ:
        case ENABLE_FIQ_IRQ:
            __asm
            {
               MRS    temp, CPSR
               AND    temp, temp, nIntState
               MSR    CPSR_c, temp
            }
        break;

        case DISABLE_IRQ:
        case DISABLE_FIQ:
        case DISABLE_FIQ_IRQ:
            __asm
            {
               MRS    temp, CPSR
               ORR    temp, temp, nIntState
               MSR    CPSR_c, temp
            }
           break;

        default:
               ;
    }
    return Successful;
}
//OK
INT32 sysSetAIC2SWMode()
{
    _sys_bIsHWMode = FALSE;
    return Successful;
}

//OK
UINT32    sysGetInterruptEnableStatus(VOID)
{
        return (inpw(REG_AIC_IMR));
}

//OK
BOOL sysGetIBitState()
{
    INT32 temp;

    __asm
    {
        MRS    temp, CPSR
    }

    if (temp & 0x80)
        return FALSE;
    else
        return TRUE;
}




wb_cache.c   。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                         *
 * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.              *
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
* FILENAME
*   wb_cache.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The cache related functions of Nuvoton ARM9 MCU
*
* HISTORY
*   2008-06-25  Ver 1.0 draft by Min-Nan Cheng
*       
* REMARK
*   None
 **************************************************************************/
#include "wblib.h"

BOOL volatile _sys_IsCacheOn = FALSE;
INT32 volatile _sys_CacheMode;
extern void sys_flush_and_clean_dcache(void);
extern void sysDisableDCache(void);
extern void sysDisableICache(void);
extern int sysInitMMUTable(int);


INT32 sysGetSdramSizebyMB()
{
    unsigned int volatile reg, totalsize=0;

    reg = inpw(REG_SDSIZE0) & 0x07;
    switch(reg)
    {
        case 1:
            totalsize += 2;
            break;

        case 2:
            totalsize += 4;
            break;

        case 3:
            totalsize += 8;
            break;

        case 4:
            totalsize += 16;
            break;

        case 5:
            totalsize += 32;
            break;

        case 6:
            totalsize += 64;
            break;
    }

    reg = inpw(REG_SDSIZE1) & 0x07;
    switch(reg)
    {
        case 1:
            totalsize += 2;
            break;

        case 2:
            totalsize += 4;
            break;

        case 3:
            totalsize += 8;
            break;

        case 4:
            totalsize += 16;
            break;

        case 5:
            totalsize += 32;
            break;

        case 6:
            totalsize += 64;
            break;
    }

    if (totalsize != 0)
        return totalsize;
    else
        return Fail;    
}


INT32 sysEnableCache(UINT32 uCacheOpMode)
{
    sysInitMMUTable(uCacheOpMode);
    _sys_IsCacheOn = TRUE;
    _sys_CacheMode = uCacheOpMode;
    
    return 0;
}

VOID sysDisableCache()
{
    int temp;

    sys_flush_and_clean_dcache();
    __asm
    {
        /*----- flush I, D cache & write buffer -----*/
        MOV temp, 0x0
        MCR p15, 0, temp, c7, c5, 0 /* flush I cache */
        MCR p15, 0, temp, c7, c6, 0 /* flush D cache */
        MCR p15, 0, temp, c7, c10,4 /* drain write buffer */        

        /*----- disable Protection Unit -----*/
        MRC p15, 0, temp, c1, c0, 0     /* read Control register */
        BIC    temp, temp, 0x01
        MCR p15, 0, temp, c1, c0, 0     /* write Control register */
        
        /*----- disable I Cache -----*/
        MRC p15, 0, r7, c1, c0, 0
        bic r7, r7, #0x1000
        MCR p15, 0, r7, c1, c0, 0
            
        /*----- disable D Cache -----*/        
        MRC p15, 0, r7, c1, c0, 0
        bic r7, r7, #0x04
        MCR p15, 0, r7, c1, c0, 0
    }
    
    _sys_IsCacheOn = FALSE;
    _sys_CacheMode = CACHE_DISABLE;
    
}

VOID sysFlushCache(INT32 nCacheType)
{
    int temp;

    switch (nCacheType)
    {
        case I_CACHE:
            __asm
            {
                /*----- flush I-cache -----*/
                MOV temp, 0x0
                MCR p15, 0, temp, c7, c5, 0 /* invalidate I cache */
            }
            break;

        case D_CACHE:
            sys_flush_and_clean_dcache();
            __asm
            {
                /*----- flush D-cache & write buffer -----*/
                MOV temp, 0x0            
                MCR p15, 0, temp, c7, c10, 4 /* drain write buffer */
            }
            break;

        case I_D_CACHE:
            sys_flush_and_clean_dcache();
            __asm
            {
                /*----- flush I, D cache & write buffer -----*/
                MOV temp, 0x0
                MCR p15, 0, temp, c7, c5, 0 /* invalidate I cache */
                MCR p15, 0, temp, c7, c10, 4 /* drain write buffer */        
            }
            break;

        default:
            ;
    }
}

VOID sysInvalidCache()
{
    int temp;

    __asm
    {        
        MOV temp, 0x0
        MCR p15, 0, temp, c7, c7, 0 /* invalidate I and D cache */
    }
}

BOOL sysGetCacheState()
{
    return _sys_IsCacheOn;
}


INT32 sysGetCacheMode()
{
    return _sys_CacheMode;
}


INT32 _sysLockCode(UINT32 addr, INT32 size)
{
    int i, cnt, temp;
        
    __asm
    {
        /* use way3 to lock instructions */
        MRC p15, 0, temp, c9, c0, 1 ;
        ORR temp, temp, 0x07 ;
        MCR p15, 0, temp, c9, c0, 1 ;
    }
    
    if (size % 16)  cnt = (size/16) + 1;
    else            cnt = size / 16;
    
    for (i=0; i<cnt; i++)
    {
        __asm
        {
            MCR p15, 0, addr, c7, c13, 1;
        }
    
        addr += 16;
    }
    
    
    __asm
    {
        /* use way3 to lock instructions */
        MRC p15, 0, temp, c9, c0, 1 ;
        BIC temp, temp, 0x07 ;
        ORR temp, temp, 0x08 ;
        MCR p15, 0, temp, c9, c0, 1 ;
    }
    
    return Successful;

}


INT32 _sysUnLockCode()
{
    int temp;
    
    /* unlock I-cache way 3 */
    __asm
    {
        MRC p15, 0, temp, c9, c0, 1;
        BIC temp, temp, 0x08 ;
        MCR p15, 0, temp, c9, c0, 1;
    
    }
 
    return Successful;
}




wb_config.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


/***************************************************************************
 *                                                                         *
 * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.              *
 *                                                                         *
 ***************************************************************************/
/****************************************************************************
 *
 * FILENAME : wb_config.c
 *
 * VERSION  : 1.1
 *
 * DESCRIPTION : 
 *               PLL control functions of Nuvoton ARM9 MCU
 *
 * HISTORY
 *
 *
 *        IBR set clocks default value    
 *             UPLL= 240MHz
 *            SYS = 120MHz
 *            CPU = 60MHz
 *            HCLK = 60MHz
 *            
 *
 *
 *
 ****************************************************************************/
#include <string.h>
#include "wblib.h"
#if 0
WB_PLL_T            _sysClock;
WB_CLKFREQ_T    _sysFreq;  //MHz, added on [2009/03/11]
#endif
//static            _sysClockIniFlag = FALSE;
static UINT32 g_u32SysClkSrc; 
static UINT32 g_u32UpllKHz = 240000, g_u32ApllKHz=240000, g_u32SysKHz = 120000, g_u32CpuKHz = 60000, g_u32HclkKHz = 60000;
static UINT32 g_u32Hclk1KHz, g_u32ApbKHz;
static UINT32 g_u32REG_APLL, g_u32REG_UPLL;
static UINT32 g_u32SysDiv, g_u32CpuDiv, g_u32ApbDiv;
BOOL bIsCpuOver2xHclk = FALSE;
static UINT32 g_u32ExtClk = 27000;

//#define PD_RAM_BASE        0xFF000000
//#define PD_RAM_SIZE        0x1000
extern UINT8  _tmp_buf[];    

//#define DBG_PRINTF        sysprintf
#define DBG_PRINTF(...)
void InitDelay(void)
{
    
}
void sysInitDDR(void)
{    
    UINT32 u32Delay;    
    outp32( 0xb0000224, 0x00000E6E);        
    outp32( 0xb0000220, 0x1008CE6E);    
    outp32( 0xb000020C, 0x00000019);        
    outp32( 0xb0003030, 0x00001010);    
    outp32( 0xb0003010, 0x00000005);
    outp32( 0xb0003004, 0x00000021);
    outp32( 0xb0003004, 0x00000023);
    outp32( 0xb0003004, 0x00000027);
    while(inp32(0xb0003004) & BIT2);
    outp32( 0xb000301C, 0x00001002);
    outp32( 0xb0003018, 0x00000122);
    outp32( 0xb0003004, 0x00000027);
    while(inp32(0xb0003004) & BIT2);
    outp32( 0xb0003004, 0x0000002B);
    while(inp32(0xb0003004) & BIT3);
    outp32( 0xb0003004, 0x0000002B);
    while(inp32(0xb0003004) & BIT3);    
    outp32( 0xb0003018, 0x00000022);
    u32Delay=250;
    while(u32Delay--);            
    outp32( 0xb0003004, 0x00000020);
    outp32( 0xb0003034, 0x00AAAA00);
    outp32( 0xb0003008, 0x000080C0);
    outp32( 0xb00000A0, 0x00000000);
}
void sysInitDDRStart(void)
{
    UINT32   vram_base, aic_status = 0;
    VOID    (*wb_func)(void);
    aic_status = inpw(REG_AIC_IMR);                    //Disable interrupt 
    outpw(REG_AIC_MDCR, 0xFFFFFFFF);
/*
void sysInitDDR(void)
*/
    vram_base = PD_RAM_BASE;        
    memcpy((char *)_tmp_buf, (char *)vram_base, PD_RAM_SIZE);                    //Backup RAM content
    memcpy((VOID *)vram_base,(VOID *)sysInitDDR, PD_RAM_SIZE);        //
    
    
    // Entering clock switch function     
    wb_func = (void(*)(void)) vram_base;
    DBG_PRINTF("Jump to SRAM\n");
    wb_func();    
    //wb_func(eSrcClk, u32Hclk, bIsUp2Hclk3X, u32SysDiv);
    //Restore VRAM
    memcpy((VOID *)vram_base, (VOID *)_tmp_buf, PD_RAM_SIZE);

    outpw(REG_AIC_MDCR, 0xFFFFFFFF);        // Disable all interrupt
    outpw(REG_AIC_MECR, aic_status);        // Restore AIC setting    
}
/*-----------------------------------------------------------------------------------------------------------
 *
 * Function : sysInitMemory
 * 
 * DESCRIPTION : 
 *               According to the external clock and expected PLL output clock to get the content of PLL controll register
 *
 * Parameters 
 *                 eSysPll : eSYS_APLL or eSYS_UPLL
 *            u32FinKHz: External clock. Unit: KHz
 * Return 
 *            PLL clock. 
 * HISTORY
 *               2010-07-15 
 *
-----------------------------------------------------------------------------------------------------------*/
UINT32 sysInitMemory(void)
{
    sysInitDDRStart();
    return 0;
}
/*-----------------------------------------------------------------------------------------------------------
 *
 * Function : sysGetPLLOutputKhz
 * 
 * DESCRIPTION : 
 *               According to the external clock and expected PLL output clock to get the content of PLL controll register
 *
 * Parameters 
 *                 eSysPll : eSYS_APLL or eSYS_UPLL
 *            u32FinKHz: External clock. Unit: KHz
 * Return 
 *            PLL clock. 
 * HISTORY
 *               2010-07-15 
 *
-----------------------------------------------------------------------------------------------------------*/
UINT32 sysGetPLLOutputKhz(
    E_SYS_SRC_CLK eSysPll,
    UINT32 u32FinKHz
    )
{
    UINT32 u32Freq, u32PllCntlReg;
    UINT32 NF, NR, NO;
    UINT8 au8Map[4] = {1, 2, 2, 4};
    
    
    if(eSysPll==eSYS_APLL)
        u32PllCntlReg = inp32(REG_APLLCON);
    else if(eSysPll==eSYS_UPLL)    
        u32PllCntlReg = inp32(REG_UPLLCON);        
        
    if(u32PllCntlReg&0x10000)            //PLL power down. 
        return 0;
            
    NF = (u32PllCntlReg&FB_DV)+2;
    NR = ((u32PllCntlReg & IN_DV)>>9)+2;
    NO = au8Map[((u32PllCntlReg&OUT_DV)>>14)];
    DBG_PRINTF("PLL regster = 0x%x\n", u32PllCntlReg);    
    DBG_PRINTF("NF = %d\n", NF);
    DBG_PRINTF("NR = %d\n", NR);
    DBG_PRINTF("NO = %d\n", NO);
        
    u32Freq = u32FinKHz*NF/NR/NO;
    DBG_PRINTF("PLL Freq = %d\n", u32Freq);
    return u32Freq;
}

volatile BOOL bIsCheckPllConstraint = FALSE;
void sysCheckPllConstraint(BOOL bIsCheck)
{
    bIsCheckPllConstraint = bIsCheck;
}

/*-----------------------------------------------------------------------------------------------------------
 *
 * Function : sysGetPLLControlRegister
 * 
 * DESCRIPTION : 
 *               According to the external clock and expected PLL output clock to get the content of PLL controll register
 *
 * Parameters 
 *                 u32FinKHz : External clock.  Unit:KHz
 *            u32TargetKHz: PLL output clock. Unit:KHz
 * Return 
 *                   0 : No any fit value for the specified PLL output clock
 *            PLL control register. 
 * HISTORY
 *               2010-07-15 
 *
-----------------------------------------------------------------------------------------------------------*/
UINT32 sysGetPLLControlRegister(UINT32 u32FinKHz, UINT32 u32TargetKHz)
{
    unsigned int u32OUT_DV, u32IN_DV, u32FB_DV;
    unsigned int u32NR, u32NF, u32NO;
    unsigned int au32Array[4] = {1 , 2, 2, 4};
    unsigned u32Target;
    unsigned int u23Register=0;
    
    do
    {
        for(u32OUT_DV =0 ; u32OUT_DV<4; u32OUT_DV=u32OUT_DV+1)
        {
            for(u32IN_DV =0 ; u32IN_DV<32; u32IN_DV=u32IN_DV+1)
            {                
                for(u32FB_DV =0 ; u32FB_DV<512; u32FB_DV=u32FB_DV+1)
                {
                    u32NR =  (2 * (u32IN_DV + 2));
                    u32NF = (2 * (u32FB_DV + 2));
                    u32NO = au32Array[u32OUT_DV];                        
                    if( (u32FinKHz/u32NR)<1000 )        
                        continue;    
                    if( (u32FinKHz/u32NR)>15000)        
                        continue;    
                    if( ((u32FinKHz/u32NR)*u32NF) <100000)
                        continue;
                    if( ((u32FinKHz/u32NR)*u32NF) >500000)
                        continue;                
                    u32Target = u32FinKHz*u32NF/u32NR/u32NO;
                    if(u32TargetKHz==u32Target)
                    {
                        u23Register = (u32OUT_DV<<14) | (u32IN_DV<<9) | (u32FB_DV);                    
                        return u23Register;
                    }    
                    if(bIsCheckPllConstraint==TRUE)
                    {
                        unsigned int u32VerifyFout;                                
                        DBG_PRINTF("===================================================\n");    
                        if((u32FinKHz*u32NF/u32NR)<250000)
                            DBG_PRINTF("Frequency is preferred");    
                        DBG_PRINTF("Frequency out = %d\n", u32Fout);
                        u23Register = (u32OUT_DV<<14) | (u32IN_DV<<9) | (u32FB_DV);
                        DBG_PRINTF("Register = 0x%x\n", u23Register);

                        u32VerifyFout = sysGetPLLOutputKhz(u32FinKHz, u23Register);
                        DBG_PRINTF("Verify Fout = %d KHz\n", u32VerifyFout);
                    }        
                }
            }    
        }
        u32TargetKHz = u32TargetKHz -4000;        //- 4MHz
    }while((u23Register==0));
        
    return 0;
}
/*-----------------------------------------------------------------------------------------------------------
* Function: sysSetPLLControlRegister                                                                
*                                                                                                        
* Parameters:                                                                                             
*              u32PllValue - [in], PLL setting value                                                      
*                                                                                                         
* Returns:                                                                                                
*      None                                                                                               
*                                                                                                         
* Description:                                                                                            
*              To set the PLL control register.                                                           
*                                                                                                         
-----------------------------------------------------------------------------------------------------------*/
void 
sysSetPLLControlRegister(
    E_SYS_SRC_CLK eSysPll,        
    UINT32 u32PllValue
    )
{
    if(eSysPll==eSYS_APLL)
        outp32(REG_APLLCON, u32PllValue);
    else if(eSysPll==eSYS_APLL)
        outp32(REG_UPLLCON, u32PllValue);    
}
/*
    1. Refresh rate base on the target 
    Check the low freq bit in SDRAM controller whether need set ot not for DDR. ???????????    
    refresh rate = REPEAT/Fmclk
*/
void sysExternalClock(void)
{
    /*Refresh rate is always from external clock */
    //UINT32 u32Repeat;
    //u32Repeat = 8*100;                                        //Max HCLK is 100MHz         
    //outp32(REG_SDREF, (inp32(REG_SDREF) & ~REFRATE) | u32Repeat);    //Set new refresh rate 
        
    outp32(REG_PWRCON, (inp32(REG_PWRCON) & ~UP2HCLK3X));        //Clear anyway no matter CPU/HCLK>2x
    outp32(REG_CLKDIV0, inp32(REG_CLKDIV0) & ~(SYSTEM_N1 | SYSTEM_S | SYSTEM_N0)); //System clock from external and divider as 0.
    outp32(REG_CLKDIV4, inp32(REG_CLKDIV4) & ~(CPU_N) );
}
/*-----------------------------------------------------------------------------------------------------------
* Function: sysSetSystemClock                                                               
*                                                                                                        
* Parameters:                                                                                             
*              u32PllValue - [in], PLL setting value                                                      
*                                                                                                         
* Returns:                                                                                                
*      None                                                                                               
*                                                                                                         
* Description:                                                                                            
*              To set the PLL control register.                                                           
*  
*Note:
*        Switch systetm clock to external clock first. Remember to adjust the refresh rate before switch to external clock 
*               
*        refresh rate = REPEAT/Fmclk
*            
*        1. Switch to external clock        
*            a. Change refresh base on PLL value. Although the value more power sumption  
*        
*
*
*
*
*                                                                                                           
-----------------------------------------------------------------------------------------------------------*/
void sysClockSwitch(register E_SYS_SRC_CLK eSrcClk,
                        register UINT32 u32PllReg,
                        register UINT32 u32HclkKHz,
                        //register BOOL bIsUp2Hclk3X,
                        register UINT32 u32SysDiv,
                        register UINT32 u32CpuDiv,
                        register UINT32 u32ApbDiv)
{
    UINT32 u32IntTmp;
    // disable interrupt (I will recovery it after clock changed)
    u32IntTmp = inp32(REG_AIC_IMR);
    outp32(REG_AIC_MDCR, 0xFFFFFFFE);
    
    outp32(REG_SDCMD, inp32(REG_SDCMD) | (AUTOEXSELFREF| REF_CMD));//DRAM enter self refresh mode
    
    if( (inp32(REG_CHIPCFG)&SDRAMSEL) == 0x20){//DDR2 will always disable DLL. Due to DLL enable only HCLK>133MHz.             
            outp32(REG_SDEMR, inp32(REG_SDEMR)  | DLLEN); //Disable DLL. 
            if(u32HclkKHz<96000)
                outp32(REG_SDOPM, inp32(REG_SDOPM)  | LOWFREQ); //Enable Low Freq
            else
                outp32(REG_SDOPM, inp32(REG_SDOPM)  & ~LOWFREQ); //Enable Low Freq        
    }    
    
    if(eSrcClk==eSYS_EXT)
    {
        //Disable DLL of SDRAM device /*05-17*/
        outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & ~SYSTEM_N0) | u32SysDiv );
        
        if( (inp32(REG_CHIPCFG)&SDRAMSEL) != 00)
        {//SDRAM unnecessary             
            outp32(REG_SDEMR, inp32(REG_SDEMR)  | DLLEN); 
            outp32(REG_SDOPM, inp32(REG_SDOPM) | LOWFREQ);
        }
        outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & (~0xFF))); //Switch to external clock and divider to 0        
    }
    else if(eSrcClk==eSYS_UPLL)
    {
        
    
        //outp32(REG_UPLLCON, u32PllReg);
        outp32(REG_CLKDIV0,  (inp32(REG_CLKDIV0) | 0x02));    //Safe consider
        outp32(REG_UPLLCON, u32PllReg);
        __asm
        {
            mov         r2, #1000
            mov        r1, #0
            mov        r0, #1
        loop1:    add         r1, r1, r0
            cmp         r1, r2
            bne        loop1
        }        
        outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & (~0xF1F)) | ((eSrcClk<<3) | u32SysDiv));    
        //outp32(0xb0000200, inp32(0xb0000200) | ((bIsUp2Hclk3X&1)<<5));
        //outp32(REG_CLKDIV4,  (inp32(REG_CLKDIV4) & ~0x0F)| u32CpuDiv );
        outp32(REG_CLKDIV4,  (inp32(REG_CLKDIV4) & ~0xF0F)| (u32CpuDiv| (u32ApbDiv<<8) ));
        __asm
        {
            mov         r2, #1000
            mov        r1, #0
            mov        r0, #1
        loop2:    add         r1, r1, r0
            cmp         r1, r2
            bne        loop2
        }        

    }
    else if (eSrcClk==eSYS_APLL)
    {                        
          if ((inp32(REG_CLKDIV0) & (0x18))==0x18)
        {//From UPLL -->APLL            
                                        
            //outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) | (0x02))); //Safe consider
            outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & (~0xFF))); //Switch to external clock and divider to 0
            
            //APB = CPU/2
            outp32(REG_CLKDIV4, 0x00000100);    
            // enable APLL
            outp32(REG_APLLCON, 0x00F8801C);     //outp32(0xb0000220, 0x00F0801C);
            __asm
            {
                mov         r2, #500
                mov        r1, #0
                mov        r0, #1
            loop3:    add         r1, r1, r0
                cmp         r1, r2
                bne        loop3
            }        
            #if 0
            for (u32Count=0; u32Count<50; u32Count=u32Count+1)
            {
                outp32(REG_APLLCON, (0x00F88000 | u32PllReg));
            }
            #else
            __asm
            {
                mov        r0, #0xb0000000
                mov         r1, #0x00F80000
                orr        r1, r1, u32PllReg
                mov        r2, #5                    
            loop3_1:    
                str        r1, [r0, 0x220]                            
                sub        r2, r2, #1
                cmp        r2, #0
                bne         loop3_1    
            }    
            #endif
            
            
            __asm
            {
                mov         r2, #500
                mov        r1, #0
                mov        r0, #1
            loop4:    add         r1, r1, r0
                cmp         r1, r2
                bne        loop4
            }        
            
            //outp32(REG_CLKDIV0, 0x12);
            
            __asm
            {
                mov         r2, #1000
                mov        r1, #0
                mov        r0, #1
            loop5:    add         r1, r1, r0
                cmp         r1, r2
                bne        loop5
            }                    
        } 
        else 
        {//From APLL -->APLL    
            
            outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & (~0xFF))); //Switch to external clock and divider to 0
            outp32(REG_APLLCON, (0x00F80000 | u32PllReg));
            __asm
            {
                mov         r2, #1000
                mov        r1, #0
                mov        r0, #1
            loop6:    add         r1, r1, r0
                cmp         r1, r2
                bne        loop6
            }                                        
        }
        outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & (~0xF1F)) | ((eSrcClk<<3) | u32SysDiv));    
        //outp32(REG_PWRCON, inp32(REG_PWRCON) | ((bIsUp2Hclk3X&1)<<5));
        outp32(REG_CLKDIV4,  (inp32(REG_CLKDIV4) & ~0xF0F)| (u32CpuDiv| (u32ApbDiv<<8) ));
    }
    __asm
    {
        mov         r2, #1000
        mov        r1, #0
        mov        r0, #1
    loop7:    add         r1, r1, r0
        cmp         r1, r2
        bne        loop7
    }    
    outp32(REG_SDCMD, inp32(REG_SDCMD) & ~REF_CMD);                //DRAM escape self refresh mode
    __asm
    {
        mov         r2, #1000
        mov        r1, #0
        mov        r0, #1
        loop8:    add         r1, r1, r0
        cmp         r1, r2
        bne        loop8
    }    
    // enable interrupt (recovery origianl interrupt maask)
    outp32(REG_AIC_MECR, u32IntTmp);    
}
void sysClockSwitchStart(E_SYS_SRC_CLK eSrcClk, 
                        UINT32 u32PllReg,
                        UINT32 u32Hclk,
                        //BOOL bIsUp2Hclk3X,
                        UINT32 u32SysDiv, 
                        UINT32 u32CpuDiv,
                        UINT32 u32ApbDiv)
{
    UINT32   vram_base, aic_status = 0;
    VOID    (*wb_func)(E_SYS_SRC_CLK, 
                    UINT32, 
                    UINT32, 
                    //BOOL, 
                    UINT32, 
                    UINT32, 
                    UINT32);
    aic_status = inpw(REG_AIC_IMR);                    //Disable interrupt 
    outpw(REG_AIC_MDCR, 0xFFFFFFFF);

    vram_base = PD_RAM_BASE;        
    memcpy((char *)((UINT32)_tmp_buf | 0x80000000), 
            (char *)((UINT32)vram_base | 0x80000000), 
            PD_RAM_SIZE);                    //Backup RAM content
    memcpy((VOID *)((UINT32)vram_base | 0x80000000),
            (VOID *)((UINT32)sysClockSwitch | 0x80000000), 
            PD_RAM_SIZE);                    //
    
    wb_func = (void(*)(E_SYS_SRC_CLK, 
                    UINT32, 
                    UINT32,                     
                    UINT32, 
                    UINT32, 
                    UINT32)) vram_base;
    
    DBG_PRINTF("SYS_DIV = %x\n", u32SysDiv);
    DBG_PRINTF("CPU_DIV = %x\n", u32CpuDiv);
    DBG_PRINTF("APB_DIV = %x\n", u32ApbDiv);
    DBG_PRINTF("Jump to SRAM\n");
    wb_func(eSrcClk, 
            u32PllReg, 
            u32Hclk, 
            u32SysDiv, 
            u32CpuDiv, 
            u32ApbDiv);    

    
    //Restore VRAM
    memcpy((VOID *)((UINT32)vram_base | 0x80000000), 
            (VOID *)((UINT32)_tmp_buf | 0x80000000), 
            PD_RAM_SIZE);

    outpw(REG_AIC_MDCR, 0xFFFFFFFF);        // Disable all interrupt
    outpw(REG_AIC_MECR, aic_status);        // Restore AIC setting    
}

BOOL bIsAPLLInitialize = FALSE;

UINT32 sysGetExternalClock(void)
{
    if((inp32(REG_CHIPCFG) & 0xC) == 0x8)
        g_u32ExtClk = 12000;
    else 
        g_u32ExtClk = 27000;    
    return g_u32ExtClk;
}        
/*-----------------------------------------------------------------------------------------------------------
*    The Function set the relative system clock. PLL, SYS,CPU, HCLK, APB
*    And if specified PLL not meet some costraint, the funtion will search the near frequency and not over the specified frequency
*    
*     Paramter:
*        eSrcClk: eSYS_UPLL or eSYS_APLL
*        u32PllKHz: Target PLL clock as system clock source. The frequency should not over 200MHz/240Mhz. 
*        u32SysKHz: System clock. The frequency should not over 200MHz/240MHz. Designer suggestion set it below 200MHz.
*        u32CpuKHz: The Frequency must equal to HCLK clock or max equal to 2HCLK.
*        u32HclkKHz: The Frequency must equal to CPU clock or equal to CPU/2. It is the memory clock. Max to 133MHz
*        u32ApbKHz: APB clock.
*    Return: 
*        Error code or Successful                                                                                                        
-----------------------------------------------------------------------------------------------------------*/
UINT32 
sysSetSystemClock(
    E_SYS_SRC_CLK eSrcClk,    
    UINT32 u32PllKHz,     
    UINT32 u32SysKHz,
    UINT32 u32CpuKHz,
    UINT32 u32HclkKHz,
    UINT32 u32ApbKHz
    )
{
    INT32 i32Div;
    UINT32 u32SysSrc; 
    INT32 i32Idx;    
    UINT32 u32RegPll;
    register UINT32 u32SysDiv, u32CpuDiv;
    
    if((inp32(REG_CHIPCFG) & 0xC) == 0x8)
        g_u32ExtClk = 12000;
    else 
        g_u32ExtClk = 27000;    
    
    if(eSrcClk != eSYS_EXT)
    {    
        i32Div = u32PllKHz%u32SysKHz;    
        i32Div = u32PllKHz/u32SysKHz-1+(i32Div?1:0);
        if(u32SysKHz>u32PllKHz)
        {
            DBG_PRINTF("SYS clock > PLL ckock\n");
            return E_ERR_CLK;
        }    
        if(u32CpuKHz>u32SysKHz)
        {
            DBG_PRINTF("CPU clock > SYS ckock\n");
            return E_ERR_CLK;
        }    
        if(u32HclkKHz>u32SysKHz)
        {
            DBG_PRINTF("HCLK clock > SYS ckock\n");
            return E_ERR_CLK;        
        }    
        if(u32ApbKHz>u32HclkKHz)
        {
            DBG_PRINTF("APB clock > HCLK ckock\n");
            return E_ERR_CLK;        
        }    
                                        
        if(u32CpuKHz <= (u32HclkKHz*2))    
        {
            bIsCpuOver2xHclk = 0;
            DBG_PRINTF("CPU/HCLK clock rate <2\n");        
        }    
        else
        {
            bIsCpuOver2xHclk = 1;    
            DBG_PRINTF("2< CPU/HCLK clock rate <3\n");        
        }
        i32Div =  u32PllKHz%u32SysKHz;
        i32Div =  u32PllKHz/u32SysKHz-1+(i32Div?1:0);
        g_u32SysDiv = i32Div;
        g_u32SysKHz = u32PllKHz/ (g_u32SysDiv+1);                    //SYS clock
        DBG_PRINTF("SYS clock = %d\n", g_u32SysKHz);            
        
        if(bIsCpuOver2xHclk==1)
        {    
            g_u32HclkKHz = g_u32SysKHz/6;                        //HCLK clock
            DBG_PRINTF("HCLK clock = %d\n", g_u32HclkKHz);            
            
            i32Div =  g_u32SysKHz%u32CpuKHz;                
            i32Div =  g_u32SysKHz/u32CpuKHz-1 + (i32Div ? 1:0);
            if(i32Div==0)                                        //i32Div must be 1 at least if bIsCpuOver2xHclk=1
                i32Div = 1;
            if(i32Div>5)
                i32Div = 5;                                    //i32Div must be 5 at most if bIsCpuOver2xHclk=1
            g_u32CpuDiv = i32Div;    
            g_u32CpuKHz = g_u32SysKHz/(g_u32CpuDiv+1);            //CPU clock    
            DBG_PRINTF("CPU clock = %d\n", g_u32CpuKHz);
            
            i32Div =  6;                                        //HCLK1's DIV = 6 if     bIsCpuOver2xHclk=1
            g_u32Hclk1KHz = g_u32SysKHz/i32Div;                    //Remember HCLK1 DIV does not plus 1. ?????
            DBG_PRINTF("HCLK1 clock = %d\n", g_u32Hclk1KHz);
                        
            i32Idx = g_u32SysKHz/u32ApbKHz;                    
            g_u32ApbDiv = i32Idx/i32Div;
            if(g_u32ApbDiv>0)
                g_u32ApbDiv= g_u32ApbDiv-1;
                
            g_u32ApbKHz = g_u32SysKHz/((g_u32ApbDiv+1)*i32Div);
            DBG_PRINTF("APB clock = %d\n", g_u32ApbKHz);
        }
        else
        {        
            g_u32HclkKHz = g_u32SysKHz/2;                        //HCLK clock
            DBG_PRINTF("HCLK clock = %d\n", g_u32HclkKHz);        
            
            i32Div =  g_u32SysKHz%u32CpuKHz;                
            i32Div =  g_u32SysKHz/u32CpuKHz-1 + (i32Div ? 1:0);
            
            g_u32CpuDiv = i32Div;
            
            //Note
            if(g_u32CpuDiv>1)
            {
                DBG_PRINTF("CPU divider greate than 1\n");
                return E_ERR_CLK;
            }
            
            g_u32CpuKHz = g_u32SysKHz/(i32Div+1);                //CPU clock    
            DBG_PRINTF("CPU clock = %d\n", g_u32CpuKHz);
            
            i32Div =  (i32Div > 2)?i32Div:2;                        //HCLK1's DIV = MAX(CPU_N, 2)                
            i32Idx = g_u32SysKHz/u32ApbKHz;                    
            g_u32ApbDiv = i32Idx/i32Div-1;
            g_u32ApbKHz = g_u32SysKHz/((g_u32ApbDiv+1)*i32Div);
            DBG_PRINTF("APB clock = %d\n", g_u32ApbKHz);                    
            
        }    
    }    
    
    switch(eSrcClk)
    {
        case eSYS_EXT:
            g_u32SysClkSrc =  eSYS_EXT;
            u32SysSrc = g_u32ExtClk;
             DBG_PRINTF("Switch to external \n");    
             break;
        case eSYS_X32K:
             g_u32SysClkSrc = eSYS_X32K;
             u32SysSrc = 32; 
             break;
        case eSYS_APLL:     
            g_u32SysClkSrc = eSYS_APLL;
            u32SysSrc = u32PllKHz;
            g_u32ApllKHz = u32PllKHz;    
            g_u32REG_APLL = sysGetPLLControlRegister(g_u32ExtClk, g_u32ApllKHz);
            DBG_PRINTF("APLL register = 0x%x\n", g_u32REG_APLL);    
            break;    
        case eSYS_UPLL:  
            g_u32SysClkSrc = eSYS_UPLL;
            u32SysSrc = u32PllKHz;
            g_u32UpllKHz = u32PllKHz;
            g_u32REG_UPLL = sysGetPLLControlRegister(g_u32ExtClk, g_u32UpllKHz);
            DBG_PRINTF("UPLL register = 0x%x\n", g_u32REG_UPLL);
            break;
        default:
            return E_ERR_CLK;
    }                        
    if(eSrcClk == eSYS_EXT)
    {        
        u32RegPll = 0;
        g_u32HclkKHz = 27000;
        bIsCpuOver2xHclk = 0;
        g_u32SysDiv =1;
        g_u32CpuDiv =1;
        g_u32ApbDiv = 1;
    }
    else
    {
        u32SysDiv = u32PllKHz / g_u32SysKHz-1;
        u32CpuDiv = g_u32SysKHz / g_u32CpuKHz-1;     
    }
    /*
    
    */    
    if(eSrcClk==eSYS_UPLL)
    {
        u32RegPll = g_u32REG_UPLL;
        DBG_PRINTF("HCLK clock from UPLL = %d\n", g_u32HclkKHz);
        bIsAPLLInitialize = FALSE; 
    }    
    else if(eSrcClk==eSYS_APLL)
    {
        u32RegPll = g_u32REG_APLL;
        DBG_PRINTF("HCLK clock from APLL = %d\n", g_u32HclkKHz);
    }    
    sysClockSwitchStart(eSrcClk, 
                    u32RegPll, 
                    g_u32HclkKHz, 
                    //bIsCpuOver2xHclk, 
                    g_u32SysDiv, 
                    g_u32CpuDiv, 
                    g_u32ApbDiv);    
    return Successful;            
}

void sysGetSystemClock(E_SYS_SRC_CLK* peSrcClk,    // System clock frol UPLL or APLL or external clock
                    PUINT32 pu32PllKHz,         // 
                    PUINT32 pu32SysKHz,
                    PUINT32 pu32CpuKHz,
                    PUINT32 pu32HclkKHz,
                    PUINT32 pu32ApbKHz)
{
    
    *peSrcClk = g_u32SysClkSrc;
    
    if(g_u32SysClkSrc==eSYS_UPLL)
        *pu32PllKHz = g_u32UpllKHz;
    else if(g_u32SysClkSrc==eSYS_APLL)
        *pu32PllKHz = g_u32ApllKHz;
    
    *pu32SysKHz = g_u32SysKHz;
    *pu32CpuKHz = g_u32CpuKHz;
    *pu32HclkKHz = g_u32HclkKHz;
    *pu32ApbKHz = g_u32ApbKHz;
}
/*-----------------------------------------------------------------------------------------------------------
*    The Function is used to set the other PLL which is not the system clock source. 
*    If system clock source come from eSYS_UPLL. The eSrcClk only can be eSYS_APLL    
*    And if specified PLL not meet some costraint, the funtion will search the near frequency and not over the specified frequency
*    
*     Paramter:
*        eSrcClk: eSYS_UPLL or eSYS_APLL
*        u32TargetKHz: The specified frequency. Unit:Khz.
*
*    Return: 
*        The specified PLL output frequency really.                                                                                                        
-----------------------------------------------------------------------------------------------------------*/
UINT32 sysSetPllClock(E_SYS_SRC_CLK eSrcClk, UINT32 u32TargetKHz)
{
    UINT32 u32PllReg, u32PllOutFreqKHz, u32FinKHz;
    
    if((inp32(REG_CHIPCFG) & 0xC) == 0x8)
        u32FinKHz = 12000;
    else 
        u32FinKHz = 27000;    
        
    //Specified clock is system clock,  return working frequency directly.        
    if( (inp32(REG_CLKDIV0) & SYSTEM_S)== 0x18 )
    {//System from UPLL
        if(eSrcClk==eSYS_UPLL)    
        {
            u32PllOutFreqKHz = sysGetPLLOutputKhz(eSrcClk, u32FinKHz);
            return u32PllOutFreqKHz;    
        }
    }
    if( (inp32(REG_CLKDIV0) & SYSTEM_S)== 0x10 )
    {//System from APLL
        if(eSrcClk==eSYS_APLL)    
        {
            u32PllOutFreqKHz = sysGetPLLOutputKhz(eSrcClk, u32FinKHz);
            return u32PllOutFreqKHz;    
        }
    }
    //Specified clock is not system clock,
    u32PllReg = sysGetPLLControlRegister(u32FinKHz, u32TargetKHz);    
    if(eSrcClk == eSYS_APLL)
        outp32(REG_APLLCON, u32PllReg);
    else if(eSrcClk == eSYS_UPLL)
        outp32(REG_UPLLCON, u32PllReg);    
    if((eSrcClk == eSYS_APLL) || (eSrcClk = eSYS_UPLL))    
    {        
        u32PllOutFreqKHz = sysGetPLLOutputKhz(eSrcClk, u32FinKHz);
        return u32PllOutFreqKHz;        
    }    
    else    
        return 0;    
        
}                


/* ================================================
Change system clock without DDR entering self-refresh.
The code will be copied to SRAM by function-sysClockDivSwitchStart()
==================================================*/  
void sysClockDiv(register UINT32 u32HCLK, register UINT32 u32SysDiv)
{
    register UINT32 u32IntTmp, u32Delay=100;
    UINT32 u32HCLKLimit;
/*Disable interrupts to ensure no any DDR request during change clock */ 
    u32IntTmp = inp32(REG_AIC_IMR);
    outp32(REG_AIC_MDCR, 0xFFFFFFFE);
    
    if( (inp32(REG_CHIPCFG)&SDRAMSEL) == 0x20){//DDR2 will always disable DLL. Due to DLL enable only HCLK>133MHz.             
        outp32(REG_SDEMR, inp32(REG_SDEMR)  | DLLEN); //Disable DLL. 
        u32HCLKLimit = 96000;    
        if(u32HCLK<u32HCLKLimit)
            outp32(REG_SDOPM, inp32(REG_SDOPM)  | LOWFREQ); //Enable Low Freq
        else
            outp32(REG_SDOPM, inp32(REG_SDOPM)  & ~LOWFREQ); //Enable Low Freq                
    }else{    
        u32HCLKLimit = 64000;
    }
    
    if(u32HCLK<u32HCLKLimit)
    {    
        //Disable DLL of SDRAM device
        outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & ~SYSTEM_N0) | u32SysDiv );
        
        if( (inp32(REG_CHIPCFG)&SDRAMSEL) != 00)
        {//SDRAM unnecessary 
            outp32(REG_SDEMR, inp32(REG_SDEMR)  | DLLEN); 
            outp32(REG_SDOPM, inp32(REG_SDOPM) | LOWFREQ);
        }    
    }
    else
    {
        //Enable DLL of SDRAM device
        outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & ~SYSTEM_N0) | u32SysDiv );
        outp32(REG_SDOPM, inp32(REG_SDOPM) & ~LOWFREQ);    
        while(u32Delay--);/*Must*/
        if( (inp32(REG_CHIPCFG)&SDRAMSEL) == 0x20){//DDR2 will always disable DLL. Due to DLL enable only HCLK>133MHz.             
            outp32(REG_SDEMR, inp32(REG_SDEMR)  | DLLEN); //Disable DLL. 
        }
        else    //Other memory type. 
            outp32(REG_SDEMR, inp32(REG_SDEMR)  & ~DLLEN);  
    }
    outp32(REG_AIC_MECR, u32IntTmp);
    u32IntTmp = 0x1000;
    while(u32IntTmp--);
}
/* ================================================
Copy function- sysClockDiv() to RAM, 
then jump to SRAM to execute the code.
==================================================*/  
INT32 sysClockDivSwitchStart(UINT32 u32SysDiv)
{
    UINT32   vram_base, aic_status = 0;
    UINT32 u32PllOutKHz, u32ExtFreq;
    VOID    (*wb_func)(UINT32, UINT32);
    if(u32SysDiv>7)
        return -1;
    /* Judge system clock come from */
    if((inp32(REG_CLKDIV0) & SYSTEM_S)==0)
        u32PllOutKHz = sysGetExternalClock();    
    else{    
        u32ExtFreq = sysGetExternalClock();
        if((inp32(REG_CLKDIV0) & SYSTEM_S) == 0x18)
            u32PllOutKHz = sysGetPLLOutputKhz(eSYS_UPLL, u32ExtFreq);    
           else
                   u32PllOutKHz = sysGetPLLOutputKhz(eSYS_APLL, u32ExtFreq);            
    }
            
    
    aic_status = inpw(REG_AIC_IMR);    //Disable all interrupts 
    outpw(REG_AIC_MDCR, 0xFFFFFFFF);
    vram_base = PD_RAM_BASE;        
    memcpy((VOID *)((UINT32)vram_base | 0x80000000),
            (VOID *)((UINT32)sysClockDiv | 0x80000000), 
            PD_RAM_SIZE);    
    sysprintf("system divider = %d\n", u32SysDiv);                        
    wb_func = (void(*)(UINT32, UINT32)) vram_base;
    sysprintf("Jump to SRAM\n");
    wb_func(u32PllOutKHz/(u32SysDiv+1)/2 , u32SysDiv);    
    outpw(REG_AIC_MDCR, 0xFFFFFFFF);    // Disable all interrupts
    outpw(REG_AIC_MECR, aic_status);        // Restore AIC setting    
    return Successful;
}
/*
    The function is used to power down unused PLL if system come from external clock  
    Please remember that don't power down the PLL is used by some IPs.
*/
INT32 sysPowerDownPLL(E_SYS_SRC_CLK eSrcClk, BOOL bIsPowerDown)
{
    if(bIsPowerDown==TRUE){/* If power down, need to check whether the PLL is system clock source */
        if( (inp32(REG_CLKDIV0)&SYSTEM_S) == (eSrcClk<<3) )
            return -1;
    }    
    if(eSrcClk == eSYS_APLL){
        if(bIsPowerDown==TRUE)
            outp32(REG_APLLCON, (inp32(REG_APLLCON)|PD) );
        else
            outp32(REG_APLLCON, (inp32(REG_APLLCON)&~PD) );
    }else if(eSrcClk == eSYS_UPLL){
        if(bIsPowerDown==TRUE)
            outp32(REG_UPLLCON, (inp32(REG_UPLLCON)|PD) );
        else
            outp32(REG_UPLLCON, (inp32(REG_UPLLCON)&~PD) );        
    }    
    if(bIsPowerDown!=TRUE)
        sysDelay(1);    /* If not power down, need wait 500us for PLL stable */        
    return Successful;
}
#if 0
void sysFirstAdjustAPLL(UINT32 u32ApllClockKHz)
{        
    DBG_PRINTF("System will switch to external\n");
    //sysExternalClock();
    sysSetSystemClock(eSYS_EXT,
                    27000,
                    27000,
                    27000,
                    27000/2,
                    27000/4);
                    
    DBG_PRINTF("System switch to external successful\n");
    DBG_PRINTF("Will first Program APLL\n");    
    sysSetSystemClock(eSYS_APLL,     //E_SYS_SRC_CLK eSrcClk,    
                        u32ApllClockKHz,        //UINT32 u32PllKHz,     
                        u32ApllClockKHz/2,        //UINT32 u32SysKHz,
                        u32ApllClockKHz/4,        //UINT32 u32CpuKHz,
                        u32ApllClockKHz/4,        //UINT32 u32HclkKHz,
                         u32ApllClockKHz/8);        //UINT32 u32ApbKHz
    DBG_PRINTF("First Program APLL successful\n");                         
    bIsAPLLInitialize = TRUE;                     
}


int sysSetPLLConfig(WB_PLL_T *sysClk)
{
    sysClk->pll0 = 0;
    sysClk->cpu_src = 0;
    sysClk->ahb_clk = 0;
    sysClk->apb_clk = 0; 
      _sysClockIniFlag = TRUE;
    return 0;
} /* end sysSetPLLConfig */

int sysGetPLLConfig(WB_PLL_T *sysClk)
{
    sysClk->pll0 = 0;
    sysClk->cpu_src = 0;
    sysClk->ahb_clk = 0;
    sysClk->apb_clk = 0;
    return 0;
} /* end sysGetPLLConfig */

int sysGetClockFreq(WB_CLKFREQ_T *sysFreq)
{
    _sysFreq.pll_clk_freq = 0;
    _sysFreq.cpu_clk_freq = 0;
    _sysFreq.ahb_clk_freq = 0;
    _sysFreq.apb_clk_freq = 0;
    return 0;
}
#endif




wb_dcache.s  。。。。。。。。。。。。。。。。。。。。。。。。。。。

    ;/***************************************************************************
    ; *                                                                         *
    ; * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.              *
    ; *                                                                         *
    ; ***************************************************************************/
    ;    
    
    AREA MEM_INIT, CODE, READONLY
    
    EXPORT    sys_flush_and_clean_dcache

sys_flush_and_clean_dcache
        
tci_loop
    MRC p15, 0, r15, c7, c14, 3 ; test clean and invalidate
    BNE tci_loop        
     BX  r14
        
    END
    

wb_ebi.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/****************************************************************************
*                                                                           *
* Copyright (c) 2008 Nuvoton Technolog. All rights reserved.                *
*                                                                           *
*****************************************************************************/

/****************************************************************************
* FILENAME
*   wb_ebi.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The EBI related functions of Nuvoton ARM9 MCU
*
* HISTORY
*   2008-06-25  Ver 1.0 draft by Min-Nan Cheng
*
* REMARK
*   None
****************************************************************************/
#include <stdio.h>
#include "wblib.h"

INT32 sysSetExternalIO(INT extNo, UINT32 extBaseAddr, UINT32 extSize, INT extBusWidth)
{
    UINT32 volatile reg, extiobase;

    switch (extNo)
    {
        case EXT0:
                    extiobase = REG_EXT0CON;
                    break;
        case EXT1:
                    extiobase = REG_EXT1CON;
                    break;
        case EXT2:
                    extiobase = REG_EXT2CON;
                    break;
        default:
                    return Fail;
    
    }
    
    reg = inpw(extiobase);
    
    // Set Bus width
    switch (extBusWidth)
    {
        case BUS_BIT_8:
                    reg = (reg & 0xfffffffc) | 0x01;
                    break;

        case BUS_BIT_16:
                    reg = (reg & 0xfffffffc) | 0x02;
                    break;

        case BUS_BIT_32:
                    reg = (reg & 0xfffffffc) | 0x03;
                    break;

        case BUS_DISABLE:
                    reg = reg & 0xfffffffc;
                    break;
    }

    // Set size
    switch (extSize)
    {
        case SIZE_256K:
                    reg = reg & 0xfff8ffff;
                    break;

        case SIZE_512K:
                    reg = (reg & 0xfff8ffff)|0x00010000;
                    break;

        case SIZE_1M:
                    reg = (reg & 0xfff8ffff)|0x00020000;
                    break;

        case SIZE_2M:
                    reg = (reg & 0xfff8ffff)|0x00030000;
                    break;

        case SIZE_4M:
                    reg = (reg & 0xfff8ffff)|0x00040000;
                    break;

        case SIZE_8M:
                    reg = (reg & 0xfff8ffff)|0x00050000;
                    break;

        case SIZE_16M:
                    reg = (reg & 0xfff8ffff)|0x00060000;
                    break;

        case SIZE_32M:
                    reg = (reg & 0xfff8ffff)|0x00070000;
                    break;
    }

    // Set Base address
    extBaseAddr = (extBaseAddr << 1) & 0xfff80000;
    reg = reg | extBaseAddr;

    // set the reg value into register
    outpw(extiobase, reg);
    
    return Successful;    
}

INT32 sysSetExternalIOTiming1(INT extNo, INT tACC, INT tACS)
{
    UINT32 volatile reg, extiobase;

    switch (extNo)
    {
        case EXT0:
                    extiobase = REG_EXT0CON;
                    break;
        case EXT1:
                    extiobase = REG_EXT1CON;
                    break;
        case EXT2:
                    extiobase = REG_EXT2CON;
                    break;
        default:
                    return Fail;
    
    }

       reg = inpw(extiobase);
    
    if ((tACC >= 0) && (tACC <= 0xf)){
                reg = (reg & 0xffff87ff) | (tACC << 11);
    }
  
            
    if ((tACS >= 0) && (tACS <= 0x7)){
                reg = (reg & 0xffffff1f) | (tACS << 5);
    }
    
    outpw(extiobase, reg);
    
    return Successful;
         
}

INT32 sysSetExternalIOTiming2(INT extNo, INT tCOH, INT tCOS)
{
    UINT32 volatile reg, extiobase;

    switch (extNo)
    {
        case EXT0:
                    extiobase = REG_EXT0CON;
                    break;
        case EXT1:
                    extiobase = REG_EXT1CON;
                    break;
        case EXT2:
                    extiobase = REG_EXT2CON;
                    break;            

        default:
                    return Fail;
    
    }

    reg = inpw(extiobase);

    if ((tCOH >= 0) && (tCOH <= 0x7))
            reg = (reg & 0xfffff8ff) | (tCOH << 8);

    if ((tCOS >= 0) && (tCOS <= 0x7))
            reg = (reg & 0xffffffe3) | (tCOS << 2);

    outpw(extiobase, reg);
    
    return Successful;
           
}




wb_init.s  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    AREA WB_INIT, CODE, READONLY

;--------------------------------------------
; Mode bits and interrupt flag (I&F) defines
;--------------------------------------------
USR_MODE    EQU        0x10
FIQ_MODE    EQU        0x11
IRQ_MODE    EQU        0x12
SVC_MODE    EQU        0x13
ABT_MODE    EQU        0x17
UDF_MODE    EQU        0x1B
SYS_MODE    EQU        0x1F

I_BIT        EQU        0x80
F_BIT        EQU        0x40

;----------------------------
; System / User Stack Memory
;----------------------------

RAM_Limit         EQU       0x800000
UND_Stack_Size    EQU        256
Abort_Stack_Size  EQU        256
IRQ_Stack_Size    EQU        0x10000
FIQ_Stack_Size    EQU        0x1000
SVC_Stack_Size    EQU        0x1000
USR_Stack_Size    EQU        0
    
    
UND_Stack        EQU        RAM_Limit
Abort_Stack        EQU        UND_Stack-UND_Stack_Size
IRQ_Stack       EQU     Abort_Stack-Abort_Stack_Size      ; followed by IRQ stack
FIQ_Stack       EQU     IRQ_Stack-IRQ_Stack_Size       ; followed by IRQ stack
SVC_Stack       EQU     FIQ_Stack-FIQ_Stack_Size      ; SVC stack at top of memory
USR_Stack        EQU        SVC_Stack-SVC_Stack_Size


    ENTRY
    EXPORT  Reset_Go


    EXPORT    Vector_Table
Vector_Table        
    B       Reset_Go    ; Modified to be relative jumb for external boot
    LDR     PC, Undefined_Addr
    LDR     PC, SWI_Addr
    LDR     PC, Prefetch_Addr
    LDR     PC, Abort_Addr
    DCD        0x0
    LDR     PC, IRQ_Addr
    LDR     PC, FIQ_Addr

        
Reset_Addr      DCD     Reset_Go
Undefined_Addr  DCD     Undefined_Handler
SWI_Addr        DCD     SWI_Handler1
Prefetch_Addr   DCD     Prefetch_Handler
Abort_Addr      DCD     Abort_Handler
                DCD        0
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_Handler


; ************************
; Exception Handlers
; ************************

; The following dummy handlers do not do anything useful in this example.
; They are set up here for completeness.

Undefined_Handler
        B       Undefined_Handler
SWI_Handler1
        B       SWI_Handler1     
Prefetch_Handler
        B       Prefetch_Handler
Abort_Handler
        B       Abort_Handler
IRQ_Handler
        B        IRQ_Handler
FIQ_Handler
        B       FIQ_Handler

    
Reset_Go

;--------------------------------
; Initial Stack Pointer register
;--------------------------------
;INIT_STACK 
 MSR    CPSR_c, #UDF_MODE | I_BIT | F_BIT
 LDR     SP, =UND_Stack

 MSR    CPSR_c, #ABT_MODE | I_BIT | F_BIT
 LDR     SP, =Abort_Stack

 MSR    CPSR_c, #IRQ_MODE | I_BIT | F_BIT
 LDR     SP, =IRQ_Stack

 MSR    CPSR_c, #FIQ_MODE | I_BIT | F_BIT
 LDR     SP, =FIQ_Stack

 MSR    CPSR_c, #SYS_MODE | I_BIT | F_BIT
 LDR     SP, =USR_Stack

 MSR    CPSR_c, #SVC_MODE | I_BIT | F_BIT
 LDR     SP, =SVC_Stack

;------------------------------------------------------
; Set the normal exception vector of CP15 control bit    
;------------------------------------------------------    
    MRC    p15, 0, r0 , c1, c0       ; r0 := cp15 register 1
    BIC r0, r0, #0x2000        ; Clear bit13 in r1
    MCR p15, 0, r0 , c1, c0     ; cp15 register 1 := r0
    
 IF :DEF:SYS_INIT
;-----------------------------
; system initialization 
;------------------------------
;LDR    r0, =0xFFF00004


 ldr    r0, =0xFFF00004
 ldr    r1, =0x00000540
 str    r1, [r0] 

 ldr    r0, =0xFFF0000C
 ldr    r1, =0x00004F47 ; 240MHz: 4F47, 192MHz: 3F47
 str    r1, [r0] 

 ldr    r0, =0XFFF00010
 ldr    r1, =0x001FFFFF
 str    r1, [r0] 

 ldr    r0, =0xFFF00014 
 ldr    r1, =0x104514BB
 str    r1, [r0] 

 ldr    r0, =0xFFF00020
 ldr    r1, =0x00000009
 str    r1, [r0] 

 ldr    r0, =0xFFF00030
 ldr    r1, =0x00000000
 str    r1, [r0] 

 ldr    r0, =0XFFF00034
 ldr    r1, =0x00000000
 str    r1, [r0] 

 ldr    r0, =0xFFF00038
 ldr    r1, =0x000001AB
 str    r1, [r0] 

 ldr    r0, =0xFFF0003C
 ldr    r1, =0x00000050    ;CPU:AHP:APB 1:2:4 0x50, CPU:AHB:APB 1:1:2 0x41
 str    r1, [r0] 

 ldr    r0, =0xFFF00040
 ldr    r1, =0x60000000
 str    r1, [r0] 

 ldr    r0, =0xFFF01000
 ldr    r1, =0x00154201
 str    r1, [r0] 

 ldr    r0, =0xFFF01004
 ldr    r1, =0x4006FFF6
 str    r1, [r0] 

 ldr    r0, =0xFFF01010
 ldr    r1, =0x000090CD    ;16M: 90CC, 32M: 90CD
 str    r1, [r0] 

 ldr    r0, =0xFFF01018 
 ldr    r1, =0x0000015B
 str    r1, [r0] 

 ldr    r0, =0xFFF01020 
 ldr    r1, =0x80007FFD
 str    r1, [r0] 

 ldr    r0, =0xFFF01028
 ldr    r1, =0x00000027
 str    r1, [r0] 


 ldr    r0, =0xFFF0001C
 ldr    r1, =0x00000080
 str    r1, [r0] 

 ENDIF


    IMPORT    __main
    IMPORT    __low_level_init
    
;-----------------------------
;    enter the C code
;-----------------------------
    ldr  r0,=__low_level_init
    BLX  r0
    B   __main
    END




wb_mmu.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                         *
 * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.              *
 *                                                                         *
 ***************************************************************************/ 
/****************************************************************************
 * 
 * FILENAME
 *     wb_mmu.c
 *
 * VERSION
 *     1.0
 *
 * DESCRIPTION
 *     This file implement mmu functions.
 *
  * HISTORY
 *     2008-06-25  Ver 1.0 draft by Min-Nan Cheng
 *
 * REMARK
 *     None
 **************************************************************************/
#include "wblib.h"

#define  _CoarsePageSize     64  //MB

typedef struct _coarse_table
{
    unsigned int page[256];
} _CTable;

__align(0x4000) unsigned int _mmuSectionTable[4096];
__align(1024) static _CTable _mmuCoarsePageTable[_CoarsePageSize];             // maximum 64MB for coarse pages
__align(1024) static _CTable _mmuCoarsePageTable_NonCache[_CoarsePageSize];    // Shadow SDRAM area for non-cacheable 

static BOOL _IsInitMMUTable = FALSE;
static int _MMUMappingMode = MMU_DIRECT_MAPPING;

extern INT32 sysGetSdramSizebyMB(void);
extern void sysSetupCP15(unsigned int);


unsigned int sysGetPhyPageAddr(unsigned int vaddr)
{
    int table_num, page_num;
    unsigned int base_addr, page_base, page_offset, phy_addr;
    volatile _CTable *PageTabPtr;
    
    if (vaddr & 0x80000000)
        PageTabPtr = (_CTable *) _mmuCoarsePageTable_NonCache; //non-cacheable virtual address
    else
        PageTabPtr = (_CTable *) _mmuCoarsePageTable;    //cache-able virtual address
        
    if (sysGetCacheState() == TRUE)
        PageTabPtr = (_CTable *) ((unsigned int)PageTabPtr | 0x80000000); //If cache is enable, must write page tables directly into SDRAM        
    
    base_addr = vaddr & 0x7FFFF000;
    table_num = base_addr / 0x100000;
    page_num = (base_addr & 0xFF000) >> 12;
    
    page_base = (*(PageTabPtr+table_num)).page[page_num] & 0xFFFFF000;
    page_offset = vaddr & 0xFFF;
    phy_addr = page_base + page_offset;

    return phy_addr;

} /* end sysGetPHYAddr */


int sysSetCachePages(unsigned int vaddr, int size, int cache_flag)
{
    int i, cnt, table_num, page_num, cache_mode;
    unsigned volatile int baseaddr, temp;
    volatile _CTable *PageTabPtr;
    
    if (vaddr & 0x80000000)
        PageTabPtr = (_CTable *) _mmuCoarsePageTable_NonCache; //non-cacheable virtual address
    else
        PageTabPtr = (_CTable *) _mmuCoarsePageTable;    //cache-able virtual address
        
    if (sysGetCacheState() == TRUE)
        PageTabPtr = (_CTable *) ((unsigned int)PageTabPtr | 0x80000000); //If cache is enable, must write page tables directly into SDRAM    
    
    vaddr &= 0x7FFFFFFF;    //ignore the non-cacheable bit 31    
    //if ( _IsInitMMUTable == FALSE ) return -1;    
    if ((vaddr + size) > (_CoarsePageSize << 20)) return -1;
    
    if (vaddr & 0xFFF)     return -1;  /* MUST 4K Boundary */
    if (size % 4096)    return -1;  /* MUST 4K multiple size */        
        
    /* for flat mapping address */
    cnt = size / 4096;    

    if (cache_flag == CACHE_WRITE_BACK) /* write back mode */
        cache_mode = 0x0C; 
    else if (cache_flag == CACHE_WRITE_THROUGH) /* write through mode */
        cache_mode = 0x08; 
    else
        cache_mode = 0; /* Non-cacheable, non-buffered */
    
    for (i=0; i<cnt; i++)
    {
        baseaddr = vaddr + i * 4096;
        table_num = baseaddr / 0x100000;
        page_num =  (baseaddr & 0xFF000) >> 12; /* bits [19:12] for level two table index */
    
        temp = (*(PageTabPtr+table_num)).page[page_num] & 0xFFFFFFF3;            
        temp |= cache_mode; /* cache mode */            
        (*(PageTabPtr+table_num)).page[page_num] = temp;
    } 
    
    //sysFlushCache(D_CACHE);
    
    return 0;
    
} /* end sysSetCachePages */

int sysInitPageTable(unsigned int vaddr, unsigned int phy_addr, int size, int cache_flag, int rev_flag)
{
    int i, cnt, table_num, page_num, cache_mode, addr_offset;
    unsigned volatile int phy_base_addr, vbase_addr, temp;
    volatile _CTable *PageTabPtr;
    
    if (vaddr & 0x80000000)
        PageTabPtr = (_CTable *) _mmuCoarsePageTable_NonCache; //non-cacheable virtual address
    else
        PageTabPtr = (_CTable *) _mmuCoarsePageTable;    //cache-able virtual address
        
    if (sysGetCacheState() == TRUE)
        PageTabPtr = (_CTable *) ((unsigned int)PageTabPtr | 0x80000000); //If cache is enable, must write page tables directly into SDRAM        
    
    //if ( _IsInitMMUTable == FALSE ) return -1;    
    vaddr &= 0x7FFFFFFF;    //ignore the non-cacheable bit 31
    if ((vaddr + size) > (_CoarsePageSize << 20)) return -1;    
    if (vaddr & 0xFFFFF)     return -1;  /* MUST 1M Boundary */
    if (size % 4096)        return -1;  /* MUST 4K multiple size */        
                        
    /* Pages count */
    cnt = size / 4096;    

    if (cache_flag == CACHE_WRITE_BACK) /* write back mode */
        cache_mode = 0x0C; 
    else if (cache_flag == CACHE_WRITE_THROUGH) /* write through mode */
        cache_mode = 0x08; 
    else
        cache_mode = 0; /* Non-cacheable, non-buffered */
        
        
    if (rev_flag == MMU_DIRECT_MAPPING)
        phy_base_addr = phy_addr;
    else
        phy_base_addr = phy_addr + size - 4096;        
    
    addr_offset = 4096;
    for (i=0; i<cnt; i++)
    {                
        vbase_addr = vaddr + i * 4096;
        table_num = vbase_addr / 0x100000;
        page_num =  (vbase_addr & 0xFF000) >> 12; /* bits [19:12] for level two table index */
    
        temp = phy_base_addr & 0xFFFFF000;
        temp |= 0xFF0; /* access permission, 11 for read/write */
        temp |= cache_mode; /* cache mode */
        temp |= 0x02;  /* small page */
        
        (*(PageTabPtr+table_num)).page[page_num] = temp;
        
        if (rev_flag == MMU_DIRECT_MAPPING)
            phy_base_addr += addr_offset;
        else
            phy_base_addr -= addr_offset;
    } 
        
    return 0;
    
} /* end sysInitPageTable */


int sysSetMMUMappingMethod(int mode)
{
    _MMUMappingMode = mode;
    
    return 0;

} /* end sysSetMMUMappingMethod */


int sysInitMMUTable(int cache_mode)
{
    unsigned volatile int temp;
    int i, size, ramsize;        
    
    if (_IsInitMMUTable == FALSE)        
    {
        ramsize = sysGetSdramSizebyMB();
        
        //flat mapping for 4GB, 4096 section table, each size is 1MB
        temp = 0xC00;   /* (11:10) access permission, R/W */
        temp |= 0x1E0;  /* (8:5) domain 15 */
        temp |= 0x10;   /* bit 4 must be 1 */
        temp |= 0x00;   /* bit 3:2 for cache control bits, cache disabled */
        temp |= 0x02;   /* set as 1Mb section */
  
        for (i=0; i<4096; i++)
        {
            _mmuSectionTable[i] = (unsigned int)(temp | (i << 20));    
        }
  
            //Inside SDRAM, divide each section into 256 small pages, each page size is 4KB
            if (ramsize > _CoarsePageSize) 
                size = _CoarsePageSize;    //maximum 64MB
            else                           
                size = ramsize;
    
        /* first 1M always direct mapping */
        sysInitPageTable(0, 0, 0x100000, cache_mode, MMU_DIRECT_MAPPING);
        temp = ((unsigned int)_mmuCoarsePageTable  & 0xFFFFFC00); /*  coarse table base address */        
        temp |= 0x1E0;  /* (8:5) domain 15 */
        temp |= 0x10;   /* bit 4 must be 1 */
        temp |= 0x01;   /* Coarse page table */
        _mmuSectionTable[0] = temp;
        
        /* Create a shadow area at 0x80000000 for non-cacheable region */
        sysInitPageTable(0x80000000, 0x0, 0x100000, CACHE_DISABLE, MMU_DIRECT_MAPPING);
        temp = ((unsigned int)_mmuCoarsePageTable_NonCache  & 0xFFFFFC00); /*  coarse table base address */
        temp |= 0x1E0;  /* (8:5) domain 15 */
        temp |= 0x10;   /* bit 4 must be 1 */
        temp |= 0x01;   /* Coarse page table */
        _mmuSectionTable[0x800] = temp;
        
        /* Mapping the other memory */
        for (i=1; i< size; i++)
        {
            temp = (((unsigned int)_mmuCoarsePageTable + (unsigned int)i*1024) & 0xFFFFFC00); /*  coarse table base address */
            //temp = ((unsigned int)(0x604000 + i*1024) & 0xFFFFFC00); /* coarse table base address */
            temp |= 0x1E0;  /* (8:5) domain 15 */
            temp |= 0x10;   /* bit 4 must be 1 */
            temp |= 0x01;   /* Coarse page table */

            if (_MMUMappingMode == MMU_DIRECT_MAPPING)        
                sysInitPageTable((i << 20), (i << 20), 0x100000, cache_mode, MMU_DIRECT_MAPPING); /* direct mapping */
            else
                sysInitPageTable((i << 20), (i << 20), 0x100000, cache_mode, MMU_INVERSE_MAPPING); /* inverse mapping for each 1MB area */
                
            _mmuSectionTable[i] = temp;            
        }
                
        //Create shadow non-cacheabel region
        for (i=1; i< size; i++)
        {
            temp = (((unsigned int)_mmuCoarsePageTable_NonCache + (unsigned int)i*1024) & 0xFFFFFC00); /*  coarse table base address */
            //temp = ((unsigned int)(0x604000 + i*1024) & 0xFFFFFC00); /* coarse table base address */
            temp |= 0x1E0;  /* (8:5) domain 15 */
            temp |= 0x10;   /* bit 4 must be 1 */
            temp |= 0x01;   /* Coarse page table */

            if (_MMUMappingMode == MMU_DIRECT_MAPPING)        
                sysInitPageTable(((i << 20) | 0x80000000), (i << 20), 0x100000, CACHE_DISABLE, MMU_DIRECT_MAPPING); /* direct mapping */
            else
                sysInitPageTable(((i << 20) | 0x80000000), (i << 20), 0x100000, CACHE_DISABLE, MMU_INVERSE_MAPPING); /* inverse mapping for each 1MB area */
                
            _mmuSectionTable[0x800+i] = temp;            
        }
                                        
        _IsInitMMUTable = TRUE;
     }
     
     //moved here by cmn [2007/01/27]
     //set CP15 registers
    sysSetupCP15((unsigned int)_mmuSectionTable);
     
     return 0;
    
} /* end sysInitMMUTable */



wb_power.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                         *
 * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.              *
 *                                                                         *
 ***************************************************************************/

/****************************************************************************
* FILENAME
*   wb_power.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The power managemnet related function of Nuvoton ARM9 MCU
*
* DATA STRUCTURES
*   None
*
* FUNCTIONS
*   sysDisableAllPM_IRQ
*   sysEnablePM_IRQ
*   sysPMStart
*
* HISTORY
*   2008-07-24  Ver 1.0 Modified by Min-Nan Cheng
*
* REMARK
*   When enter PD or MIDLE mode, the sysPMStart function will disable cache
*   (in order to access SRAM) and then recovery it after wake up.
****************************************************************************/
#include <string.h>
#include "wblib.h"

//#define PD_RAM_BASE        0xFF000000
//#define PD_RAM_SIZE        0x1000    


extern BOOL    sysGetCacheState(VOID);
extern INT32     sysGetCacheMode(VOID);
extern INT32     _sysLockCode(UINT32, INT32);
extern INT32     _sysUnLockCode(VOID);

static UINT32 volatile _sys_PM_IRQ = 0;
UINT8  _tmp_buf[PD_RAM_SIZE];

/****************************************************************************
* FUNCTION
*   sysEnablePM_IRQ
*
* DESCRIPTION
*   This function is use to set _sys_PM_IRQ variable. The _sys_PM_IRQ variable
*   save the IRQ channel which use to wake up the system form IDLE, MIDLE, and
*   PD mode
*
* INPUTS
*   irq_no         The interrupt channel
*
* OUTPUTS
*   Successful              The interrupt channel saved successfully
*   WB_PM_INVALID_IRQ_NUM   The interrupt channel number out of range
*
****************************************************************************/
INT sysEnablePM_IRQ(INT irq_no) // set the PM needed IRQ flag
{
    if ((irq_no > 31) || (irq_no < 1))
    {
        return WB_PM_INVALID_IRQ_NUM;
    }

    _sys_PM_IRQ = _sys_PM_IRQ | (UINT32)(1<<irq_no);
    return Successful;
}

/****************************************************************************
* FUNCTION
*   sysDisableAllPM_IRQ
*
* DESCRIPTION
*   This function is use to reset the _sys_PM_IRQ variable.
*
* INPUTS
*   None
*
* OUTPUTS
*   None
*
****************************************************************************/
VOID sysDisableAllPM_IRQ(VOID)  // clear the PM IRQ flag
{
    _sys_PM_IRQ = 0;
}


/****************************************************************************
* FUNCTION
*   _sysEnterPowerSavingMode
*
* DESCRIPTION
*   This function is use to enter idle or power down mode
*
* INPUTS
*   None
*
* OUTPUTS
*   None
*
****************************************************************************/
VOID _sysEnterPowerSavingMode(INT mode, UINT32 irqno)
{
     volatile UINT32 i;
        
        outpw(REG_AIC_MECR, irqno); /* interrupt source to return from power saving mode */            
        //outpw(REG_PMCON, mode);     /* write control register to enter power saving mode */             
        outpw(REG_SDCMD, inpw(REG_SDCMD) | 
                            (AUTOEXSELFREF | REF_CMD));
        __asm 
        {
            mov         r2, 0xb0000200
            ldmia     r2, {r0, r1}
            bic        r0, r0, #0x01
            bic        r1, r1, #0x01
            stmia     r2, {r0, r1}
        }                        
        for (i=0; i<0x100; i++) ;
}


/****************************************************************************
* FUNCTION
*   sysPMStart
*
* DESCRIPTION
*   This function is use to enter power saving mode.
*
* INPUTS
*   pd_type     WB_PM_IDLE/WB_PM_MIDLE/WB_PM_PD
*               The Power saving mode
*
* OUTPUTS
*   Successful          Enter power saving mode and wake up successfully
*   WB_PM_PD_IRQ_Fail   Enter PD mode without enable one of USB DEVICE, KPI, 
*                       RTC or nIRQ
*                       which supports to wake up the system from PD mode
*   WB_PM_Type_Fail     pd_type error
*   WB_PM_CACHE_OFF     cache is disabled that can not lock necessary 
*                       instructions into cache
*
****************************************************************************/
INT sysPMStart(INT pd_type)
{
    E_SYS_SRC_CLK eSrcClk;    
    UINT32 u32PllKHz;    
    UINT32 u32SysKHz;
    UINT32 u32CpuKHz;
    UINT32 u32HclkKHz;
    UINT32 u32ApbKHz;


    VOID    (*wb_func)(INT32, UINT32);
    UINT32   vram_base, aic_status = 0;

    if(pd_type != WB_PM_IDLE && pd_type != WB_PM_MIDLE && pd_type != WB_PM_PD)
    {
        return WB_PM_Type_Fail;
    }

    if(pd_type == WB_PM_PD)
    {
        // Enter PD mode, but IRQ setting error
        // one of nIRQ0~7, KPI, RTC or USBD_INT must enable when enter PD mode
        if (!(_sys_PM_IRQ & (1<<IRQ_EXTINT0 | 1<<IRQ_EXTINT1 | 1<<IRQ_EXTINT2 | 1<<IRQ_EXTINT3 | 1<<IRQ_ADC)))
        {
            return WB_PM_PD_IRQ_Fail;
        }
    }

    aic_status = inpw(REG_AIC_IMR);
    outpw(REG_AIC_MDCR, 0xFFFFFFFF);

    if ((pd_type == WB_PM_MIDLE) || (pd_type == WB_PM_PD))
    {
        //use VRAM Block 1 to store power down function        
        vram_base = PD_RAM_BASE;        
        memcpy((VOID *)_tmp_buf, (VOID *)vram_base, PD_RAM_SIZE);
        memcpy((VOID *)vram_base,(VOID *)_sysEnterPowerSavingMode, PD_RAM_SIZE);        
    }

#if 0
    // Select CPU clock from external clock source
    sysGetPLLConfig(&_oldsysClk);    

    _newsysClk.pll0 = PLL_DISABLE;
    _newsysClk.cpu_src = CPU_FROM_EXTERNAL;
    _newsysClk.ahb_clk = AHB_CPUCLK_1_1;
    _newsysClk.apb_clk = APB_AHB_1_2;
    sysSetPLLConfig(&_newsysClk);
#else
    sysGetSystemClock(&eSrcClk,
                     &u32PllKHz,    
                    &u32SysKHz,
                    &u32CpuKHz,
                    &u32HclkKHz,
                    &u32ApbKHz);    
#endif
    // Entering Power saving mode
    wb_func = (void(*)(INT32, UINT32)) vram_base;
    wb_func(pd_type, _sys_PM_IRQ);

#if 0
    // Restore CPU clock source
    sysSetPLLConfig(&_oldsysClk);
#else
    sysSetSystemClock(eSrcClk,
                    u32PllKHz,
                    u32SysKHz,
                    u32CpuKHz,
                    u32HclkKHz,
                    u32ApbKHz);
#endif    

    //Restore VRAM
    memcpy((VOID *)vram_base, (VOID *)_tmp_buf, PD_RAM_SIZE);

    outpw(REG_AIC_MDCR, 0xFFFFFFFF);        // Disable all interrupt
    outpw(REG_AIC_MECR, aic_status);        // Restore AIC setting    

    return Successful;

}

static void Sample_PowerDown(void)
{
    /* Enter self refresh */            
    __asm
    {/* Dealy */
        mov     r2, #100
        mov        r1, #0
        mov        r0, #1
    loopa:        add r1, r1, r0
        cmp     r1, r2
        bne        loopa
    }    
    outp32(REG_SDOPM, inp32(REG_SDOPM) & ~OPMODE);
    outp32(REG_SDCMD, (inp32(REG_SDCMD) & ~(AUTOEXSELFREF | CKE_H)) | SELF_REF);    
            
    //outp32(REG_GPIOD_DOUT, inp32(REG_GPIOD_DOUT) & ~0x3);  
    /* Change the system clock souce to 12M crystal*/
    outp32(REG_CLKDIV0, (inp32(REG_CLKDIV0) & (~0x18)) );                
    __asm
    {/* Delay */
        mov         r2, #100
        mov        r1, #0
        mov        r0, #1
    loop0:    add         r1, r1, r0
        cmp         r1, r2
        bne        loop0
    }        
    //outp32(REG_GPIOD_DOUT, inp32(REG_GPIOD_DOUT) | 0x3);  
    
    outp32(REG_UPLLCON, inp32(REG_UPLLCON) | 0x4000);        /* Power down UPLL and APLL */
    outp32(REG_APLLCON, inp32(REG_APLLCON) | 0x4000);            
    __asm
    {
            mov         r2, #300
            mov        r1, #0
            mov        r0, #1
    loop1:    add         r1, r1, r0
            cmp         r1, r2
            bne        loop1
    }        
    /* Fill and enable the pre-scale for power down wake up */
    //outp32(REG_PWRCON, (inp32(REG_PWRCON)  & ~0xFFFF00) | 0xFFFF02);    //1.2 s
    outp32(REG_PWRCON, (inp32(REG_PWRCON)  & ~0xFFFF00) | 0xFF02);        // s    
        
    __asm
    {
        mov         r2, #10
        mov        r1, #0
        mov        r0, #1
    loop2:    add         r1, r1, r0
        cmp         r1, r2
        bne        loop2
    }    
    //outp32(REG_GPIOD_DOUT, (inp32(REG_GPIOD_DOUT) & ~0x03) | 0x1);
    /*  Enter power down. (Stop the external clock */
    __asm 
    {/* Power down */
            mov     r2, 0xb0000200
            ldmia     r2, {r0}
            bic        r0, r0, #0x01
            stmia     r2, {r0}
    }   
    __asm
    {/* Wake up*/ 
            mov     r2, #300
            mov        r1, #0
            mov        r0, #1
    loop3:    add     r1, r1, r0
            cmp     r1, r2
            bne        loop3
    }
    //outp32(REG_GPIOD_DOUT, (inp32(REG_GPIOD_DOUT) & ~0x03) | 0x2);
    

         
     /* Force UPLL and APLL in normal mode */ 
    outp32(REG_UPLLCON, inp32(REG_UPLLCON) & (~0x4000));        
    outp32(REG_APLLCON, inp32(REG_APLLCON) & (~0x4000));    

    __asm
    {/* Delay a moment for PLL stable */
            mov     r2, #5000
            mov        r1, #0
            mov        r0, #1
    loop4:    add     r1, r1, r0
            cmp     r1, r2
            bne        loop4
    }        
    /* Change system clock to PLL and delay a moment.  Let DDR/SDRAM lock the frequency */
    outp32(REG_CLKDIV0, inp32(REG_CLKDIV0) | 0x18);    
                
    __asm
    {
            mov     r2, #500
            mov        r1, #0
            mov        r0, #1
    loop5:    add     r1, r1, r0
            cmp         r1, r2
            bne        loop5
    }
    

    
    /* Set CKE to Low and escape self-refresh mode, Force DDR/SDRAM escape self-refresh */
    outp32(0xB0003004,  0x20);                
    __asm
    {/*  Delay a moment until the escape self-refresh command reached to DDR/SDRAM */
            mov         r2, #100
            mov        r1, #0
            mov        r0, #1
    loop6:    add         r1, r1, r0
            cmp         r1, r2
            bne        loop6
    }            
        
}

static void Entry_PowerDown(UINT32 u32WakeUpSrc)
{
    UINT32 j;
    UINT32 u32IntEnable;
    void (*wb_fun)(void);
    
    UINT32 u32RamBase = PD_RAM_BASE;
    UINT32 u32RamSize = PD_RAM_SIZE;    
    BOOL bIsEnableIRQ = FALSE;
    
    if( sysGetIBitState()==TRUE )
    {
        bIsEnableIRQ = TRUE;
        sysSetLocalInterrupt(DISABLE_IRQ);    
    }        
    memcpy((char*)((UINT32)_tmp_buf| 0x80000000), (char*)(u32RamBase | 0x80000000), u32RamSize);
    memcpy((char*)(u32RamBase | 0x80000000), (char*)((UINT32)Sample_PowerDown | 0x80000000), u32RamSize);
    if(memcmp((char*)(u32RamBase | 0x80000000), (char*)((UINT32)Sample_PowerDown | 0x80000000), u32RamSize)!=0)
    {
        sysprintf("Memcpy copy wrong\n");
    }
    sysFlushCache(I_CACHE);        
    wb_fun = (void(*)(void)) u32RamBase;
    sysprintf("Jump to SRAM (Suspend)\n");
    

    u32IntEnable = inp32(REG_AIC_IMR);    
    outp32(REG_AIC_MDCR, 0xFFFFFFFE);
    outp32(REG_AIC_MECR, 0x00000000);    
    j = 0x800;
    while(j--);
    outp32(0xb0000030, ((u32WakeUpSrc<<24)|(u32WakeUpSrc<<16)));    //Enable and Clear interrupt
    wb_fun();
    outp32(0xb0000030, ((u32WakeUpSrc<<24)|(u32WakeUpSrc<<16)));    //Enable and Clear interrupt
    memcpy((VOID *)u32RamBase, (VOID *)_tmp_buf, PD_RAM_SIZE);
    
    
    sysprintf("Exit to SRAM (Suspend)\n");
    outp32(REG_AIC_MECR, u32IntEnable);                                /*  Restore the interrupt channels */        
    if(bIsEnableIRQ==TRUE)
        sysSetLocalInterrupt(ENABLE_IRQ);    
}
INT32 sysPowerDown(WAKEUP_SOURCE_E eWakeUpSrc)
{
    Entry_PowerDown(eWakeUpSrc);
    return Successful;
}



wb_sysctl.s  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    ;/***************************************************************************
    ; *                                                                         *
    ; * Copyright (c) 2008 Nuvoton Technology. All rights reserved.             *
    ; *                                                                         *
    ; ***************************************************************************/
    ;
        
    AREA SYS_INIT, CODE, READONLY
    
    EXPORT    sysSetupCP15

sysSetupCP15
    
    MOV        r1, r0                 ; _mmuSectionTable
    MCR        p15, 0, r1, c2, c0, 0  ; write translation table base register c2
            
    MOV        r1, #0x40000000
    MCR        p15, 0, r1, c3, c0, 0  ; domain access control register c3
        
    MRC        p15, 0, r1, c1, c0, 0  ; read control register c1
    ORR        r1, r1, #0x1000           ; set enable icache bit
    ORR        r1, r1, #0x5           ; set enable dcache and MMU bits
    MCR        p15, 0, r1, c1, c0, 0  ; write control regiser c1
    
     BX  r14
        
    END
    



wb_timer.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                         *
 * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.              *
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
* FILENAME
*   wb_timer.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The timer related function of Nuvoton ARM9 MCU
*
* HISTORY
*   2008-06-25  Ver 1.0 draft by Min-Nan Cheng
*
* REMARK
*   None
 **************************************************************************/
#include <stdio.h>
#include "wblib.h"

/* Global variables */
PVOID  _sys_pvOldTimer0Vect;
UINT32 _sys_uTimer0ClockRate = EXTERNAL_CRYSTAL_CLOCK;
UINT32 volatile _sys_uTimer0Count = 0;
UINT32 volatile _sys_uTime0EventCount = 0;
UINT32 volatile _sys_uTimer0TickPerSecond;
BOOL   _sys_bIsSetTime0Event = FALSE;
BOOL volatile _sys_bIsTimer0Initial = FALSE;

PVOID  _sys_pvOldTimer1Vect;
UINT32 _sys_uTimer1ClockRate = EXTERNAL_CRYSTAL_CLOCK;
UINT32 volatile _sys_uTimer1Count = 0;
UINT32 volatile _sys_uTime1EventCount = 0;
UINT32 volatile _sys_uTimer1TickPerSecond;
BOOL _sys_bIsSetTime1Event = FALSE;
BOOL volatile _sys_bIsTimer1Initial = FALSE;


#define SECONDS_PER_HOUR        3600
#define SECONDS_PER_DAY        86400
#define SECONDS_365_DAY        31536000
#define SECONDS_366_DAY        31622400

#define TimerEventCount        10

typedef void (*sys_pvTimeFunPtr)();   /* function pointer */
typedef struct timeEvent_t
{
    UINT32                active;
    UINT32                initTick;
    UINT32                curTick;
    sys_pvTimeFunPtr    funPtr;
} TimeEvent_T;
TimeEvent_T tTime0Event[TimerEventCount];
TimeEvent_T tTime1Event[TimerEventCount];

UINT32    volatile _sys_ReferenceTime_Clock = 0;
UINT32    volatile _sys_ReferenceTime_UTC;

static UINT32 month_seconds[] = 
{
    31 * SECONDS_PER_DAY, 
    28 * SECONDS_PER_DAY, 
    31 * SECONDS_PER_DAY, 
    30 * SECONDS_PER_DAY, 
    31 * SECONDS_PER_DAY, 
    30 * SECONDS_PER_DAY, 
    31 * SECONDS_PER_DAY, 
    31 * SECONDS_PER_DAY, 
    30 * SECONDS_PER_DAY, 
    31 * SECONDS_PER_DAY, 
    30 * SECONDS_PER_DAY, 
    31 * SECONDS_PER_DAY
};


/* Interrupt service routine */
VOID sysTimerISR()
{
    int volatile i;

    /*----- check channel 0 -----*/
    if (inpw(REG_TISR) & 0x00000001)
    {
        _sys_uTimer0Count++;
        outpw(REG_TISR, 0x01); /* clear TIF0 */
        if (_sys_uTimer0Count >= 0xfffffff)
              _sys_uTimer0Count = 0;

        if (_sys_bIsSetTime0Event)
        {
            for (i=0; i<TimerEventCount; i++)
            {
                if (tTime0Event[i].active)
                {
                    tTime0Event[i].curTick--;
                    if (tTime0Event[i].curTick == 0)
                    {
                        (*tTime0Event[i].funPtr)();
                        tTime0Event[i].curTick = tTime0Event[i].initTick;
                    }
                }
            }
        }
    }
    /*----- check channel 1 -----*/
    if (inpw(REG_TISR) & 0x00000002)
    {
        _sys_uTimer1Count++;
        outpw(REG_TISR, 0x02); /* clear TIF0 */
        if (_sys_uTimer0Count >= 0xfffffff)
              _sys_uTimer1Count = 0;

        if (_sys_bIsSetTime1Event)
        {
            for (i=0; i<TimerEventCount; i++)
            {
                if (tTime1Event[i].active)
                {
                    tTime1Event[i].curTick--;
                    if (tTime1Event[i].curTick == 0)
                    {
                        (*tTime1Event[i].funPtr)();
                        tTime1Event[i].curTick = tTime1Event[i].initTick;
                    }
                }
            }
        }
    }
}

/* Timer library functions */
UINT32 sysGetTicks(INT32 nTimeNo)
{
    switch (nTimeNo)
    {
        case TIMER0:
            return _sys_uTimer0Count;
        case TIMER1:
            return _sys_uTimer1Count;
        default:
               ;
    }
      return Successful;
}

INT32 sysResetTicks(INT32 nTimeNo)
{
    switch (nTimeNo)
    {
        case TIMER0:
            _sys_uTimer0Count = 0;
            break;
        case TIMER1:
            _sys_uTimer1Count = 0;
            break;

        default:
               ;
    }
    return Successful;
}

INT32 sysUpdateTickCount(INT32 nTimeNo, UINT32 uCount)
{
    switch (nTimeNo)
    {
        case TIMER0:
            _sys_uTimer0Count = uCount;
            break;
        case TIMER1:
            _sys_uTimer1Count = uCount;
            break;
        default:
               ;
    }
    return Successful;
}

INT32 sysSetTimerReferenceClock(INT32 nTimeNo, UINT32 uClockRate)
{
    switch (nTimeNo)
    {
        case TIMER0:
            _sys_uTimer0ClockRate = uClockRate;
            break;
        case TIMER1:
            _sys_uTimer1ClockRate = uClockRate;
            break;
        default:        
               ;
    }
    return Successful;
}

INT32 sysStartTimer(INT32 nTimeNo, UINT32 uTicksPerSecond, INT32 nOpMode)
{
    int volatile i;
    UINT32 _mTicr, _mTcr;

    _mTcr = 0x60000000 | (nOpMode << 27);

    switch (nTimeNo)
    {
        case TIMER0:
            _sys_bIsTimer0Initial = TRUE;
            _sys_uTimer0TickPerSecond = uTicksPerSecond;
            outp32(REG_APBCLK, inp32(REG_APBCLK) | TMR0_CKE);
            outp32(REG_APBIPRST, inp32(REG_APBIPRST) | TMR0RST);
            outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~TMR0RST);
            for (i=0; i<TimerEventCount; i++)
                tTime0Event[i].active = FALSE;
            _sys_pvOldTimer0Vect = sysInstallISR(IRQ_LEVEL_1, 
                                            IRQ_TMR0, 
                                            (PVOID)sysTimerISR);
            sysEnableInterrupt(IRQ_TMR0);
            sysSetInterruptType(IRQ_TMR0, 1);    //eDRVAIC_HIGH_LEVEL
            
            _sys_uTimer0Count = 0;
            _mTicr = _sys_uTimer0ClockRate / uTicksPerSecond;
            outpw(REG_TICR0, _mTicr);
            outpw(REG_TCSR0, (inpw(REG_TCSR0) & 0x87FFFF00) | ((nOpMode | 0xC)<<27));            
            break;
        case TIMER1:
            _sys_bIsTimer1Initial = TRUE;
            _sys_uTimer1TickPerSecond = uTicksPerSecond;
            outp32(REG_APBCLK, inp32(REG_APBCLK) | TMR1_CKE);
            outp32(REG_APBIPRST, inp32(REG_APBIPRST) | TMR1RST);
            outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~TMR1RST);
            for (i=0; i<TimerEventCount; i++)
                tTime1Event[i].active = FALSE;

            _sys_pvOldTimer1Vect = sysInstallISR(IRQ_LEVEL_1, 
                                            IRQ_TMR1, 
                                            (PVOID)sysTimerISR);
            sysEnableInterrupt(IRQ_TMR1);
            sysSetInterruptType(IRQ_TMR1, 1);    //eDRVAIC_HIGH_LEVEL
            
            _sys_uTimer1Count = 0;
            _mTicr = _sys_uTimer1ClockRate / uTicksPerSecond;
            outpw(REG_TICR1, _mTicr);
            outpw(REG_TCSR1, (inpw(REG_TCSR1) & 0x87FFFF00) | ((nOpMode | 0xC)<<27));            
            break;
        default:
            ;
    }
    sysSetLocalInterrupt(ENABLE_IRQ);
    return Successful;
}

INT32 sysStopTimer(INT32 nTimeNo)
{
    switch (nTimeNo)
    {
        case TIMER0:
            _sys_bIsTimer0Initial = FALSE;
            sysInstallISR(IRQ_LEVEL_1, IRQ_TMR0, _sys_pvOldTimer0Vect);
            sysDisableInterrupt(IRQ_TMR0);
            outp32(REG_TCSR0, 0);    /* disable timer */
            outp32(REG_TISR, 1);    /* clear for safty */
            _sys_uTime0EventCount = 0;
            _sys_bIsSetTime0Event = FALSE;                        
            outp32(REG_APBCLK, inp32(REG_APBCLK) & ~TMR0_CKE);
            break;
        case TIMER1:
            _sys_bIsTimer1Initial = FALSE;
            sysInstallISR(IRQ_LEVEL_1, IRQ_TMR1, _sys_pvOldTimer1Vect);
            sysDisableInterrupt(IRQ_TMR1);
            outp32(REG_TCSR1, 0);    /* disable timer */
            outp32(REG_TISR, 2);    /* clear for safty */
            _sys_uTime1EventCount = 0;
            _sys_bIsSetTime1Event = FALSE;
            outp32(REG_APBCLK, inp32(REG_APBCLK) & ~TMR1_CKE);
            break;
        default:
            ;
    }
    //   WB_SetLocalInterrupt(DISABLE_IRQ);
    return Successful;
}

VOID sysClearWatchDogTimerCount()
{
    UINT32 volatile _mWtcr;

    _mWtcr = inpw(REG_WTCR);
    _mWtcr |= 0x01;             /* write WTR */
    outpw(REG_WTCR, _mWtcr);
}

VOID sysClearWatchDogTimerInterruptStatus()
{
    UINT32 volatile _mWtcr;

    _mWtcr = inpw(REG_WTCR);
    _mWtcr |= 0x08;       /* clear WTIF */
    outpw(REG_WTCR, _mWtcr);
}

VOID sysDisableWatchDogTimer()
{
    UINT32 volatile _mWtcr;

    _mWtcr = inpw(REG_WTCR);
    _mWtcr &= 0xFFFFFF7F;
    outpw(REG_WTCR, _mWtcr);
}

VOID sysDisableWatchDogTimerReset()
{
    UINT32 volatile _mWtcr;

    _mWtcr = inpw(REG_WTCR);
    _mWtcr &= 0xFFFFFFFD;
    outpw(REG_WTCR, _mWtcr);
}

VOID sysEnableWatchDogTimer()
{
    UINT32 volatile _mWtcr;

    _mWtcr = inpw(REG_WTCR);
    _mWtcr |= 0x80;
    outpw(REG_WTCR, _mWtcr);
}

VOID sysEnableWatchDogTimerReset()
{
    UINT32 volatile _mWtcr;

    _mWtcr = inpw(REG_WTCR);
    _mWtcr |= 0x02;
    outpw(REG_WTCR, _mWtcr);
}

PVOID sysInstallWatchDogTimerISR(INT32 nIntTypeLevel, PVOID pvNewISR)
{
    PVOID _mOldVect;
    UINT32 volatile _mWtcr;

    _mWtcr = inpw(REG_WTCR);
    _mWtcr |= 0x40;
    outpw(REG_WTCR, _mWtcr);
    _mOldVect = sysInstallISR(nIntTypeLevel, IRQ_WDT, pvNewISR);
    sysEnableInterrupt(IRQ_WDT);
    sysSetLocalInterrupt(ENABLE_IRQ);

    return _mOldVect;
}

INT32 sysSetWatchDogTimerInterval(INT32 nWdtInterval)
{
    UINT32 volatile _mWtcr;

    _mWtcr = inpw(REG_WTCR) & (~0x30); /* SW Fixed */
    _mWtcr = _mWtcr|(0x400)|(nWdtInterval << 4);
    outpw(REG_WTCR, _mWtcr);

    return Successful;
}


INT32 sysSetTimerEvent(INT32 nTimeNo, UINT32 uTimeTick, PVOID pvFun)
{
    int volatile i;
    int val=0;

    switch (nTimeNo)
    {
        case TIMER0:
            _sys_bIsSetTime0Event = TRUE;
            _sys_uTime0EventCount++;
            for (i=0; i<TimerEventCount; i++)
            {
                if (tTime0Event[i].active == FALSE)
                {
                    tTime0Event[i].active = TRUE;
                    tTime0Event[i].initTick = uTimeTick;
                    tTime0Event[i].curTick = uTimeTick;
                    tTime0Event[i].funPtr = (sys_pvTimeFunPtr)pvFun;
                    val = i+1;
                    break;
                }
            }
            /*SW ADD*/
            if(i==TimerEventCount)
                return 0x0;        /*0 means invalid channel*/            
            /**/    
            break;
        case TIMER1:
            _sys_bIsSetTime1Event = TRUE;
            _sys_uTime1EventCount++;
            for (i=0; i<TimerEventCount; i++)
            {
                if (tTime1Event[i].active == FALSE)
                {
                    tTime1Event[i].active = TRUE;
                    tTime1Event[i].initTick = uTimeTick;
                    tTime1Event[i].curTick = uTimeTick;
                    tTime1Event[i].funPtr = (sys_pvTimeFunPtr)pvFun;
                    val = i+1;
                    break;
                }
            }
            /*SW ADD*/
            if(i==TimerEventCount)
                return 0x0;        /*0 means invalid channel*/            
            /**/    
            break;    
        default:
            ;
    }

    return val;
}

VOID sysClearTimerEvent(INT32 nTimeNo, UINT32 uTimeEventNo)
{
    switch (nTimeNo)
    {
        case TIMER0:
            tTime0Event[uTimeEventNo-1].active = FALSE;
            _sys_uTime0EventCount--;
            if (_sys_uTime0EventCount == 0)
                _sys_bIsSetTime0Event = FALSE;
            break;
        case TIMER1:
            tTime1Event[uTimeEventNo-1].active = FALSE;
            _sys_uTime1EventCount--;
            if (_sys_uTime1EventCount == 0)
                _sys_bIsSetTime1Event = FALSE;
            break;
        default:
            ;
    }
}

/* 
 *  The default time: 2005.05.01 Sun 00:00 00:00
 *
 *  one day = 3600 * 24 = 86400
 *  one year = 86400 * 365 = 31536000
 *  year 2005 = 31536000 * 35 + 8 * 86400 = 1104451200
 */

UINT32 sysDOS_Time_To_UTC(DateTime_T ltime)
{
    int        i, leap_year_cnt;
    UINT32    utc;
    
    if ((ltime.mon < 1) || (ltime.mon > 12) || (ltime.day < 1) || (ltime.day > 31) ||
        (ltime.hour > 23) || (ltime.min > 59) || (ltime.sec > 59))
    {
        //_debug_msg("DOS_Time_To_UTC - illegal time!! %d-%d-%d %d:%d:%d\n", year, month, day, hour, minute, second);
        return Fail;
    }

    ltime.year = ltime.year - 1970;        /* DOS is 1980 started, UTC is 1970 started */
    
    leap_year_cnt = (ltime.year + 1) / 4;
    
    utc = ltime.year * SECONDS_365_DAY + leap_year_cnt * SECONDS_PER_DAY;
    
    if ((ltime.year + 2) % 4 == 0)
        month_seconds[1] = 29 * SECONDS_PER_DAY;    /* leap year */
    else
        month_seconds[1] = 28 * SECONDS_PER_DAY;    /* non-leap year */
    
    for (i = 0; i < ltime.mon - 1; i++) 
        utc += month_seconds[i];
        
    utc += (ltime.day - 1) * SECONDS_PER_DAY;
    
    utc += ltime.hour * SECONDS_PER_HOUR + ltime.min * 60 + ltime.sec;
    
    return utc;
}


VOID  sysUTC_To_DOS_Time(UINT32 utc, DateTime_T *dos_tm)
{
    int        the_year = 1970;
    int        i, seconds;
        
    while (1)
    {
        if (the_year % 4 == 0)
            seconds = SECONDS_366_DAY;
        else
            seconds = SECONDS_365_DAY;
        if (utc >= seconds)
        {
            utc -= seconds;
            the_year++;
        }
        else
            break;
    }
    
    dos_tm->year = the_year;
    
    if (the_year % 4 == 0)
        month_seconds[1] = 29 * SECONDS_PER_DAY;
    else
        month_seconds[1] = 28 * SECONDS_PER_DAY;
    
    dos_tm->mon = 1;
    for (i = 0; i < 11; i++)
    {
        if (utc >= month_seconds[i])
        {
            utc -= month_seconds[i];
            dos_tm->mon++;
        }
        else
            break;
    }
    
    dos_tm->day = 1 + (utc / SECONDS_PER_DAY);
    utc %= SECONDS_PER_DAY;
    
    dos_tm->hour = utc / SECONDS_PER_HOUR;
    utc %= SECONDS_PER_HOUR;
    
    dos_tm->min = utc / 60;
    dos_tm->sec = utc % 60;
}


VOID sysSetLocalTime(DateTime_T ltime)
{
    _sys_ReferenceTime_Clock = _sys_uTimer0Count;
    _sys_ReferenceTime_UTC = sysDOS_Time_To_UTC(ltime);
}

VOID sysGetCurrentTime(DateTime_T *curTime)
{
    UINT32 clock, utc_time;

    clock = _sys_uTimer0Count;
    utc_time = _sys_ReferenceTime_UTC + (clock - _sys_ReferenceTime_Clock) / _sys_uTimer0TickPerSecond;

    sysUTC_To_DOS_Time(utc_time, curTime);
}


VOID sysDelay(UINT32 uTicks)
{
    UINT32 volatile btime;

    if(!_sys_bIsTimer0Initial)
    {
            sysStartTimer(TIMER0, 100, PERIODIC_MODE);
    }

    btime = sysGetTicks(TIMER0);
    while(1)
    {
        if((sysGetTicks(TIMER0) - btime) > uTicks)
        {
                break;
        }
    }
}


wb_uart.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                         *
 * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.              *
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
* FILENAME
*   wb_uart.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The UART related function of Nuvoton ARM9 MCU
*
* HISTORY
*   2008-06-25  Ver 1.0 draft by Min-Nan Cheng
*
* REMARK
*   None
 **************************************************************************/
#include <string.h>
#include <stdio.h>
#include "wblib.h"

#ifdef    __HW_SIM__
#undef     REG_UART_THR                       
#define    REG_UART_THR      (0xFFF04400)        // TUBE ON
#endif


#define vaStart(list, param) list = (INT8*)((INT)&param + sizeof(param))
#define vaArg(list, type) ((type *)(list += sizeof(type)))[-1]

/* Global variables */
static BOOL volatile _sys_bIsUARTInitial = FALSE;
static BOOL volatile _sys_bIsUseUARTInt = TRUE;
static UINT32 _sys_uUARTClockRate = EXTERNAL_CRYSTAL_CLOCK;
//UINT32 UART_BA = UART0_BA;

#define RX_ARRAY_NUM 100
static UINT8 uart_rx[RX_ARRAY_NUM] = {0};

VOID _PutChar_f(UINT8 ucCh);
static UINT32 volatile rx_cnt = 0;

#define sysTxBufReadNextOne()    (((_sys_uUartTxHead+1)==UART_BUFFSIZE)? NULL: _sys_uUartTxHead+1)
#define sysTxBufWriteNextOne()    (((_sys_uUartTxTail+1)==UART_BUFFSIZE)? NULL: _sys_uUartTxTail+1)
#define UART_BUFFSIZE    256
static UINT8 _sys_ucUartTxBuf[UART_BUFFSIZE];
static UINT32 volatile _sys_uUartTxHead, _sys_uUartTxTail;
static PVOID  _sys_pvOldUartVect;
static UINT32 u32UartPort =0x100; /* Default Normal Speed UART */


static INT32 i32UsedPort = 1;

void sysUartPort(UINT32 u32Port)
{
    u32UartPort = (u32Port & 0x1)*0x100;
    if(u32Port==0)
    {//High Speed UART        
        outp32(REG_CLKDIV3, (inp32(REG_CLKDIV3) & (~0xFF)));
        outp32(REG_GPDFUN, (inp32(REG_GPDFUN) & ~(MF_GPD2 | MF_GPD1)) | (0x5<<2) );
        outp32(REG_APBCLK, inp32(REG_APBCLK) | UART0_CKE);    
    }
    else if(u32Port==1)
    {//Nornal Speed UART
        outp32(REG_CLKDIV3, (inp32(REG_CLKDIV3) & (~0xFF00)));
        outp32(REG_GPAFUN, inp32(REG_GPAFUN) | (MF_GPA11 | MF_GPA10));
        outp32(REG_APBCLK, inp32(REG_APBCLK) | UART1_CKE);
        
    }
    i32UsedPort = u32Port;
}
static VOID sysSetBaudRate(UINT32 uBaudRate)
{
    UINT32 _mBaudValue;

    /* First, compute the baudrate divisor. */
#if 0        
    // mode 0
    _mBaudValue = (_sys_uUARTClockRate / (uBaudRate * 16));
    if ((_sys_uUARTClockRate % (uBaudRate * 16)) > ((uBaudRate * 16) / 2))
          _mBaudValue++;
    _mBaudValue -= 2;
    outpw(REG_UART_BAUD+u32UartPort, _mBaudValue);        
#else
    // mode 3
    _mBaudValue = (_sys_uUARTClockRate / uBaudRate)-2;
    outpw(REG_UART_BAUD+u32UartPort,  ((0x30<<24)| _mBaudValue));    
#endif    
}

void sysUartEnableInt(INT32 eIntType)
{
    if(eIntType==UART_INT_RDA)
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) |RDA_IEN);
    else if (eIntType==UART_INT_RDTO)    
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) |RTO_IEN |Time_out_EN);
    else if (eIntType == UART_INT_THRE) 
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) |THRE_IEN);
    else if (eIntType==UART_INT_NONE)        
        outp32(REG_UART_IER+u32UartPort, 0x0);
}

extern VOID Uart2Handler(VOID);
extern VOID UartHandler(VOID);

INT32 sysInitializeUART(WB_UART_T *uart)
{
    /* Enable UART multi-function pins*/
    //outpw(REG_PINFUN, inpw(REG_PINFUN) | 0x80);
    //outpw(REG_GPAFUN, inpw(REG_GPAFUN) | 0x00F00000);    //Normal UART pin function 
    static BOOL bIsResetFIFO = FALSE;
    /* Check the supplied parity */
    if ((uart->uiParity != WB_PARITY_NONE) &&
        (uart->uiParity != WB_PARITY_EVEN) &&
        (uart->uiParity != WB_PARITY_ODD))

            /* The supplied parity is not valid */
            return WB_INVALID_PARITY;

    /* Check the supplied number of data bits */
    else if ((uart->uiDataBits != WB_DATA_BITS_5) &&
             (uart->uiDataBits != WB_DATA_BITS_6) &&
             (uart->uiDataBits != WB_DATA_BITS_7) &&
             (uart->uiDataBits != WB_DATA_BITS_8))

            /* The supplied data bits value is not valid */
            return WB_INVALID_DATA_BITS;

    /* Check the supplied number of stop bits */
    else if ((uart->uiStopBits != WB_STOP_BITS_1) &&
             (uart->uiStopBits != WB_STOP_BITS_2))

            /* The supplied stop bits value is not valid */
            return WB_INVALID_STOP_BITS;

    /* Verify the baud rate is within acceptable range */
    else if (uart->uiBaudrate < 1200)
            /* The baud rate is out of range */
            return WB_INVALID_BAUD;

    /* Reset the TX/RX FIFOs */
    if(bIsResetFIFO==FALSE)
    {
        outpw(REG_UART_FCR+u32UartPort, 0x07);
        bIsResetFIFO=TRUE;
    }
    /* Setup reference clock */
    _sys_uUARTClockRate = uart->uiFreq;

    /* Setup baud rate */
    sysSetBaudRate(uart->uiBaudrate);

    /* Set the modem control register. Set DTR, RTS to output to LOW,
    and set INT output pin to normal operating mode */ 
    //outpb(UART_MCR, (WB_DTR_Low | WB_RTS_Low | WB_MODEM_En)); 

    /* Setup parity, data bits, and stop bits */
    outpw(REG_UART_LCR+u32UartPort,(uart->uiParity | uart->uiDataBits | uart->uiStopBits));

    /* Timeout if more than ??? bits xfer time */
    outpw(REG_UART_TOR+u32UartPort, 0x80+0x20);

    /* Setup Fifo trigger level and enable FIFO */
    outpw(REG_UART_FCR+u32UartPort, (uart->uiRxTriggerLevel << 4) | 0x01);

    /* Enable HUART interrupt Only (Receive Data Available Interrupt & RX Time out Interrupt) */
#if 0    
#if 1 //Enable RX data time out    
    outp32(REG_UART_IER+u32UartPort,inp32(REG_UART_IER+u32UartPort) |RDA_IEN |RTO_IEN |Time_out_EN);
#else    
    outp32(REG_UART_IER+u32UartPort,inp32(REG_UART_IER+u32UartPort) |RDA_IEN);
#endif    
#endif 

    /* Timeout if more than ??? bits xfer time */
    outpw(REG_UART_TOR+u32UartPort, 0x7F);

    // hook UART interrupt service routine
    if (u32UartPort)
    {//==1 NORMAL UART
        _sys_uUartTxHead = _sys_uUartTxTail = NULL;
        _sys_pvOldUartVect = sysInstallISR(IRQ_LEVEL_1, IRQ_UART, (PVOID)Uart2Handler);
        sysEnableInterrupt(IRQ_UART);        
    }
    else
    {//==0 High SPEED
        _sys_uUartTxHead = _sys_uUartTxTail = NULL;
        _sys_pvOldUartVect = sysInstallISR(IRQ_LEVEL_1, IRQ_HUART, (PVOID)UartHandler);
        sysEnableInterrupt(IRQ_HUART);
    }
    _sys_bIsUARTInitial = TRUE;

    return Successful;
}


VOID _PutChar_f(UINT8 ucCh)
{
    /* Wait until the transmitter buffer is empty */        
    while (!(inpw(REG_UART_FSR+u32UartPort) & 0x400000));
    /* Transmit the character */
    outpb(REG_UART_THR+u32UartPort, ucCh);

    if (ucCh == '\n')
    {
        /* Wait until the transmitter buffer is empty */
            while (!(inpw(REG_UART_FSR+u32UartPort) & 0x400000));
        outpb(REG_UART_THR+u32UartPort, '\r');
    }

}


VOID sysPutString(INT8 *string)
{
    while (*string != '\0')
    {
        _PutChar_f(*string);
        string++;
    }
}


static VOID sysPutRepChar(INT8 c, INT count)
{
    while (count--)
    _PutChar_f(c);
}


static VOID sysPutStringReverse(INT8 *s, INT index)
{
    while ((index--) > 0)
    _PutChar_f(s[index]);
}


static VOID sysPutNumber(INT value, INT radix, INT width, INT8 fill)
{
    INT8    buffer[40];
    INT     bi = 0;
    UINT32  uvalue;
    UINT16  digit;
    UINT16  left = FALSE;
    UINT16  negative = FALSE;

    if (fill == 0)
            fill = ' ';

    if (width < 0)
    {
        width = -width;
        left = TRUE;
    }

    if (width < 0 || width > 80)
            width = 0;

    if (radix < 0)
    {
        radix = -radix;
        if (value < 0)
        {
            negative = TRUE;
            value = -value;
            }
    }

    uvalue = value;

    do
    {
        if (radix != 16)
        {
            digit = uvalue % radix;
            uvalue = uvalue / radix;
        }
        else
        {
            digit = uvalue & 0xf;
            uvalue = uvalue >> 4;
        }
        buffer[bi] = digit + ((digit <= 9) ? '0' : ('A' - 10));
        bi++;

        if (uvalue != 0)
        {
            if ((radix == 10)
                && ((bi == 3) || (bi == 7) || (bi == 11) | (bi == 15)))
            {
                buffer[bi++] = ',';
            }
        }
    }
    while (uvalue != 0);

    if (negative)
    {
        buffer[bi] = '-';
        bi += 1;
    }

    if (width <= bi)
        sysPutStringReverse(buffer, bi);
    else
    {
        width -= bi;
        if (!left)
            sysPutRepChar(fill, width);
        sysPutStringReverse(buffer, bi);
        if (left)
                sysPutRepChar(fill, width);
    }
}


static INT8 *FormatItem(INT8 *f, INT a)
{
    INT8   c;
    INT    fieldwidth = 0;
    INT    leftjust = FALSE;
    INT    radix = 0;
    INT8   fill = ' ';

    if (*f == '0')
        fill = '0';

    while ((c = *f++) != 0)
    {
        if (c >= '0' && c <= '9')
        {
            fieldwidth = (fieldwidth * 10) + (c - '0');
        }
        else
            switch (c)
            {
                case '\000':
                    return (--f);
                case '%':
                        _PutChar_f('%');
                        return (f);
                case '-':
                        leftjust = TRUE;
                        break;
                case 'c':
                {
                        if (leftjust)
                            _PutChar_f(a & 0x7f);

                        if (fieldwidth > 0)
                                sysPutRepChar(fill, fieldwidth - 1);

                        if (!leftjust)
                                _PutChar_f(a & 0x7f);
                        return (f);
                }
                case 's':
                {
                        if (leftjust)
                            sysPutString((PINT8)a);

                        if (fieldwidth > strlen((PINT8)a))
                                sysPutRepChar(fill, fieldwidth - strlen((PINT8)a));

                        if (!leftjust)
                               sysPutString((PINT8)a);
                        return (f);
                }
                case 'd':
                case 'i':
                        radix = -10;
                break;
                case 'u':
                        radix = 10;
                break;
                case 'x':
                        radix = 16;
                break;
                case 'X':
                        radix = 16;
                break;
                case 'o':
                        radix = 8;
                break;
                default:
                        radix = 3;
                break;      /* unknown switch! */
            }
        if (radix)
            break;
    }

    if (leftjust)
            fieldwidth = -fieldwidth;

    sysPutNumber(a, radix, fieldwidth, fill);

    return (f);
}


VOID sysPrintf(PINT8 pcStr,...)
{
    WB_UART_T uart;
    INT8  *argP;
    
    vaStart(argP, pcStr);       /* point at the end of the format string */
    while (*pcStr)
    {                       /* this works because args are all ints */
            if (*pcStr == '%')
                pcStr = FormatItem(pcStr + 1, vaArg(argP, INT));
            else
                _PutChar_f(*pcStr++);
    }
}


VOID sysprintf(PINT8 pcStr,...)
{
#if 1
    WB_UART_T uart;
    INT8  *argP;


    vaStart(argP, pcStr);       /* point at the end of the format string */
    while (*pcStr)
    {                       /* this works because args are all ints */
        if (*pcStr == '%')
                pcStr = FormatItem(pcStr + 1, vaArg(argP, INT));
        else
                _PutChar_f(*pcStr++);
    }
#endif
}


INT8 sysGetChar()
{
    while (1)
    {
        if (inpw(REG_UART_ISR+u32UartPort) & 0x01)        
            return (inpb(REG_UART_RBR+u32UartPort));    
    }
}

INT8 sysGetChar_NoBlocking(void)
{
//    while (1)
    {
        if (inpw(REG_UART_ISR+u32UartPort) & 0x01)        
            return (inpb(REG_UART_RBR+u32UartPort));    
        else
            return 0xFF;
    }
}

VOID sysPutChar(UINT8 ucCh)
{
    /* Wait until the transmitter buffer is empty */        
        while (!(inpw(REG_UART_FSR+u32UartPort) & 0x400000));
    /* Transmit the character */
        outpb(REG_UART_THR+u32UartPort, ucCh);     
}

void sysUartTransfer(char* pu8buf, UINT32 u32Len)
{
    do
    {
        if( (inp32(REG_UART_FSR+u32UartPort) & Tx_Full) ==0 ) {
            outpb(REG_UART_THR+u32UartPort, *pu8buf++);
            u32Len = u32Len-1;
        }
    }while(u32Len!=0) ;
}
//=========================================================================
static void UartPort(UINT32 u32Port)
{
    sysUartPort(u32Port);
}    

static INT32 UartInitialize(WB_UART_T *uart)
{
    INT32 i32ErrCode;
    i32ErrCode = sysInitializeUART(uart);
    return i32ErrCode;
}
static void UartEnableInt(INT32 eIntType)
{
    sysUartEnableInt(eIntType);
}

static void UartTransfer(char* pu8buf, UINT32 u32Len)
{
    sysUartTransfer( pu8buf, u32Len);
}
static VOID UartPutChar(UINT8 ucCh)
{
    sysPutChar(ucCh);
}
static INT8 UartGetChar(void)
{
    INT8 i8Data;
    i8Data = sysGetChar();
    return i8Data;
}

INT8 UartGetChar_NoBlocking()
{
//    while (1)
    {
        if (inpw(REG_UART_ISR+u32UartPort) & 0x01)        
            return (inpb(REG_UART_RBR+u32UartPort));    
        else
            return 0xFF;            
    }
}

static UINT32 UartGetRecCount() {
     return (inpw(REG_UART_FSR+u32UartPort) & Rx_Pointer) >> 8;
}
static UINT32 UartGetIntStatus() {

     UINT status =inpb(REG_UART_ISR+u32UartPort);
     UINT mask =inpb(REG_UART_IER+u32UartPort);
     UINT interrupt = status & mask;

     return interrupt;
}

static void UartDisableInt(INT32 eIntType) {

    if(eIntType == UART_INT_RDA)
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) & ~RDA_IEN);
    else if (eIntType == UART_INT_RDTO)    
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) & ~RTO_IEN & ~Time_out_EN);
    else if (eIntType == UART_INT_THRE) 
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) & ~THRE_IEN);
    else if (eIntType == UART_INT_NONE)        
        outp32(REG_UART_IER+u32UartPort, 0x0);
}
static BOOL UartCheckTxStatus(INT32 type) {
    return (inpw(REG_UART_FSR+u32UartPort) & type);
}
static void UartPutDataInReg(UINT8 data) {
    outpb(REG_UART_THR+u32UartPort, data);
}
#if 0
static void Uartprintf(PINT8 pcStr,...)
{
    sysprintf(pcStr,...);
}

static void sysPrintf(PINT8 pcStr,...)
{

}
#endif
UARTDEV_T nvt_uart1 =
{
    UartPort,
    UartInitialize,
    UartEnableInt,
    UartTransfer,
    UartPutChar,
    UartGetChar,
    UartGetChar_NoBlocking,    
    UartGetRecCount,
    UartGetIntStatus,
    UartDisableInt,
    UartCheckTxStatus,
    UartPutDataInReg,
#if 0            
    Uartprintf,
    UartPrintf,
#endif    
};


wb_uart0.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                         *
 * Copyright (c) 2008 Nuvoton Technolog. All rights reserved.              *
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
* FILENAME
*   wb_uart.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The UART related function of Nuvoton ARM9 MCU
*
* HISTORY
*   2008-06-25  Ver 1.0 draft by Min-Nan Cheng
*
* REMARK
*   None
 **************************************************************************/
#include <string.h>
#include <stdio.h>
#include "wblib.h"

#ifdef    __HW_SIM__
#undef     REG_UART_THR                       
#define    REG_UART_THR      (0xFFF04400)        // TUBE ON
#endif


#define vaStart(list, param) list = (INT8*)((INT)&param + sizeof(param))
#define vaArg(list, type) ((type *)(list += sizeof(type)))[-1]

/* Global variables */
static BOOL volatile _sys_bIsUARTInitial = FALSE;
static BOOL volatile _sys_bIsUseUARTInt = TRUE;
static UINT32 _sys_uUARTClockRate = EXTERNAL_CRYSTAL_CLOCK;
//UINT32 UART_BA = UART0_BA;

#define RX_ARRAY_NUM 100
static UINT8 uart_rx[RX_ARRAY_NUM] = {0};

VOID _PutChar_f0(UINT8 ucCh);
static UINT32 volatile rx_cnt = 0;

#define sysTxBufReadNextOne()    (((_sys_uUartTxHead+1)==UART_BUFFSIZE)? NULL: _sys_uUartTxHead+1)
#define sysTxBufWriteNextOne()    (((_sys_uUartTxTail+1)==UART_BUFFSIZE)? NULL: _sys_uUartTxTail+1)
#define UART_BUFFSIZE    256
static UINT8 _sys_ucUartTxBuf[UART_BUFFSIZE];
static UINT32 volatile _sys_uUartTxHead, _sys_uUartTxTail;
static PVOID  _sys_pvOldUartVect;
static UINT32 u32UartPort =0x0; /* High Speed UART */


static INT32 i32UsedPort = 0;
static void sysUartPort0(UINT32 u32Port)
{
    u32UartPort = (u32Port & 0x1)*0x100;
    if(u32Port==0)
    {//High Speed UART        
        outp32(REG_CLKDIV3, (inp32(REG_CLKDIV3) & (~0xFF)));
        outp32(REG_GPDFUN, (inp32(REG_GPDFUN) & ~(MF_GPD2 | MF_GPD1)) | (0x5<<2) );
        outp32(REG_APBCLK, inp32(REG_APBCLK) | UART0_CKE);    
    }
    else if(u32Port==1)
    {//Nornal Speed UART
        outp32(REG_CLKDIV3, (inp32(REG_CLKDIV3) & (~0xFF00)));
        outp32(REG_GPAFUN, inp32(REG_GPAFUN) | (MF_GPA11 | MF_GPA10));
        outp32(REG_APBCLK, inp32(REG_APBCLK) | UART1_CKE);
    }
    i32UsedPort = u32Port;
}
static VOID sysSetBaudRate(UINT32 uBaudRate)
{
    UINT32 _mBaudValue;

    /* First, compute the baudrate divisor. */
#if 0        
    // mode 0
    _mBaudValue = (_sys_uUARTClockRate / (uBaudRate * 16));
    if ((_sys_uUARTClockRate % (uBaudRate * 16)) > ((uBaudRate * 16) / 2))
          _mBaudValue++;
    _mBaudValue -= 2;
    outpw(REG_UART_BAUD+u32UartPort, _mBaudValue);        
#else
    // mode 3
    _mBaudValue = (_sys_uUARTClockRate / uBaudRate)-2;
    outpw(REG_UART_BAUD+u32UartPort,  ((0x30<<24)| _mBaudValue));    
#endif    
}

static void sysUart0EnableInt(INT32 eIntType)
{
    if(eIntType==UART_INT_RDA)
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) |RDA_IEN);
    else if (eIntType==UART_INT_RDTO)    
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) |RTO_IEN |Time_out_EN);
    else if (eIntType==UART_INT_NONE)        
        outp32(REG_UART_IER+u32UartPort, 0x0);
}
INT32 sysInitializeUART0(WB_UART_T *uart)
{
    /* Enable UART multi-function pins*/
    //outpw(REG_PINFUN, inpw(REG_PINFUN) | 0x80);
    //outpw(REG_GPAFUN, inpw(REG_GPAFUN) | 0x00F00000);    //Normal UART pin function 
    static BOOL bIsResetFIFO = FALSE;
    /* Check the supplied parity */
    if ((uart->uiParity != WB_PARITY_NONE) &&
        (uart->uiParity != WB_PARITY_EVEN) &&
        (uart->uiParity != WB_PARITY_ODD))

            /* The supplied parity is not valid */
            return WB_INVALID_PARITY;

    /* Check the supplied number of data bits */
    else if ((uart->uiDataBits != WB_DATA_BITS_5) &&
             (uart->uiDataBits != WB_DATA_BITS_6) &&
             (uart->uiDataBits != WB_DATA_BITS_7) &&
             (uart->uiDataBits != WB_DATA_BITS_8))

            /* The supplied data bits value is not valid */
            return WB_INVALID_DATA_BITS;

    /* Check the supplied number of stop bits */
    else if ((uart->uiStopBits != WB_STOP_BITS_1) &&
             (uart->uiStopBits != WB_STOP_BITS_2))

            /* The supplied stop bits value is not valid */
            return WB_INVALID_STOP_BITS;

    /* Verify the baud rate is within acceptable range */
    else if (uart->uiBaudrate < 1200)
            /* The baud rate is out of range */
            return WB_INVALID_BAUD;

    /* Reset the TX/RX FIFOs */
    if(bIsResetFIFO==FALSE)
    {
        outpw(REG_UART_FCR+u32UartPort, 0x07);
        bIsResetFIFO=TRUE;
    }
    /* Setup reference clock */
    _sys_uUARTClockRate = uart->uiFreq;

    /* Setup baud rate */
    sysSetBaudRate(uart->uiBaudrate);

    /* Set the modem control register. Set DTR, RTS to output to LOW,
    and set INT output pin to normal operating mode */ 
    //outpb(UART_MCR, (WB_DTR_Low | WB_RTS_Low | WB_MODEM_En)); 

    /* Setup parity, data bits, and stop bits */
    outpw(REG_UART_LCR+u32UartPort,(uart->uiParity | uart->uiDataBits | uart->uiStopBits));

    /* Timeout if more than ??? bits xfer time */
    outpw(REG_UART_TOR+u32UartPort, 0x80+0x20);

    /* Setup Fifo trigger level and enable FIFO */
    outpw(REG_UART_FCR+u32UartPort, (uart->uiRxTriggerLevel << 4) | 0x01);

    /* Enable HUART interrupt Only (Receive Data Available Interrupt & RX Time out Interrupt) */
#if 0    
#if 1 //Enable RX data time out    
    outp32(REG_UART_IER+u32UartPort,inp32(REG_UART_IER+u32UartPort) |RDA_IEN |RTO_IEN |Time_out_EN);
#else    
    outp32(REG_UART_IER+u32UartPort,inp32(REG_UART_IER+u32UartPort) |RDA_IEN);
#endif    
#endif 

    /* Timeout if more than ??? bits xfer time */
    outpw(REG_UART_TOR+u32UartPort, 0x7F);

    // hook UART interrupt service routine
    if (u32UartPort)
    {//==1 NORMAL UART
        _sys_uUartTxHead = _sys_uUartTxTail = NULL;
        _sys_pvOldUartVect = sysInstallISR(IRQ_LEVEL_1, IRQ_UART, (PVOID)uart->ufun);
        sysEnableInterrupt(IRQ_UART);        
    }
    else
    {//==0 High SPEED
        _sys_uUartTxHead = _sys_uUartTxTail = NULL;
        _sys_pvOldUartVect = sysInstallISR(IRQ_LEVEL_1, IRQ_HUART, (PVOID)uart->ufun);
        sysEnableInterrupt(IRQ_HUART);
    }
    _sys_bIsUARTInitial = TRUE;

    return Successful;
}


VOID _PutChar_f0(UINT8 ucCh)
{
    if (_sys_bIsUseUARTInt == TRUE)
    {
        while(sysTxBufWriteNextOne() == _sys_uUartTxHead) ;    // buffer full

        _sys_ucUartTxBuf[_sys_uUartTxTail] = ucCh;
        _sys_uUartTxTail = sysTxBufWriteNextOne();

        if (ucCh == '\n')
        {
            while(sysTxBufWriteNextOne() == _sys_uUartTxHead) ;    // buffer full

            _sys_ucUartTxBuf[_sys_uUartTxTail] = '\r';
            _sys_uUartTxTail = sysTxBufWriteNextOne();
        }

        if (!(inpw(REG_UART_IER+u32UartPort) & 0x02))
            outpw(REG_UART_IER+u32UartPort, 0x02);
    }
    else
    {
        /* Wait until the transmitter buffer is empty */        
        while (!(inpw(REG_UART_FSR+u32UartPort) & 0x400000));
        /* Transmit the character */
        outpb(REG_UART_THR+u32UartPort, ucCh);

        if (ucCh == '\n')
        {
            /* Wait until the transmitter buffer is empty */
                while (!(inpw(REG_UART_FSR+u32UartPort) & 0x400000));
            outpb(REG_UART_THR+u32UartPort, '\r');
        }
    }
}


VOID sysPutString0(INT8 *string)
{
    while (*string != '\0')
    {
        _PutChar_f0(*string);
        string++;
    }
}


static VOID sysPutRepChar(INT8 c, INT count)
{
    while (count--)
    _PutChar_f0(c);
}


static VOID sysPutStringReverse0(INT8 *s, INT index)
{
    while ((index--) > 0)
    _PutChar_f0(s[index]);
}


static VOID sysPutNumber(INT value, INT radix, INT width, INT8 fill)
{
    INT8    buffer[40];
    INT     bi = 0;
    UINT32  uvalue;
    UINT16  digit;
    UINT16  left = FALSE;
    UINT16  negative = FALSE;

    if (fill == 0)
            fill = ' ';

    if (width < 0)
    {
        width = -width;
        left = TRUE;
    }

    if (width < 0 || width > 80)
            width = 0;

    if (radix < 0)
    {
        radix = -radix;
        if (value < 0)
        {
            negative = TRUE;
            value = -value;
            }
    }

    uvalue = value;

    do
    {
        if (radix != 16)
        {
            digit = uvalue % radix;
            uvalue = uvalue / radix;
        }
        else
        {
            digit = uvalue & 0xf;
            uvalue = uvalue >> 4;
        }
        buffer[bi] = digit + ((digit <= 9) ? '0' : ('A' - 10));
        bi++;

        if (uvalue != 0)
        {
            if ((radix == 10)
                && ((bi == 3) || (bi == 7) || (bi == 11) | (bi == 15)))
            {
                buffer[bi++] = ',';
            }
        }
    }
    while (uvalue != 0);

    if (negative)
    {
        buffer[bi] = '-';
        bi += 1;
    }

    if (width <= bi)
        sysPutStringReverse0(buffer, bi);
    else
    {
        width -= bi;
        if (!left)
            sysPutRepChar(fill, width);
        sysPutStringReverse0(buffer, bi);
        if (left)
                sysPutRepChar(fill, width);
    }
}


static INT8 *FormatItem(INT8 *f, INT a)
{
    INT8   c;
    INT    fieldwidth = 0;
    INT    leftjust = FALSE;
    INT    radix = 0;
    INT8   fill = ' ';

    if (*f == '0')
        fill = '0';

    while ((c = *f++) != 0)
    {
        if (c >= '0' && c <= '9')
        {
            fieldwidth = (fieldwidth * 10) + (c - '0');
        }
        else
            switch (c)
            {
                case '\000':
                    return (--f);
                case '%':
                        _PutChar_f0('%');
                        return (f);
                case '-':
                        leftjust = TRUE;
                        break;
                case 'c':
                {
                        if (leftjust)
                            _PutChar_f0(a & 0x7f);

                        if (fieldwidth > 0)
                                sysPutRepChar(fill, fieldwidth - 1);

                        if (!leftjust)
                                _PutChar_f0(a & 0x7f);
                        return (f);
                }
                case 's':
                {
                        if (leftjust)
                            sysPutString0((PINT8)a);

                        if (fieldwidth > strlen((PINT8)a))
                                sysPutRepChar(fill, fieldwidth - strlen((PINT8)a));

                        if (!leftjust)
                               sysPutString0((PINT8)a);
                        return (f);
                }
                case 'd':
                case 'i':
                        radix = -10;
                break;
                case 'u':
                        radix = 10;
                break;
                case 'x':
                        radix = 16;
                break;
                case 'X':
                        radix = 16;
                break;
                case 'o':
                        radix = 8;
                break;
                default:
                        radix = 3;
                break;      /* unknown switch! */
            }
        if (radix)
            break;
    }

    if (leftjust)
            fieldwidth = -fieldwidth;

    sysPutNumber(a, radix, fieldwidth, fill);

    return (f);
}


VOID sysPrintf0(PINT8 pcStr,...)
{
    WB_UART_T uart;
    INT8  *argP;

        _sys_bIsUseUARTInt = TRUE;
    if (!_sys_bIsUARTInitial)
    {
        uart.uart_no = WB_UART_0;
        uart.uiFreq = sysGetExternalClock()*1000;
        uart.uiBaudrate = 115200;
        uart.uiDataBits = WB_DATA_BITS_8;
        uart.uiStopBits = WB_STOP_BITS_1;
        uart.uiParity = WB_PARITY_NONE;
        uart.uiRxTriggerLevel = LEVEL_1_BYTE;
        sysInitializeUART(&uart);        
        }
    
    vaStart(argP, pcStr);       /* point at the end of the format string */
    while (*pcStr)
    {                       /* this works because args are all ints */
            if (*pcStr == '%')
                pcStr = FormatItem(pcStr + 1, vaArg(argP, INT));
            else
                _PutChar_f0(*pcStr++);
    }
}


VOID sysprintf0(PINT8 pcStr,...)
{
    WB_UART_T uart;
    INT8  *argP;

    _sys_bIsUseUARTInt = FALSE;
    if (!_sys_bIsUARTInitial)
    {//Default use external clock 12MHz as source clock. 
        uart.uart_no = WB_UART_0;
        uart.uiFreq = sysGetExternalClock()*1000;
        uart.uiBaudrate = 115200;
        uart.uiDataBits = WB_DATA_BITS_8;
        uart.uiStopBits = WB_STOP_BITS_1;
        uart.uiParity = WB_PARITY_NONE;
        uart.uiRxTriggerLevel = LEVEL_1_BYTE;
        sysInitializeUART(&uart);
    }

    vaStart(argP, pcStr);       /* point at the end of the format string */
    while (*pcStr)
    {                       /* this works because args are all ints */
        if (*pcStr == '%')
                pcStr = FormatItem(pcStr + 1, vaArg(argP, INT));
        else
                _PutChar_f0(*pcStr++);
    }
}


static INT8 sysGetChar0(void)
{
    while (1)
    {
        if (inpw(REG_UART_ISR+u32UartPort) & 0x01)        
            return (inpb(REG_UART_RBR+u32UartPort));    
    }
}

static INT8 sysGetChar0_NoBlocking(void)
{
//    while (1)
    {
        if (inpw(REG_UART_ISR+u32UartPort) & 0x01)        
            return (inpb(REG_UART_RBR+u32UartPort));    
        else
            return (0xFF);    
    }
}

static VOID sysPutChar0(UINT8 ucCh)
{
    /* Wait until the transmitter buffer is empty */        
        while (!(inpw(REG_UART_FSR+u32UartPort) & 0x400000));
    /* Transmit the character */
        outpb(REG_UART_THR+u32UartPort, ucCh);     
}

static void sysUartTransfer0(char* pu8buf, UINT32 u32Len)
{
    do
    {
        if( (inp32(REG_UART_FSR+u32UartPort) & Tx_Full) ==0 ) {
            outpb(REG_UART_THR+u32UartPort, *pu8buf++);
            u32Len = u32Len-1;
        }
    }while(u32Len!=0) ;
}
//=========================================================================
static void UartPort(UINT32 u32Port)
{
    sysUartPort0(u32Port);
}    

static INT32 UartInitialize(WB_UART_T *uart)
{
    INT32 i32ErrCode;
    i32ErrCode = sysInitializeUART0(uart);
    return i32ErrCode;
}
static  void UartEnableInt(INT32 eIntType)
{
    sysUart0EnableInt(eIntType);
}

static void UartTransfer(char* pu8buf, UINT32 u32Len)
{
    sysUartTransfer0( pu8buf, u32Len);
}
static VOID UartPutChar(UINT8 ucCh)
{
    sysPutChar0(ucCh);
}
static INT8 UartGetChar(void)
{
    INT8 i8Data;
    i8Data = sysGetChar0();
    return i8Data;
}
static INT8 UartGetChar_NoBlocking(void)
{
    INT8 i8Data;
    i8Data = sysGetChar0_NoBlocking();
    return i8Data;
}
static UINT32 UartGetRecCount() {
     return (inpw(REG_UART_FSR+u32UartPort) & Rx_Pointer) >> 8;
}
static UINT32 UartGetIntStatus() {
     UINT status =inpb(REG_UART_ISR+u32UartPort);
     UINT mask =inpb(REG_UART_IER+u32UartPort);
     UINT interrupt = status & mask;
     return interrupt;
}
static void UartDisableInt(INT32 eIntType) {
    if(eIntType == UART_INT_RDA)
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) & ~RDA_IEN);
    else if (eIntType == UART_INT_RDTO)    
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) & ~RTO_IEN & ~Time_out_EN);
    else if (eIntType == THRE_IEN) 
        outp32(REG_UART_IER+u32UartPort, inp32(REG_UART_IER+u32UartPort) & ~THRE_IEN);
    else if (eIntType == UART_INT_NONE)        
        outp32(REG_UART_IER+u32UartPort, 0x0);
}
#if 0
static void Uartprintf(PINT8 pcStr,...)
{
    sysprintf(pcStr,...);
}

static void sysPrintf(PINT8 pcStr,...)
{

}
#endif
UARTDEV_T nvt_uart0 =
{
    UartPort,
    UartInitialize,
    UartEnableInt,
    UartTransfer,    
    UartPutChar,
    UartGetChar,
    UartGetChar_NoBlocking,    
    UartGetRecCount,
    UartGetIntStatus,
    UartDisableInt,
#if 0            
    Uartprintf,
    UartPrintf,
#endif    
};




wb_uartdev.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#include "wblib.h"
extern UARTDEV_T nvt_uart0;
extern UARTDEV_T nvt_uart1;
INT32 register_uart_device(UINT32 u32port, UARTDEV_T* pUartDev)
{
    if(u32port==0)
        *pUartDev = nvt_uart0;
    else if(u32port==1)
        *pUartDev = nvt_uart1;
    else     
        return -1;
    return Successful;    
}


wberrcode.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/****************************************************************************
 *                                                                          *
 * Copyright (c) 2009 Nuvoton Technology. All rights reserved.              *
 *                                                                          *
 ***************************************************************************/

/****************************************************************************
 *
 * FILENAME
 *     wberrcode.h
 *
 * VERSION
 *     1.0
 *
 * DESCRIPTION
 *       The Error Codes returned by Nuvoton S/W library are defined as the following
 *     format:
 *              0xFFFFXX## (XX : Module ID, ##:Error Number)
 *
 *     The Module IDs for each S/W library are defined in this file. The error
 *     numbers are defined by S/W library according to its requirement.
 *
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *     None
 *
 * HISTORY
 *     2009-02-26  Ver 1.0 draft by Min-Nan Cheng
 * REMARK
 *     None
 **************************************************************************/
#ifndef _WBERRCODE_H_
#define _WBERRCODE_H_

/* Error Code's Module ID */
#define FMI_ERR_ID            0xFFFF0100    /* FMI library ID */
#define APU_ERR_ID            0xFFFF0200    /* Audio Processing library ID */
#define USB_ERR_ID            0xFFFF0300    /* USB Device library ID */
#define GDMA_ERR_ID            0xFFFF0400    /* GDMA library ID */
#define JPG_ERR_ID            0xFFFF0500    /* ATA library ID */
#define DMAC_ERR_ID            0xFFFF0600    /* DMA library ID */
#define TMR_ERR_ID            0xFFFF0700    /* Timer library ID */
#define GE_ERR_ID            0xFFFF0800    /* 2D graphics library ID */
#define AIC_ERR_ID            0xFFFF0900    /* AIC library ID */
#define SYSLIB_ERR_ID            0xFFFF0A00    /* System library ID */
#define USBO_ERR_ID            0xFFFF0C00    /* OHCI library ID */
#define USBH_ERR_ID            0xFFFF0D00    /* USB Host library ID */
#define RTC_ERR_ID            0xFFFF0E00    /* RTC library ID */
#define GPIO_ERR_ID            0xFFFF0F00    /* GPIO library ID */
#define VIN_ERR_ID            0xFFFF1000    /* Video-In library ID */
#define I2C_ERR_ID            0xFFFF1100    /* I2C library ID */
#define SPI_ERR_ID            0xFFFF1200    /* SPI library ID */
#define PWM_ERR_ID            0xFFFF1300    /* PWM library ID */
#define    BLT_ERR_ID            0xFFFF1500    /* BLT library ID */
#define UART_ERR_ID            0xFFFF1700    /* UART library ID */
#define LCD_ERR_ID            0xFFFF1800    /* LCD library ID */
#define ADC_ERR_ID            0xFFFF1A00    /* ADC library ID */

#define FAT_ERR_ID            0xFFFF8200    /* FAT file system library ID */


/* Macros for handing error code */
#define NVTAPI_RESULT_IS_ERROR(value)    ((value) < 0) ? 1 : 0        /* 1:error, 0:non-err */
#define NVTAPI_GET_ERROR_ID(value)    ((value) & 0x0000FF00) >> 8     /* get Module ID of error code */
#define NVTAPI_GET_ERROR_NUMBER(value)    ((value) & 0x000000FF)         /* get Error Number of error code */

/* Error Number defined by XXX library */

#endif /* _WBERRCODE_H */




wbio.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                         *
 * Copyright (c) 2009 Nuvoton Technology. All rights reserved.             *
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
 * 
 * FILENAME
 *     WBIO.h
 *
 * VERSION
 *     1.0
 *
 * DESCRIPTION
 *     This file contains I/O macros, and basic macros and inline functions.
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *     None
 *
 * HISTORY
 *     03/28/02         Ver 1.0 Created by PC30 YCHuang
 *
 * REMARK
 *     None
 **************************************************************************/

#ifndef _WBIO_H
#define _WBIO_H

#ifndef _WBTYPES_H_
#include "common.h"
#endif


#define LITTLE_ENDIAN


#define outpb(port,value)     (*((UINT8 volatile *) (port))=value)
#define inpb(port)            (*((UINT8 volatile *) (port)))
#define outphw(port,value)    (*((UINT16 volatile *) (port))=value)
#define inphw(port)           (*((UINT16 volatile *) (port)))
#define outpw(port,value)     (*((UINT32 volatile *) (port))=value)
#define inpw(port)            (*((UINT32 volatile *) (port)))

#define readb(addr)           (*(UINT8 volatile *)(addr))
#define writeb(addr,x)        ((*(UINT8 volatile *)(addr)) = (UINT8 volatile)x)
#define readhw(addr)          (*(UINT16 volatile *)(addr))
#define writehw(addr,x)       ((*(UINT16 volatile *)(addr)) = (UINT16 volatile)x)
#define readw(addr)           (*(UINT32 volatile *)(addr))
#define writew(addr,x)        ((*(UINT32 volatile *)(addr)) = (UINT32 volatile)x)

#define outp8(port,value)     (*((UINT8 volatile *) (port))=value)
#define inp8(port)            (*((UINT8 volatile *) (port)))
#define outp16(port,value)    (*((UINT16 volatile *) (port))=value)
#define inp16(port)           (*((UINT16 volatile *) (port)))
#define outp32(port,value)     (*((UINT32 volatile *) (port))=value)
#define inp32(port)            (*((UINT32 volatile *) (port)))

#define Maximum(a,b)          (a>b ? a : b)
#define Minimum(a,b)          (a<b ? a : b)
#define Middle(a,b)           ((a+b)/2)
#define Equal(a,b)            (a==b ? 1 : 0)
#define NotEqual(a,b)         (a==b ? 0 : 1)
#define GreaterEqual(a,b)     (a>=b ? 1 : 0)
#define LittleEqual(a,b)      (a<=b ? 1 : 0) 

static __inline UINT16 Swap16(UINT16 val)
{
    return (val<<8) | (val>>8);
}

static __inline UINT32 Swap32(UINT32 val)
{
    return (val<<24) | ((val<<8)&0xff0000) | ((val>>8)&0xff00) | (val>>24);
}

static __inline UINT16 Get16(PUINT8 addr)
{
#ifdef LITTLE_ENDIAN
    return ((addr[1]<<8) | addr[0]);
#else    
    return ((addr[0]<<8) | addr[1]);
#endif    
}

static __inline UINT32 Get32(PUINT8 addr)
{
#ifdef LITTLE_ENDIAN
    return (addr[3]<<24) | (addr[2]<<16) | (addr[1]<<8) | addr[0];
#else
    return (addr[0]<<24) | (addr[1]<<16) | (addr[2]<<8) | addr[3];
#endif
}

static __inline void Set16(UINT16 val, PUINT8 addr)
{
#ifdef LITTLE_ENDIAN
    addr[0] = (UINT8) val;
    addr[1] = (UINT8)(val >> 8);
#else
    addr[0] = (UINT8)(val >> 8);
    addr[1] = (UINT8) val;
#endif    
}

static __inline void Set32(UINT32 val, PUINT8 addr)
{
#ifdef LITTLE_ENDIAN
    addr[0] = (UINT8) val;
    addr[1] = (UINT8)(val >> 8);
    addr[2] = (UINT8)(val >> 16);
    addr[3] = (UINT8)(val >> 24);
#else
    addr[0] = (UINT8)(val >> 24);
    addr[1] = (UINT8)(val >> 16);
    addr[2] = (UINT8)(val >> 8);
    addr[3] = (UINT8) val & 0xff;
#endif    
}

#endif /* _WBIO_H */



wblib.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/***************************************************************************
 *                                                                         *
 * Copyright (c) 2009 Nuvoton Technology. All rights reserved.             *
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
 * 
 * FILENAME
 *     WBLIB.h
 *
 * VERSION
 *     1.1
 *
 * DESCRIPTION
 *     The header file of NUC900 system library.
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *     None
 *
 * HISTORY
 *     2008-06-26  Ver 1.0 draft by Min-Nan Cheng
 *     2009-02-26  Ver 1.1 Changed for NUC900 MCU
 *
 * REMARK
 *     None
 **************************************************************************/
#ifndef _WBLIB_H
#define _WBLIB_H

#ifdef __cplusplus
extern "C"{
#endif

//#include "NUC930_reg.h"
#include "W55FA93_reg.h"
#include "wberrcode.h"
#include "wbio.h"

//-- function return value
#define       Successful  0
#define       Fail        1

#define EXTERNAL_CRYSTAL_CLOCK  12000000


/* Define constants for use external IO in service parameters.  */
#define EXT0            0
#define EXT1            1
#define EXT2            2


#define SIZE_256K        4
#define SIZE_512K        5
#define SIZE_1M            6
#define SIZE_2M            7
#define SIZE_4M            8
#define SIZE_8M            9
#define SIZE_16M        10
#define SIZE_32M        11

#define BUS_DISABLE        12
#define BUS_BIT_8        13
#define BUS_BIT_16        14
#define BUS_BIT_32        15


/* Define the vector numbers associated with each interrupt */
typedef enum int_source_e
{
    IRQ_WDT = 1, 
    IRQ_EXTINT0 = 2, 
    IRQ_EXTINT1 = 3, 
    IRQ_EXTINT2 = 4, 
        IRQ_EXTINT3 = 5, 
       IRQ_SPU = 6, 
        IRQ_I2S = 7, 
        IRQ_VPOST = 8, 
        IRQ_VIDEOIN = 9, 
        IRQ_GPU = 10, 
        IRQ_BLT = 11, 
        IRQ_FSC = 12, 
        IRQ_HUART = 13, 
        IRQ_TMR0 = 14, 
        IRQ_TMR1 = 15, 
        IRQ_UDC = 16, 
        IRQ_SIC = 17, 
        IRQ_UHC = 18, 
        IRQ_EDMA = 19, 
        IRQ_SPIMS0 = 20, 
        IRQ_SPIMS1 = 21, 
        IRQ_ADC = 22, 
        IRQ_RTC = 23, 
        IRQ_UART = 24, 
        IRQ_PWM = 25, 
        IRQ_JPG = 26,  
        //IRQ_PWM2 = 27, 
        IRQ_KPI = 28, 
        IRQ_DES    = 29,
        IRQ_I2C = 30, 
        IRQ_PWR = 31    
} INT_SOURCE_E;

typedef enum
{
    WE_GPIO =0x01,
    WE_RTC =0x02,
    WE_SDH =0x04,
    WE_UART =0x08,
    WE_UDC =0x10,
    WE_UHC =0x20,
    WE_ADC =0x40,
    WE_KPI =0x80
}WAKEUP_SOURCE_E;

typedef struct datetime_t
{
    UINT32    year;
    UINT32    mon;
    UINT32    day;
    UINT32    hour;
    UINT32    min;
    UINT32    sec;
} DateTime_T;

/* Define constants for use timer in service parameters.  */
#define TIMER0            0
#define TIMER1            1


#define ONE_SHOT_MODE     0
#define PERIODIC_MODE     1
#define TOGGLE_MODE       2
#define UNINTERRUPT_MODE  3

#define ONE_HALF_SECS     0
#define FIVE_SECS         1
#define TEN_SECS          2
#define TWENTY_SECS       3

/* Define constants for use UART in service parameters.  */
#define WB_UART_0        0
#define WB_UART_1        1

#define WB_DATA_BITS_5    0x00
#define WB_DATA_BITS_6    0x01
#define WB_DATA_BITS_7    0x02
#define WB_DATA_BITS_8    0x03

#define WB_STOP_BITS_1    0x00
#define WB_STOP_BITS_2    0x04

#if 0 //VA91
#define WB_PARITY_NONE    0x00
#define WB_PARITY_ODD     0x00
#define WB_PARITY_EVEN    0x10
#else
#define WB_PARITY_NONE   0x00
#define WB_PARITY_ODD     0x08
#define WB_PARITY_EVEN    0x18
#endif
//#define WB_DTR_Low        0x01
//#define WB_RTS_Low        0x02
//#define WB_MODEM_En       0x08

#define LEVEL_1_BYTE          0x0    /* Normal/High speed UART */
#define LEVEL_4_BYTES        0x1
#define LEVEL_8_BYTES         0x2
#define LEVEL_14_BYTES        0x3
#define LEVEL_30_BYTES        0x4    /* High speed UART only */
#define LEVEL_46_BYTES        0x5
#define LEVEL_62_BYTES        0x6 

/* Define constants for use AIC in service parameters.  */
#define WB_SWI                     0
#define WB_D_ABORT                 1
#define WB_I_ABORT                 2
#define WB_UNDEFINE                3

/* The parameters for sysSetInterruptPriorityLevel() and 
   sysInstallISR() use */
#define FIQ_LEVEL_0                0
#define IRQ_LEVEL_1                1
#define IRQ_LEVEL_2                2
#define IRQ_LEVEL_3                3
#define IRQ_LEVEL_4                4
#define IRQ_LEVEL_5                5
#define IRQ_LEVEL_6                6
#define IRQ_LEVEL_7                7

/* The parameters for sysSetGlobalInterrupt() use */
#define ENABLE_ALL_INTERRUPTS      0
#define DISABLE_ALL_INTERRUPTS     1

/* The parameters for sysSetInterruptType() use */
#define LOW_LEVEL_SENSITIVE        0x00
#define HIGH_LEVEL_SENSITIVE       0x01
#define NEGATIVE_EDGE_TRIGGER   0x02
#define POSITIVE_EDGE_TRIGGER    0x03

/* The parameters for sysSetLocalInterrupt() use */
#define ENABLE_IRQ                 0x7F
#define ENABLE_FIQ                 0xBF
#define ENABLE_FIQ_IRQ          0x3F
#define DISABLE_IRQ                0x80
#define DISABLE_FIQ                0x40
#define DISABLE_FIQ_IRQ         0xC0

/* Define Cache type  */
#define CACHE_WRITE_BACK        0
#define CACHE_WRITE_THROUGH    1
#define CACHE_DISABLE            -1

#define MMU_DIRECT_MAPPING    0
#define MMU_INVERSE_MAPPING    1


/* Define Error Code */
#define E_ERR_CLK            (SYS_BA+0x01)

/* Define system clock come from */
typedef enum 
{
    eSYS_EXT     = 0,
    eSYS_X32K     = 1,
    eSYS_APLL      = 2,
    eSYS_UPLL      = 3
}E_SYS_SRC_CLK;

/* Define constants for use Cache in service parameters.  */
#define CACHE_4M        2
#define CACHE_8M        3
#define CACHE_16M        4
#define CACHE_32M        5
#define I_CACHE        6
#define D_CACHE        7
#define I_D_CACHE        8


/* Define UART initialization data structure */
typedef struct UART_INIT_STRUCT
{
    UINT32        uart_no;
        UINT32        uiFreq;
        UINT32        uiBaudrate;
        UINT8        uiDataBits;
        UINT8        uiStopBits;
        UINT8        uiParity;
        UINT8        uiRxTriggerLevel;
        VOID        (*ufun)();       
}WB_UART_T;

//extern UINT32 UART_BA;

/* UART return value */
#define WB_INVALID_PARITY           -1
#define WB_INVALID_DATA_BITS        -2
#define WB_INVALID_STOP_BITS        -3
#define WB_INVALID_BAUD             -4


#if 0
/* Define PLL initialization data structure */
typedef struct PLL_INIT_STRUCT
{
    UINT32        pll0;        /* PLL0 output frequency */
    UINT32        cpu_src;    /* Select CPU clock from PLL0 or PLL1 */
    UINT32        ahb_clk;    /* the ratio of CPU : AHB clock */
    UINT32        apb_clk;    /* the ratio of AHB : APB clock */
    UINT32        pll_off_clkskew;
    UINT32        pll_on_clkskew;        /* clock skew of SDRAM timing */
    UINT32        pll_off_refresh;    /* SDRAM refresh count value */
    UINT32        pll_on_refresh;
} WB_PLL_T;


/* Define PLL freq. setting */
#define PLL_DISABLE    0x14F27
#define    PLL_80MHZ    0xFF01  //user defined
#define    PLL_96MHZ    0x3F67 
#define PLL_132MHZ    0x2B27 
#define    PLL_192MHZ    0x3F47 
#define    PLL_200MHZ    0x4227 
#define    PLL_201MHZ    0x2087 
#define    PLL_240MHZ    0x4F47 
#define PLL_336MHZ    0x3707

/* Define CPU clock source */
#define CPU_FROM_PLL0            0
#define CPU_FROM_EXTERNAL        1
#define CPU_FROM_SYS32K            2

/* Define AHB clock */
#define    AHB_CPUCLK_1_1    0
#define    AHB_CPUCLK_1_2    1
#define    AHB_CPUCLK_1_4    2
#define    AHB_CPUCLK_1_8    3

/* Define APB clock */
#define APB_AHB_1_1        0
#define APB_AHB_1_2        1
#define APB_AHB_1_4        2
#define APB_AHB_1_8        3
 
/* Define to get clock freq. */
typedef struct CLK_FREQ_STRUCT
{
    INT32        pll_clk_freq;    /* PLL output frequency, MHz */
    INT32        cpu_clk_freq;    /* CPU frequency, MHz */
    INT32        ahb_clk_freq;    /* the ratio of CPU : AHB clock */
    INT32        apb_clk_freq;    /* the ratio of AHB : APB clock */
} WB_CLKFREQ_T;
#endif

/* Define the constant values of PM */
#define WB_PM_IDLE        1
#define WB_PM_PD            2
#define WB_PM_MIDLE            5

/* Define Wake up source */ 
#define    WAKEUP_GPIO     0
#define    WAKEUP_RTC         1
#define    WAKEUP_SDH      2
#define    WAKEUP_UART      3
#define    WAKEUP_UDC      4
#define    WAKEUP_UHC      5
#define    WAKEUP_ADC      6
#define    WAKEUP_KPI      7

#define WB_PM_PD_IRQ_Fail            -1
#define WB_PM_Type_Fail                    -2
#define WB_PM_INVALID_IRQ_NUM        -3
#define WB_PM_CACHE_OFF            -4


#define PD_RAM_BASE        0xFF000000
#define PD_RAM_START    0xFF001000
#define PD_RAM_SIZE        0x2000
/* Define system library Timer functions */
UINT32 sysGetTicks (INT32 nTimeNo);
INT32 sysResetTicks (INT32 nTimeNo);
INT32 sysUpdateTickCount(INT32 nTimeNo, 
                    UINT32 uCount);
INT32 sysSetTimerReferenceClock (INT32 nTimeNo, 
                            UINT32 uClockRate);
INT32 sysStartTimer (INT32 nTimeNo, 
                    UINT32 uTicksPerSecond, 
                    INT32 nOpMode);
INT32 sysStopTimer (INT32 nTimeNo);
INT32 sysSetTimerEvent(INT32 nTimeNo, 
            UINT32 uTimeTick, 
            PVOID pvFun);
VOID    sysClearTimerEvent(INT32 nTimeNo, 
                UINT32 uTimeEventNo);
void    sysSetLocalTime(DateTime_T ltime);
VOID    sysGetCurrentTime(DateTime_T *curTime);
VOID    sysDelay(UINT32 uTicks);


VOID    sysClearWatchDogTimerCount (void);
VOID    sysClearWatchDogTimerInterruptStatus(void);
VOID    sysDisableWatchDogTimer (void);
VOID    sysDisableWatchDogTimerReset(void);
VOID    sysEnableWatchDogTimer (void);
VOID    sysEnableWatchDogTimerReset(void);

PVOID sysInstallWatchDogTimerISR (INT32 nIntTypeLevel, 
                PVOID pvNewISR);
INT32 sysSetWatchDogTimerInterval (INT32 nWdtInterval);


/* Define system library UART functions */
#define UART_INT_RDA        1
#define UART_INT_RDTO        2
#define UART_INT_THRE        3
#define UART_INT_TX            4    
#define UART_INT_NONE        255

typedef void (*PFN_SYS_UART_CALLBACK)(
                UINT8* u8Buf,     
                UINT32 u32Len);
                
void         sysUartPort(UINT32 u32Port);
INT8        sysGetChar (void);
INT32    sysInitializeUART (WB_UART_T *uart);
VOID        sysPrintf (PINT8 pcStr,...);
VOID        sysprintf (PINT8 pcStr,...);
VOID        sysPutChar (UINT8 ucCh);
INT8    sysGetChar_NoBlocking(void);
VOID sysUartEnableDebugMessage(BOOL bIsDebugMessage);

void         sysUartEnableInt(INT32 eIntType);
void         sysUartTransfer(char* pu8buf, UINT32 u32Len);

/* Define system library AIC functions */
INT32     sysDisableInterrupt (INT_SOURCE_E eIntNo);
INT32     sysEnableInterrupt (INT_SOURCE_E eIntNo);
BOOL     sysGetIBitState(void);
UINT32     sysGetInterruptEnableStatus(void);
PVOID     sysInstallExceptionHandler (INT32 nExceptType, 
                                PVOID pvNewHandler);
PVOID     sysInstallFiqHandler (PVOID pvNewISR);
PVOID     sysInstallIrqHandler (PVOID pvNewISR);
PVOID     sysInstallISR (INT32 nIntTypeLevel, 
                INT_SOURCE_E eIntNo, 
                PVOID pvNewISR);
INT32     sysSetGlobalInterrupt (INT32 nIntState);
INT32     sysSetInterruptPriorityLevel (INT_SOURCE_E eIntNo, 
                            UINT32 uIntLevel);
INT32     sysSetInterruptType (INT_SOURCE_E eIntNo, 
                        UINT32 uIntSourceType);
INT32     sysSetLocalInterrupt (INT32 nIntState);
INT32     sysSetAIC2SWMode(void);


/* Define system library Cache functions */
VOID     sysDisableCache(void);
INT32 sysEnableCache(UINT32 uCacheOpMode);
VOID     sysFlushCache(INT32 nCacheType);
BOOL sysGetCacheState(void);
INT32 sysGetSdramSizebyMB(void);
VOID    sysInvalidCache(void);
INT32 sysSetCachePages(UINT32 addr, 
                    INT32 size, 
                    INT32 cache_mode);


/* Define system clock functions */
#if 0
INT32 sysGetPLLConfig(WB_PLL_T *sysClk);
INT32 sysSetPLLConfig(WB_PLL_T *sysClk);
INT32 sysGetClockFreq(WB_CLKFREQ_T *sysFreq);
#endif
UINT32 sysGetPLLOutputKhz(E_SYS_SRC_CLK eSysPll, UINT32 u32FinKHz);


/* Define system power management functions */
VOID sysDisableAllPM_IRQ(void);
INT sysEnablePM_IRQ(INT irq_no);
INT sysPMStart(INT pd_type);
INT32 sysPowerDown(WAKEUP_SOURCE_E eWakeUpSrc);


//void sysSetClock(void);
void sysExternalClock(void);
UINT32 sysGetExternalClock(void);
CHAR sysGetChipVersion(void);
//void sysFirstAdjustAPLL(UINT32 u32ApllClockKHz);
UINT32 
sysSetSystemClock(E_SYS_SRC_CLK eSrcClk,    
                UINT32 u32PllKHz,     
                UINT32 u32SysKHz,
                UINT32 u32CpuKHz,
                UINT32 u32HclkKHz,
                UINT32 u32ApbKHz);
UINT32 sysSetCPUClock(UINT32 u32CPUClockKHz);
UINT32 sysGetCPUClock(VOID);
UINT32 sysSetAPBClock(UINT32 u32APBlockKHz);
UINT32 sysGetAPBClock(VOID);
    
void sysGetSystemClock(E_SYS_SRC_CLK* eSrcClk,
                     PUINT32 pu32PllKHz,    
                    PUINT32 pu32SysKHz,
                    PUINT32 pu32CpuKHz,
                    PUINT32 pu32HclkKHz,
                    PUINT32 pu32ApbKHz);        
                    
INT32 sysClockDivSwitchStart(UINT32 u32SysDiv);
void sysCheckPllConstraint(BOOL bIsCheck);
INT32 sysPowerDownPLL(E_SYS_SRC_CLK eSrcClk, BOOL bIsPowerDown);
void sysPowerDownPLLDuringSysPowerDown(BOOL bIsPowerDownPLL);

/* Support two UART Port */
typedef struct
{
    void (*UartPort)(UINT32 u32Port);
    INT32 (*UartInitialize)(WB_UART_T *uart);
    void (*UartEnableInt)(INT32 eIntType);
    void (*UartTransfer)(char* pu8buf, UINT32 u32Len);
    VOID (*UartPutChar)(UINT8 ucCh);
    INT8 (*UartGetChar)(void);
    INT8 (*UartGetChar_NoBlocking)(void);    
    UINT32 (*UartGetRecCount)(void);
    UINT32 (*UartGetIntStatus)(void);
    void   (*UartDisableInt)(INT32 eIntType);
    BOOL   (*UartCheckTxStatus)(INT32 type);
    void (*UartPutDataInReg)(UINT8 data);
}UARTDEV_T;
extern UARTDEV_T nvt_uart0;

extern UARTDEV_T nvt_uart1;
INT32 register_uart_device(UINT32 u32port, UARTDEV_T* pUartDev);

#ifdef __cplusplus
}
#endif

#endif  /* _WBLIB_H */





wbtypes.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/****************************************************************************
 *                                                                          *
 * Copyright (c) 2009 Nuvoton Technology. All rights reserved.              *
 *                                                                          *
 ***************************************************************************/
 
/****************************************************************************
 * 
 * FILENAME
 *     wbtypes.h
 *
 * VERSION
 *     1.0
 *
 * DESCRIPTION
 *     This file contains PreDefined data types for NUC900 software development
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *     None
 *
 * HISTORY
 *     03/11/02         Ver 1.0 Created by PC30 YCHuang
 *
 * REMARK
 *     None
 **************************************************************************/

#ifndef _WBTYPES_H
#define _WBTYPES_H

#if 0
/* Nuvoton NUC930 coding standard draft 2.0 */
/* wbtypes.h Release 1.0 */

#define CONST             const

#define FALSE             0
#define TRUE              1

typedef void              VOID;
typedef void *            PVOID;

typedef char              BOOL;
typedef char *            PBOOL;

typedef char              INT8;
typedef char              CHAR;
typedef char *            PINT8;
typedef char *            PCHAR;
typedef unsigned char     UINT8;
typedef unsigned char     UCHAR;
typedef unsigned char *   PUINT8;
typedef unsigned char *   PUCHAR;
typedef char *            PSTR;
typedef const char *      PCSTR;

typedef short             SHORT;
typedef short *           PSHORT;
typedef unsigned short    USHORT;
typedef unsigned short *  PUSHORT;

typedef short             INT16;
typedef short *           PINT16;
typedef unsigned short    UINT16;
typedef unsigned short *  PUINT16;

typedef int               INT;
typedef int *             PINT;
typedef unsigned int      UINT;
typedef unsigned int *    PUINT;

typedef int               INT32;
typedef int *             PINT32;
typedef unsigned int      UINT32;
typedef unsigned int *    PUINT32;

typedef __int64           INT64;
typedef unsigned __int64  UINT64;

typedef float             FLOAT;
typedef float *           PFLOAT;

typedef double            DOUBLE;
typedef double *          PDOUBLE;

typedef int               SIZE_T;

typedef unsigned char     REG8;
typedef unsigned short    REG16;
typedef unsigned int      REG32;
#endif
#endif /* _WBTYPES_H */

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值