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

📄 board.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
/* -*-C-*-
 *
 * $Revision: 1.5 $
 *   $Author: kwelton $
 *     $Date: 2000/08/08 21:45:52 $
 *
 * board.c - Integrator-specific C code
 *
 * Copyright (c) ARM Limited 1998-2000
 * All Rights Reserved.
 */

#include <windows.h>
#include <nkintr.h>
#include "mmu_h.h"
#include "win_plat.h"

 /* 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
};

/* Pre-MMU: Write the given pattern to the alpha LEDs */
void ARMSetAlpha(DWORD value)
{
    volatile DWORD  *AlphaBank = (DWORD *)INTEGRATOR_DBG_ALPHA;

    /*
     * Poll the scan in progress bit
     *
     * If the H/W is in the process of writing to the LED's then writing
     * to the control register will screw things up
     */
    while (*(volatile DWORD *)AlphaBank & 1)
        ;

    *AlphaBank = value;
}

void ARMWriteAlpha(DWORD value)
{
    ARMSetAlpha(alpha_codes[(value & 0x0F)] |
                ((alpha_codes[((value & 0xF0) >> 4)]) << 14));
}

/* Write the given pattern to the alpha LEDs */
void pHALir_SetAlpha(DWORD value)
{
    volatile DWORD  *AlphaBank =
        (DWORD *)(VA_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET);

    /*
     * Poll the scan in progress bit
     */
    while (*(volatile DWORD *)AlphaBank & 1)
        ;

    *AlphaBank = value;
}

/* Convert the given value into the Alpha LED bit pattern */
void pHALr_WriteAlpha(DWORD value)
{
    pHALir_SetAlpha(alpha_codes[(value & 0x0F)] |
                    ((alpha_codes[((value & 0xF0) >> 4)]) << 14));
}

/* Pre-MMU: Initialise the LED(s) to given value - usually 0 */
int ARMSetLEDs(DWORD value)
{
    volatile DWORD  *LedBank = (DWORD *)LED_BANK;

    /*
     * Poll the scan in progress bit
     */
    while (*(volatile DWORD *)INTEGRATOR_DBG_ALPHA & 1)
       ;

    *LedBank = value;

    /* Return the number of LEDs in the system */
    return (uHAL_NUM_OF_LEDS);
}

/* Set the state of the specified LED */
DWORD pHALr_SetLEDs(DWORD value)
{
    DWORD            mask = 0;
    DWORD            VAOffset = (VA_DBG_BASE - INTEGRATOR_DBG_BASE);
    volatile DWORD  *LedBank = (DWORD *)(VAOffset + LED_BANK);
    volatile DWORD  *LedActive = (DWORD *)(VAOffset + INTEGRATOR_DBG_ALPHA);

#ifdef OldCode
    if (value & 1)
        mask |= GREEN_LED;
    if (value & 2)
        mask |= YELLOW_LED;
    if (value & 4)
        mask |= RED_LED;
    if (value & 8)
        mask |= GREEN_LED_2;
#else /* OldCode */
    mask |= (value & ALL_LEDS);
#endif /* OldCode */

    /*
     * Poll the scan in progress bit
     */
    while (*LedActive & 1)
        ;

    *LedBank = mask;

    return (uHAL_NUM_OF_LEDS);
}

/*
 * Update the register on the target which masks the irq passed to the CPU.
 * This routine is target-specific.  Turn the interrupt source off.
 */
void pHALir_DisableIrq(DWORD irq)
{
    LONG header_number;
    volatile LONG *IRQBase;
    volatile LONG *pHDRnum =
        (volatile LONG *)(VA_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET);

    header_number = *pHDRnum & 3;
    IRQBase = (LONG *)(VA_IC_BASE + (header_number << 8));

    IRQBase[(IRQ_ENABLE_CLEAR >> 2)] = (1 << irq);
}

/*
 * Update the register on the target which masks the irq passed to the CPU.
 * This routine is target-specific.  Turn the interrupt source on.
 */
