⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 board.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
字号:
/*   The content of this file or document is CONFIDENTIAL and PROPRIETARY
*   to Jade Technologies Co., Ltd.  It is subjected to the terms of a
*   License Agreement between Licensee and Jade Technologies Co., Ltd.
*   restricting among other things, the use, reproduction, distribution
*   and transfer.  Each of the embodiments, including this information 
*   and any derivative work shall retain this copyright notice.
* 
*   Copyright (c) 2004 - 2005 Jade Technologies Co., Ltd. 
*   All rights reserved.tent permitted
 * by a licensing agreement from ARM Limited.
 * ----------------------------------------------------------------
 * File:     board.c,v
 * Revision: 1.0
 * ----------------------------------------------------------------
 * $
 */

#include <windows.h>
#include <nkintr.h>
#include <oalfuncs.h>
#include <oalintr.h>
#include "win_plat.h" /* This includes platform.h */
#include <pl190.h>  // VIC and SIC
#include <sp804.h>  // timers
//#include <apcharlcd.h>

/* OS_TIMER increment for 1 ms clock time */
DWORD OEMCount1ms;

/* system tick frequency */
unsigned long OEMClockFreq;     /* OEM clock frequency is used only in OAL */

/* counts per reschedule */
extern DWORD dwReschedIncrement;
extern ULONG LogIntrOpenStatus[LOGINTR_MAX];
// Internal fucntion
//void apCHARLCD_Write(unsigned char dat, unsigned char rs);

/* Codes for hexadecimal characters */
//static unsigned int alpha_codes[] =
//{
//    0x007E, 0x080C, 0x01B6, 0x011E, 0x01CC, 0x01DA, 0x01FA, 0x2802,
//    0x01FE, 0x01CE, 0x01EE, 0x01F8, 0x0072, 0x01BC, 0x00F2, 0x00E2
//};

/* Data structure used for timer-related information */
typedef struct uHALis_Timer
{
    pvstTimerRegs pt;               /* timer registers */
    DWORD irq;                      /* IRQ number */
} SoftTimer_t;

/* Array timer data */
SoftTimer_t gSysTimers[] = {
    { (pvstTimerRegs)(VA_CT_BASE + TIMER0_OFFSET), LOGINTR_TIMER0 },
    { (pvstTimerRegs)(VA_CT_BASE + TIMER1_OFFSET), LOGINTR_TIMER1 }
};

