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

📄 syslib.c

📁 ARM7开发板 AT91EB01 BSP源代码
💻 C
字号:
/* sysLib.c - Atmel AT91EB01 Evaluation Board system-dependent routines */

/* Copyright 1999 ARM Limited */

/*
modification history
--------------------
01a,26aug99,jpd  sysHwInit2(): remove NOMANUAL, protect from being called twice;
		 conditionally add declaration of sysCacheLibInit.
01a,29jun99,jpd  written.
*/



/* includes */

#include "vxWorks.h"
#include "config.h"

#include "sysLib.h"
#include "string.h"
#include "intLib.h"
#include "taskLib.h"
#include "vxLib.h"
#include "at91Timer.h"
#include "plx9056.h"
#include "rs422.h"



/* imports */

IMPORT char end [];			    /* end of system, created by ld */
IMPORT VOIDFUNCPTR _func_armIntStackSplit;  /* ptr to fn to split stack */


#if ((CPU == ARMARCH4) || (CPU == ARMARCH4_T))
#if defined(INCLUDE_CACHE_SUPPORT)
FUNCPTR	sysCacheLibInit = NULL;
#endif
#endif /* ((CPU == ARMARCH4) || (CPU == ARMARCH4_T)) */

int	sysBus	    = BUS;		/* system bus type (VME_BUS, etc) */
int	sysCpu	    = CPU;		/* system CPU type (ARMARCH4/4_T) */
char *	sysBootLine = BOOT_LINE_ADRS; 	/* address of boot line */
char *	sysExcMsg   = EXC_MSG_ADRS;	/* catastrophic message area */
int	sysProcNum;			/* processor number of this CPU */
int	sysFlags;			/* boot flags */
char	sysBootHost [BOOT_FIELD_LEN];	/* name of host from which we booted */
char	sysBootFile [BOOT_FIELD_LEN];	/* name of file from which we booted */


/* locals */

#ifdef AT91_INT_SOFT_PRIORITY_MAP

/*
 * List of interrupts to be serviced in order of decreasing priority.
 * Interrupts not in this list will be serviced least-significant bit
 * first at a lower priority than those in the list.
 *
 * To use lowest-bit = highest-priority, reverse the sense of the
 * condition below so that at91IntLvlPriMap is a zero pointer.
 */

#if TRUE
LOCAL int at91IntLvlPriMap[] =
{
    INT_LVL_USART_1,
    INT_LVL_USART_0,
    SYS_TIMER_INT_LVL,          /* sysClk */
    AUX_TIMER_INT_LVL,	    	/* auxClk */
    INT_LVL_EXT_0,              /* External interrupt 0 */
    INT_LVL_EXT_1,              /* External interrupt 1 */
    INT_LVL_EXT_2,              /* External interrupt 2 */
    INT_LVL_EXT_3,              /* External interrupt 3 */
    INT_LVL_EXT_4,              /* External interrupt 4 */
    INT_LVL_EXT_5,              /* External interrupt 5 */
    -1			            	/* list terminator */
};
#else
LOCAL int *at91IntLvlPriMap = 0;
#endif


#else
/*
 * This array maps interrupt levels to mask patterns.  The interrupt level
 * is the index, the data is the mask value.  A mask bit enables one
 * level.  The mask value is 'and'd with the at91IntLvlEnabled value
 * before writing to the chip.
 */

LOCAL UINT32 at91IntLvlMask[AT91_INT_NUM_LEVELS + 1] = /* int level mask */
        {
	0x0000, /* level 0, all disabled */
	0x0001, 0x0003, 0x0007, 0x000f,
	0x001f
#if (AT91_INT_NUM_LEVELS == 19)
	, 0x003f, 0x007f, 0x00ff,
	0x01ff, 0x03ff, 0x07ff, 0x0fff,
	0x1fff, 0x3fff, 0x7fff, 0xffff,
	0x1ffff, 0x3ffff, 0x7ffff /* level 19, all enabled */
#endif /* (AT91_INT_NUM_LEVELS == 19) */
	};

#if ((AT91_INT_NUM_LEVELS != 19) && (AT91_INT_NUM_LEVELS != 6))
#   error at91IntLvlMask is wrong size for number of levels
#endif
#endif	/* ifdef AT91_INT_SOFT_PRIORITY_MAP */