void pHALir_EnableIrq(DWORD irq)
{
    LONG header_number;
    volatile LONG *IRQBase;
    volatile LONG *pHDRnum =
        (volatile LONG *)(VA_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET);

    header_number = *pHDRnum & 3;
    IRQBase = (LONG *)(VA_IC_BASE + (header_number << 8));

    IRQBase[(IRQ_ENABLE_SET >> 2)] = (1 << irq);
}

/*
 * routine:     uHALr_PCIHost()
 *
 * parameters:  void
 *
 * description: This routine determines if the target is PCI Host.
 *
 * calls:       none
 *
 * returns:     FALSE if not PCI Host
 *
 */
DWORD uHALr_PCIHost(void)
{
#if uHAL_PCI != 0
    return (TRUE);
#else
    return (FALSE);
#endif
}

/*
 * Integrator Timer register definitions.
 *
 * Integrator has 2 fixed rate timers.
 */
typedef struct TimerStruct
{
    unsigned short TimerLoad;
    unsigned char pad0[2];
    unsigned short TimerValue;
    unsigned char pad1[2];
    unsigned char TimerControl;
    unsigned char pad2[3];
    unsigned char TimerClear;
} TimerStruct_t;

TimerStruct_t *TimerBase[] =
{
    0,
    (TimerStruct_t *)(VA_CT_BASE + TIMER1_OFFSET),
    (TimerStruct_t *)(VA_CT_BASE + TIMER2_OFFSET)
};

#ifdef OldCode
TimerStruct_t *PreMMU_TimerBase[] =
{
    0,
    (TimerStruct_t *)INTEGRATOR_TIMER1_BASE,
    (TimerStruct_t *)INTEGRATOR_TIMER2_BASE
};
#endif /* def OldCode */

DWORD TimerInterrupts[] = TIMER_VECTORS;

/* Enum to describe timer: free, one-shot, on-going interval or locked-out */
enum uHALe_TimerState
{
    T_FREE,
    T_ONESHOT,
    T_INTERVAL,
    T_LOCKED
};

typedef struct uHALis_Timer
{
    DWORD irq;                                  /* IRQ number */
    enum uHALe_TimerState state;
    DWORD period;                               /* Period between triggers */
    const BYTE *name;                           /* Debug, owner id */
    struct uHALis_Timer *next;
    /* Flag set if HW supports interval timers */
    DWORD hw_interval:1;
} SoftTimer_t;

struct uHALis_Timer uHALiv_TimerStatus[MAX_TIMER + 1];

#define CLOCK_DIV_256   0x08
#define CLOCK_DIV_16    0x04
#define CLOCK_ENABLE    0x80
#define CLOCK_PERIODIC  0x40

void pHALir_ClearTimerInterrupt(DWORD timer)
{
    volatile TimerStruct_t  *Timer = TimerBase[timer];

    /* clear the interrupt (if any) */
    Timer->TimerClear = 1;
}

/* This routine stops the specified timer hardware. */
void uHALir_DisableTimer(DWORD timer)
{
    volatile TimerStruct_t  *Timer = TimerBase[timer];
    struct uHALis_Timer     *action;

    /* Clear control register to disable timer */
    Timer->TimerControl = 0;

    /* clear the interrupt (if any) */
    Timer->TimerClear = 1;

    action = &uHALiv_TimerStatus[timer];
    action->state = T_FREE;
}

/*
 * This routine stores the interval for the given timer. NOTE: The actual
 * timer count is not altered.
 *
 * Returns:     -1 if timer is out of range
 *              OK otherwise
 */
DWORD uHALr_SetTimerInterval(DWORD timer, DWORD interval)
{
    struct uHALis_Timer *action;

    if (timer == 0 || timer > MAX_TIMER)
        return 0;

    if (interval > MAX_PERIOD)
        return 0;

    action = &uHALiv_TimerStatus[timer];
    action->period = interval;

    /*
     * Force a H/W interval timer to be re-enabled next
     * time it goes off so that it picks up this change.
     */
    action->hw_interval = 0;

    return (interval);
}