static int Irq2Vic[] = 
{
	-1,
	/*LOGINTR_WDOG     	*/	0	,
	/*LOGINTR_SOFTINT   */  1   ,
	/*LOGINTR_CPUINT0   */  2   ,
	/*LOGINTR_CPUINT1   */  3   ,
	/*LOGINTR_TIMER0    */  4   ,
	/*LOGINTR_TIMER1    */  5   ,
	/*LOGINTR_IIC       */  7   ,
	/*LOGINTR_CF        */  8   ,
	/*LOGINTR_RTC       */  9   ,
	/*LOGINTR_USB       */  10  ,
	/*LOGINTR_UART0		*/	11	,
	/*LOGINTR_UART1		*/	12	,
	/*LOGINTR_UART2		*/	13	,
	/*LOGINTR_UART3		*/	14	,
	/*LOGINTR_SD0		*/	14	,
	/*LOGINTR_FIRI	    */  14  ,
	/*LOGINTR_SCI       */  15  ,
	/*LOGINTR_CLCD1     */  16  ,
	/*LOGINTR_SD1       */  16  ,
	/*LOGINTR_DMA       */  17  ,
	/*LOGINTR_PWRFAIL   */  18  ,
	/*LOGINTR_SSP0      */  19  ,
	/*LOGINTR_IIS       */  19  ,
	/*LOGINTR_KBD       */  22  ,
	/*LOGINTR_AUDIO     */  23  ,
	/*LOGINTR_SSP1      */  23  ,
	/*LOGINTR_CLCD0     */  24  ,
	/*LOGINTR_DMA23     */  26  ,
	/*LOGINTR_VIA       */  27  ,
	/*LOGINTR_MP4D      */  28  ,
	/*LOGINTR_MP4E      */  29  ,
	/*LOGINTR_EXTINT0	*/	30	,
	/*LOGINTR_EXTINT1   */  31  
};
static int Vic2Irq[][4] = 
{
/*0 */	{ LOGINTR_WDOG    , -1 , -1 , -1 				   } ,
/*1 */  { LOGINTR_SOFTINT , -1 , -1 , -1                   } ,
/*2 */  { LOGINTR_CPUINT0 , -1 , -1 , -1                   } ,
/*3 */  { LOGINTR_CPUINT1 , -1 , -1 , -1                   } ,
/*4 */  { LOGINTR_TIMER0  , -1 , -1 , -1                   } ,
/*5 */  { LOGINTR_TIMER1  , -1 , -1 , -1                   } ,
/*6 */  { -1 , -1 , -1 , -1 ,                              } ,
/*7 */	{ LOGINTR_IIC     , -1 , -1 , -1                   } ,
/*8 */  { LOGINTR_CF      , -1 , -1 , -1                   } ,
/*9 */  { LOGINTR_RTC     , -1 , -1 , -1                   } ,
/*10*/  { LOGINTR_USB     , -1 , -1 , -1                   } ,
/*11*/  { LOGINTR_UART0	, -1 , -1 , -1                     } ,
/*12*/  { LOGINTR_UART1	, -1 , -1 , -1                     } ,
/*13*/  { LOGINTR_UART2	, -1 , -1 , -1                     } ,
/*14*/  { LOGINTR_UART3 , LOGINTR_SD0	, LOGINTR_FIRI , -1} ,
/*15*/  { LOGINTR_SCI		, -1 , -1 , -1                 } ,
/*16*/  { LOGINTR_CLCD1 , LOGINTR_SD1 , -1 , -1            } ,
/*17*/  { LOGINTR_DMA	  	, -1 , -1 , -1                 } ,
/*18*/  { LOGINTR_PWRFAIL , -1 , -1 , -1                   } ,
/*19*/  { LOGINTR_SSP0  , LOGINTR_IIS , -1 , -1            } ,
/*20*/  { -1 , -1 , -1 , -1                                } ,
/*21*/  { -1 , -1 , -1 , -1                                } ,
/*22*/  { LOGINTR_KBD   , -1 , -1 , -1                     } ,
/*23*/  { LOGINTR_AUDIO , LOGINTR_SSP1 , -1 , -1           } ,
/*24*/  { LOGINTR_CLCD0 , -1 , -1 , -1                     } ,
/*25*/  { -1 , -1 , -1 , -1                                } ,
/*26*/  { LOGINTR_DMA23, -1 , -1 , -1                      } ,
/*27*/  { LOGINTR_VIA  , -1 , -1 , -1                      } ,
/*28*/  { LOGINTR_MP4D , -1 , -1 , -1                      } ,
/*29*/  { LOGINTR_MP4E , -1 , -1 , -1                      } ,
/*30*/  { LOGINTR_EXTINT0, -1 , -1 , -1                    } ,
/*31*/  { LOGINTR_EXTINT1, -1 , -1 , -1                    } ,

};
// Z228 Development Board- we must take into account the VIC 
// and the Z228 Development Board's secondary interrupt controller.
void pHALir_DisableIrq(DWORD irq)
{   
    pvstVICRegs     pVic;
    
	pVic = (pvstVICRegs)(VA_VIC_BASE);
    
    if( irq >MAXLOGINTR || irq < 1 )
    {
    	DEBUGMSG(1, (TEXT("ERROR: attempt to DISABLE a not exist irq!\r\n"))); 
    	return;
    }
    
    pVic->IntEnClear = (1 << Irq2Vic[irq]);
    return;
}

void pHALir_DisableVic(DWORD irq)
{
    pvstVICRegs     pVic;	
	
    pVic = (pvstVICRegs)(VA_VIC_BASE);
    
    if( irq >MAXLOGINTR || irq < 1 )
    {
    	DEBUGMSG(1, (TEXT("ERROR: attempt to DISABLE a not exist irq!\r\n"))); 
    	return;
    }
    pVic->IntEnClear = (1 << Irq2Vic[irq]);
    return;
}
// Z228 Development Board - we must take into account the VIC 
// and the Z228 Development Board's secondary interrupt controller.
void pHALir_EnableIrq(DWORD irq)
{
    pvstVICRegs     pVic;
	
    pVic = (pvstVICRegs)(VA_VIC_BASE);
    
    if( irq >MAXLOGINTR || irq < 1 )
    {
    	RETAILMSG(1, (TEXT("ERROR: attempt to DISABLE a not exist irq!\r\n"))); 
    	return;
    }
    
    pVic->IntEnable = (1 << Irq2Vic[irq] );
}


/* Returns TRUE if the timer has generated an interrupt */
BOOL pHALir_HasTimerInterrupt(DWORD timer)
{
    pvstTimerRegs pTimer = gSysTimers[timer].pt;
    return (pTimer->MaskedInterruptStatus);
}

/* Returns TRUE if the timer can generate an interrupt */
BOOL pHALir_TimerInterruptEnabled(DWORD timer)
{
    pvstTimerRegs pTimer = gSysTimers[timer].pt;
    return (pTimer->Control & TimerControlEnable);
}

/* Enables the interrupt for the timer */
void pHALir_EnableTimerInterrupt(DWORD timer)
{
    pvstTimerRegs pTimer = gSysTimers[timer].pt;
    pTimer->Control |= TimerControlIntEnable;
}

/* Disables the interrupt for the timer */
void pHALir_DisableTimerInterrupt(DWORD timer)
{
    pvstTimerRegs pTimer = gSysTimers[timer].pt;
    pTimer->Control &= ~TimerControlIntEnable;
}

/* Clears the Timer interrupt */
void pHALir_ClearTimerInterrupt(DWORD timer)
{
    pvstTimerRegs pTimer = gSysTimers[timer].pt;

    /* clear the interrupt (if any) */
    pTimer->InterruptClear = 1;
}