/* defines */


/* externals */

IMPORT int  at91IntDevInit (void);
IMPORT void sysIntStackSplit (char *, long);


/* globals */


/* forward LOCAL functions declarations */


/* forward declarations */

char *	sysPhysMemTop (void);


/* included source files */

#ifdef INCLUDE_FLASH
#include "nvRamToFlash.c"
#include "mem/flashMem.c"
#else
#include "mem/nullNvRam.c"
#endif
#include "vme/nullVme.c"
#include "sysSerial.c"
#include "at91Timer.c"
#include "at91IntrCtl.c"
#include "ExtInt.c"


/*******************************************************************************
*
* sysModel - return the model name of the CPU board
*
* This routine returns the model name of the CPU board.
*
* RETURNS: A pointer to a string identifying the board and CPU.
*/

char *sysModel (void)
    {
#if	(ARM_THUMB)
    return	"Atmel AT91EB01 (Thumb)";
#else
    return	"Atmel AT91EB01 (ARM)";
#endif
    }

/*******************************************************************************
*
* sysBspRev - return the BSP version with the revision eg 1.2/<x>
*
* This function returns a pointer to a BSP version with the revision,
* e.g. 1.2/<x>. BSP_REV is concatenated to BSP_VERSION to form the
* BSP identification string.
*
* RETURNS: A pointer to the BSP version/revision string.
*/

char * sysBspRev (void)
    {
    return (BSP_VERSION BSP_REV);
    }

/*******************************************************************************
*
* sysHwInit - initialize the CPU board hardware
*
* This routine initializes various features of the hardware.
* Normally, it is called from usrInit() in usrConfig.c.
*
* NOTE: This routine should not be called directly by the user.
*
* RETURNS: N/A
*/

void sysHwInit (void)
    {
    /* install the IRQ/SVC interrupt stack splitting routine */

    _func_armIntStackSplit = sysIntStackSplit;

    /* initialize the plx9056 and u2 */
    PCI_VME_HwInit();

	/* initialize the RS422 */
    rs422_drv();

    /* disable watchdog timer */
    AT91EB01_REG_WRITE (AT91_WDT_OMR, (0x234 << 4));


    /* initialise C/T Block Mode Register: nothing connected to XC0-2 */
    AT91EB01_REG_WRITE (AT91_TIMER_BMR, ((1 << 0) | (1 << 2) | (1 << 4)));


#ifdef INCLUDE_SERIAL
    /*
     * Configure the two data pins for each of the two serial ports to be
     * connected to the peripheral (i.e. connected to the USARTs rather than
     * general-purpose PIO).  Leave the others as PIO.
     */

/*
    AT91EB01_REG_WRITE (AT91_PIO_PER, 0x019F3FFF);
    AT91EB01_REG_WRITE (AT91_PIO_PDR, 0xFE60C000);
*/
    /* initialise the serial devices */

    sysSerialHwInit ();      /* initialise serial data structure */

#endif /* INCLUDE_SERIAL */

    return;
    }

/*******************************************************************************
*
* sysHwInit2 - additional system configuration and initialization
*
* This routine connects system interrupts and does any additional
* configuration necessary. Note that this routine is called from
* sysClkConnect() in the timer driver.
*
* RETURNS: N/A
*
*/

void sysHwInit2 (void)
    {
    static BOOL configured = FALSE;

    if (!configured)
    	{
	/* initialise the interrupt library and interrupt driver */

	intLibInit (AT91_INT_NUM_LEVELS, AT91_INT_NUM_LEVELS, INT_MODE);
	at91IntDevInit();


	/* configure timer interrupt polarities and types */

	at91IntLvlConfigure (SYS_TIMER_INT_LVL,
			     AT91_INT_POLARITY_NEGATIVE |
			     AT91_INT_TYPE_EDGE);

	at91IntLvlConfigure (AUX_TIMER_INT_LVL,
			     AT91_INT_POLARITY_NEGATIVE |
			     AT91_INT_TYPE_EDGE);


	/* connect sys clock interrupt and auxiliary clock interrupt */

	(void)intConnect (INUM_TO_IVEC (SYS_TIMER_INT_VEC), sysClkInt, 0);
	(void)intConnect (INUM_TO_IVEC (AUX_TIMER_INT_VEC), sysAuxClkInt, 0);


	/* configure extern interrupt 0-5 polarities and types */
	
	at91IntLvlConfigure (INT_LVL_EXT_0,
			     AT91_INT_POLARITY_NEGATIVE |
			     AT91_INT_TYPE_EDGE);

	at91IntLvlConfigure (INT_LVL_EXT_1,
			     AT91_INT_POLARITY_POSITIVE |
			     AT91_INT_TYPE_EDGE);

    at91IntLvlConfigure (INT_LVL_EXT_2,
			     AT91_INT_POLARITY_POSITIVE |
			     AT91_INT_TYPE_EDGE);

    at91IntLvlConfigure (INT_LVL_EXT_3,
			     AT91_INT_POLARITY_POSITIVE |
			     AT91_INT_TYPE_EDGE);

    at91IntLvlConfigure (INT_LVL_EXT_4,
			     AT91_INT_POLARITY_POSITIVE |
			     AT91_INT_TYPE_EDGE);

    at91IntLvlConfigure (INT_LVL_EXT_5,
			     AT91_INT_POLARITY_NEGATIVE |
			     AT91_INT_TYPE_EDGE);


	/* connect extern interrupt 0-5 */

	(void)intConnect (INUM_TO_IVEC (INT_VEC_EXT_0), ExtInt0, 0);
	(void)intConnect (INUM_TO_IVEC (INT_VEC_EXT_1), ExtInt1, 0);
    (void)intConnect (INUM_TO_IVEC (INT_VEC_EXT_2), ExtInt2, 0);
	(void)intConnect (INUM_TO_IVEC (INT_VEC_EXT_3), ExtInt3, 0);
    (void)intConnect (INUM_TO_IVEC (INT_VEC_EXT_4), ExtInt4, 0);
    (void)intConnect (INUM_TO_IVEC (INT_VEC_EXT_5), ExtInt5, 0);


#ifdef INCLUDE_SERIAL
	/* configure serial interrupt polarities and types */

	at91IntLvlConfigure (INT_LVL_USART_0,
			     AT91_INT_POLARITY_NEGATIVE |
			     AT91_INT_TYPE_LEVEL);

	at91IntLvlConfigure (INT_LVL_USART_1,
			     AT91_INT_POLARITY_NEGATIVE |
			     AT91_INT_TYPE_LEVEL);

	/* connect serial interrupt */
	sysSerialHwInit2();

#endif /* INCLUDE_SERIAL */

	configured = TRUE;

    at91IntLvlEnable(INT_LVL_EXT_0);
    at91IntLvlEnable(INT_LVL_EXT_1);
    at91IntLvlEnable(INT_LVL_EXT_2);
    at91IntLvlEnable(INT_LVL_EXT_3);
    at91IntLvlEnable(INT_LVL_EXT_4);
    at91IntLvlEnable(INT_LVL_EXT_5);


	} /* endif !configured */

    return;
    }

/*******************************************************************************
*
* sysPhysMemTop - get the address of the top of physical memory
*
* This routine returns the address of the first missing byte of memory,
* which indicates the top of memory.
*
* Normally, the user specifies the amount of physical memory with the
* macro LOCAL_MEM_SIZE in config.h.  BSPs that support run-time
* memory sizing do so only if the macro LOCAL_MEM_AUTOSIZE is defined.
* If not defined, then LOCAL_MEM_SIZE is assumed to be, and must be, the
* true size of physical memory.
*
* NOTE: Do not adjust LOCAL_MEM_SIZE to reserve memory for application
* use.  See sysMemTop() for more information on reserving memory.
*
* NOTE: Normal BSPs have LOCAL_MEM_SIZE of RAM fitted from 0
* (LOCAL_MEM_LOCAL_ADRS) upwards. We have LOCAL_MEM_LOCAL_ADRS set to 0
* (where the vectors are), and some on-chip RAM from there upwards.
* However, the off-chip RAM cannot be mapped contiguously from the end of
* the on-chip RAM, and is mapped from a higher address from
* AT91EB01_OFF_CHIP_RAM_BASE_ADRS upwards.
*
* RETURNS: The address of the top of physical memory.
*
* SEE ALSO: sysMemTop()
*/

char * sysPhysMemTop (void)
    {
    static char * physTop = NULL;

    if (physTop == NULL)
	{
#ifdef LOCAL_MEM_AUTOSIZE

	/* If auto-sizing is possible, this would be the spot.  */

#	error   "Dynamic memory sizing not supported"

#else
	/*
	 * Don't do autosizing, if size is given.
	 *
	 * Fix top at end of on-chip SRAM, which comes after the two
	 * banks of off-chip SRAM, on the expansion board.
	 */

	physTop = (char *)(AT91EB01_OFF_CHIP_RAM_BASE_ADRS + LOCAL_MEM_SIZE);

#endif /* LOCAL_MEM_AUTOSIZE */
	}

    return physTop;
    }

/*******************************************************************************
*
* sysMemTop - get the address of the top of VxWorks memory
*
* This routine returns a pointer to the first byte of memory not
* controlled or used by VxWorks.
*
* The user can reserve memory space by defining the macro USER_RESERVED_MEM
* in config.h.  This routine returns the address of the reserved memory
* area.  The value of USER_RESERVED_MEM is in bytes.
*
* RETURNS: The address of the top of VxWorks memory.
*/

char * sysMemTop (void)
    {
    static char * memTop = NULL;

    if (memTop == NULL)
	{
	memTop = sysPhysMemTop () - USER_RESERVED_MEM;
	}

    return memTop;
    }

/*******************************************************************************
*
* sysToMonitor - transfer control to the ROM monitor
*
* This routine transfers control to the ROM monitor.  It is usually called
* only by reboot() -- which services ^X -- and bus errors at interrupt
* level.  However, in some circumstances, the user may wish to introduce a
* new <startType> to enable special boot ROM facilities.
*
* NOTE
* This routine transfers control to the VxWorks boot ROM image in the
* expansion card Flash ROM, it does not reenter the initial ROM that is
* entered on reset which then passes control to the expansion card
* Flash ROM.
*
* RETURNS: Does not return.
*/

STATUS sysToMonitor
    (
    int startType	/* passed to ROM to tell it how to boot */
    )
    {
    FUNCPTR	pRom;
    UINT32 *	p = (UINT32 *)ROM_TEXT_ADRS;

#ifdef INCLUDE_SERIAL
    sysSerialReset ();	/* put serial devices into quiet state */
#endif

    /*
     * Examine ROM - if it's a VxWorks boot ROM, jump to the warm boot entry
     * point; otherwise jump to the start of the ROM.
     * A VxWorks boot ROM begins
     *    MOV	R0,#BOOT_COLD
     *    B	...
     *    DCB	"Copyright"
     * We check the first and third words only. This could be tightened up
     * if required (see romInit.s).
     */

    if (p[0] == 0xE3A00002 && p[2] == 0x79706F43)
	pRom = (FUNCPTR)(ROM_TEXT_ADRS + 4);	/* warm boot address */
    else
	pRom = (FUNCPTR)ROM_TEXT_ADRS;		/* start of ROM */


    (*pRom)(startType);	/* jump to boot ROM */

    return OK;		/* in case we ever continue from ROM monitor */
    }

/****************************************************************************
*
* sysProcNumGet - get the processor number
*
* This routine returns the processor number for the CPU board, which is
* set with sysProcNumSet().
*
* RETURNS: The processor number for the CPU board.
*
* SEE ALSO: sysProcNumSet()
*/

int sysProcNumGet (void)
    {
    return 0;
    }

/****************************************************************************
*
* sysProcNumSet - set the processor number
*
* Set the processor number for the CPU board.  Processor numbers should be
* unique on a single backplane.
*
* NOTE
* By convention, only processor 0 should dual-port its memory.
*
* RETURNS: N/A
*
* SEE ALSO: sysProcNumGet()
*/

void sysProcNumSet
    (
    int procNum		/* processor number */
    )
    {
    sysProcNum = procNum;
    }


#ifdef INCLUDE_FLASH
/******************************************************************************
*
* sysFlashBoardDelay - create a delay
*
* This routine is needed by flashMem.c to produce specified delays.
*
* RETURNS: N/A
*/

void sysFlashBoardDelay (void)
    {
    volatile UINT32 p;

    /* Read from Flash ROM, a known timing */

    p = *(volatile UINT32 *)ROM_TEXT_ADRS;

    return;
    }
#endif /* INCLUDE_FLASH */

⌨️ 快捷键说明

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