/*
 * Routine to initialise install requested timer. Stops the timer.
 */
DWORD uHALir_InitTimer(DWORD timer, const BYTE *devname)
{
    struct uHALis_Timer *action;

    if (timer == 0 || timer > MAX_TIMER)
        return 0;

    uHALir_DisableTimer(timer);

    action = &uHALiv_TimerStatus[timer];
    action->state = T_INTERVAL;                 /* Default to interval timer */
    action->name = devname;
    action->irq = TimerInterrupts[timer];       /* IRQ number */
    action->next = 0;
    action->hw_interval = 0;
    pHALir_DisableIrq(action->irq);

    return timer;
}

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

    for (i = 1; i <= MAX_TIMER; i++)
    {
        uHALir_DisableTimer(i);
        /* Default time period is 25 mS */
        uHALr_SetTimerInterval(i, mSEC_1);
    }
}

DWORD uHALr_RequestTimer(DWORD timer, const BYTE *devname)
{
    if (uHALiv_TimerStatus[timer].state != T_FREE)
        return 0;

    return (uHALir_InitTimer(timer, devname));
}

/* This routine starts the specified timer hardware. */
void pHALr_EnableTimer(DWORD timer)
{
    SoftTimer_t *action = &uHALiv_TimerStatus[timer];
    volatile TimerStruct_t *Timer = TimerBase[timer];
    DWORD ticks;
    BYTE control = 0;

    /* clear the interrupt (if any) */
    Timer->TimerClear = 1;

    /*
     * Period is in usec.
     * Calculate the number of ticks required.
     */
    ticks = action->period * TICKS_PER_uSEC;

    if (ticks >= 0x100000)
    {
        ticks >>= 8;                    /* Divide by 256 */
        control = CLOCK_DIV_256;
    }
    else if (ticks >= 0x10000)
    {
        ticks >>= 4;                    /* Divide by 16 */
        control = CLOCK_DIV_16;
    }

    control |= CLOCK_ENABLE;

    /* set its count */
    Timer->TimerLoad = (unsigned short)ticks;

    if (action->state == T_INTERVAL)
    {
        /* H/W supports interval timer operation */
        action->hw_interval = 1;
        control |= CLOCK_PERIODIC;
    }

    Timer->TimerControl = control;
    pHALir_EnableIrq(action->irq);
}

// Routine which calculates number of mSeconds left before OS_TIMER expires
DWORD HAL_mSecsLeft(void)
{
    SoftTimer_t *action = &uHALiv_TimerStatus[OS_TIMER];
    volatile TimerStruct_t *Timer = TimerBase[OS_TIMER];
    DWORD ticks, count;

    // Period is in usec. Calculate the number of ticks required.
    ticks = action->period * TICKS_PER_uSEC;

    // Read the count and scale up if required
    count = Timer->TimerValue;

    if (ticks >= 0x100000)
        count <<= 8;                    /* Divided by 256 */
    else if (ticks >= 0x10000)
        count <<= 4;                    /* Divided by 16 */

    // mS gone = start - count (converted from ticks)
    return (ticks - count) / (TICKS_PER_uSEC * mSEC_1);
}

// Routine which calculates number of uSeconds left before OS_TIMER expires
DWORD HAL_uSecsLeft(void)
{
    SoftTimer_t *action = &uHALiv_TimerStatus[OS_TIMER];
    volatile TimerStruct_t  *Timer = TimerBase[OS_TIMER];
    DWORD ticks, count;

    // Period is in usec. Calculate the number of ticks required.
    ticks = action->period * TICKS_PER_uSEC;

    // Read the count and scale up if required
    count = Timer->TimerValue;

    if (ticks >= 0x100000)
        count <<= 8;                    /* Divided by 256 */
    else if (ticks >= 0x10000)
        count <<= 4;                    /* Divided by 16 */

    // uS gone = start - count (converted from ticks)
    return ((ticks - count) / TICKS_PER_uSEC);
}

/* EOF board.c */

⌨️ 快捷键说明

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