/* This routine stops the specified timer hardware. */
void uHALir_DisableTimer(DWORD timer)
{
    pvstTimerRegs pTimer = gSysTimers[timer].pt;

    /* Clear control register to disable timer */
    pTimer->Control = 0;

    /* clear the interrupt (if any) */
    pTimer->InterruptClear = 1;

    /* Disable at VIC */ 
    pHALir_DisableIrq(gSysTimers[timer].irq);
}

/* Start-up routine to initialise the timers to a known state */
void uHALr_InitTimers(void)
{
    DWORD i;

    for (i = 0; i < NUMSYSTIMERS; i++) 
    {
        uHALir_DisableTimer(i);
    }
}

/* set a timer to a specific tick count */
void SetSysTimerInterval(DWORD dwTicks)
{
    pvstTimerRegs pTimer = gSysTimers[OS_TIMER].pt;
    
    pTimer->Control =  0;
    /* program the new timer value */
    pTimer->Load = dwTicks;

    /* Set up timer control register */
    pTimer->Control = TimerControlPeriodic | TimerControlEnable | 
                      TimerControlIntEnable | TimerControlSize32;

    /* Enable at IC */
    pHALir_EnableIrq(gSysTimers[OS_TIMER].irq);
}

/* Put the CPU into a low-power state.  
** If none is available, loop on a flag that gets set by ISRs. 
*/
void  CPUEnterIdle(DWORD dwIdleParam)
{

    /* Wait For Interrupt */
    WFI();

}

/* determine the maximum delay for a given request within the limits of 
** the hardware 
*/
DWORD CPUGetSysTimerCountMax(DWORD dwIdleMSecRequested)
{
    if (dwIdleMSecRequested > IDLE_MAX_MS) 
    {
        /*
        ** Our timer isn't capable of idling more than IDLE_MAX_MS milliseconds. 
        ** We'll have to break the sleep time into reasonable chunks.
        */
        return IDLE_MAX_MS;
    }
    
    return dwIdleMSecRequested;
}

/* set the new period for the timer */
void  CPUSetSysTimerCount(DWORD dwIdleMSec)
{
    DWORD dwTicks;

    /* determine the number of ticks required for the number of milliseconds 
     * requested 
     */
    dwTicks = dwIdleMSec * RESCHED_INCREMENT;
    
    /* program the new timer value */
    SetSysTimerInterval(dwTicks);
}

/* return TRUE if a timer IRQ was pending, false otherwise.  
** Clear the interrupt if pending. 
*/
BOOL CPUClearSysTimerIRQ(void)
{
    BOOL fPending;

    /* This is the base address for the ADK timer block */
    pvstTimerRegs pTimer = gSysTimers[OS_TIMER].pt;

    /* Check if OS_TIMER interrupt is set */
    if(((pTimer->RawInterruptStatus) & 0x1) != 0)
    {
        pHALir_ClearTimerInterrupt(OS_TIMER);
        fPending = TRUE;
    } 
    else 
    {
        fPending = FALSE;
    }
    
    return fPending;
}



DWORD
CPUGetSysTimerCountElapsed(
                           DWORD dwTimerCountdownMSec,
                           volatile DWORD *pCurMSec,
                           DWORD *pPartialCurMSec,
                           volatile ULARGE_INTEGER *pCurTicks
                           )
{
    pvstTimerRegs pTimer = gSysTimers[OS_TIMER].pt;
    DWORD dwTick = dwTimerCountdownMSec * OEMCount1ms;
    DWORD dwCount;
    
    /* If timer IRQ pending, a full resched period elapsed */
    if (CPUClearSysTimerIRQ( )) 
    {
        *pCurMSec += dwTimerCountdownMSec;
        pCurTicks->QuadPart += dwTick;
        return dwTimerCountdownMSec;
    }
    
    /* No timer IRQ pending, calculate how much time has elapsed */
    dwCount = pTimer->Value;
    if (dwCount > dwTick) 
    {
        /* This is an error case.  Recover gracefully. */
        RETAILMSG(1, (L"CPUGetSysTimerCountElapsed( ): Correcting periodic timer read error\r\n"));
        dwCount = dwTick;
    } 
    else 
    {
        dwCount = dwTick - dwCount;
    }
    
    pCurTicks->QuadPart += dwCount;
    
    dwCount += *pPartialCurMSec;
    *pPartialCurMSec = dwCount % OEMCount1ms;
    *pCurMSec += (dwCount /= OEMCount1ms);
    
    return dwCount;
}

DWORD PerfCountFreq()
{
    return(OEMClockFreq);
}

// NOTE: This only returns the clock value, since the last tick, which may 
//  have happened before this call and the tick you were checking
DWORD PerfCountSinceTick()
{
    pvstTimerRegs pTimer = gSysTimers[OS_TIMER].pt;

    return dwReschedIncrement - pTimer->Value;
}


/* EOF board.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -