Recreated MicroBlaze example using Vivado 2016.1 - the Microblaze project is still a work in progress - not yet fully functional.
parent
501be60574
commit
fedb98c5f6
@ -0,0 +1,28 @@
|
||||
COMPILER=
|
||||
ARCHIVER=
|
||||
CP=cp
|
||||
COMPILER_FLAGS=
|
||||
EXTRA_COMPILER_FLAGS=
|
||||
LIB=libxil.a
|
||||
LEVEL=0
|
||||
|
||||
RELEASEDIR=../../../lib
|
||||
INCLUDEDIR=../../../include
|
||||
INCLUDES=-I./. -I${INCLUDEDIR}
|
||||
|
||||
INCLUDEFILES=*.h
|
||||
LIBSOURCES=*.c
|
||||
|
||||
OUTS = *.o
|
||||
|
||||
libs:
|
||||
echo "Compiling intc"
|
||||
$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES)
|
||||
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS}
|
||||
make clean
|
||||
|
||||
include:
|
||||
${CP} $(INCLUDEFILES) $(INCLUDEDIR)
|
||||
|
||||
clean:
|
||||
rm -rf ${OUTS}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,371 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xintc.h
|
||||
* @addtogroup intc_v3_4
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* The Xilinx interrupt controller driver component. This component supports the
|
||||
* Xilinx interrupt controller.
|
||||
*
|
||||
* The interrupt controller driver uses the idea of priority for the various
|
||||
* handlers. Priority is an integer within the range of 0 and 31 inclusive with
|
||||
* 0 being the highest priority interrupt source.
|
||||
*
|
||||
* The Xilinx interrupt controller supports the following features:
|
||||
*
|
||||
* - specific individual interrupt enabling/disabling
|
||||
* - specific individual interrupt acknowledging
|
||||
* - attaching specific callback function to handle interrupt source
|
||||
* - master enable/disable
|
||||
* - single callback per interrupt or all pending interrupts handled for
|
||||
* each interrupt of the processor
|
||||
*
|
||||
* The acknowledgement of the interrupt within the interrupt controller is
|
||||
* selectable, either prior to the device's handler being called or after
|
||||
* the handler is called. This is necessary to support interrupt signal inputs
|
||||
* which are either edge or level signals. Edge driven interrupt signals
|
||||
* require that the interrupt is acknowledged prior to the interrupt being
|
||||
* serviced in order to prevent the loss of interrupts which are occurring
|
||||
* extremely close together. A level driven interrupt input signal requires
|
||||
* the interrupt to acknowledged after servicing the interrupt to ensure that
|
||||
* the interrupt only generates a single interrupt condition.
|
||||
*
|
||||
* Details about connecting the interrupt handler of the driver are contained
|
||||
* in the source file specific to interrupt processing, xintc_intr.c.
|
||||
*
|
||||
* This driver is intended to be RTOS and processor independent. It works with
|
||||
* physical addresses only. Any needs for dynamic memory management, threads
|
||||
* or thread mutual exclusion, virtual memory, or cache control must be
|
||||
* satisfied by the layer above this driver.
|
||||
*
|
||||
* <b>Interrupt Vector Tables</b>
|
||||
*
|
||||
* The interrupt vector table for each interrupt controller device is declared
|
||||
* statically in xintc_g.c within the configuration data for each instance.
|
||||
* The device ID of the interrupt controller device is used by the driver as a
|
||||
* direct index into the configuration data table - to retrieve the vector table
|
||||
* for an instance of the interrupt controller. The user should populate the
|
||||
* vector table with handlers and callbacks at run-time using the XIntc_Connect()
|
||||
* and XIntc_Disconnect() functions.
|
||||
*
|
||||
* Each vector table entry corresponds to a device that can generate an
|
||||
* interrupt. Each entry contains an interrupt handler function and an argument
|
||||
* to be passed to the handler when an interrupt occurs. The tools default this
|
||||
* argument to the base address of the interrupting device. Note that the
|
||||
* device driver interrupt handlers given in this file do not take a base
|
||||
* address as an argument, but instead take a pointer to the driver instance.
|
||||
* This means that although the table is created statically, the user must still
|
||||
* use XIntc_Connect() when the interrupt handler takes an argument other than
|
||||
* the base address. This is only to say that the existence of the static vector
|
||||
* tables should not mislead the user into thinking they no longer need to
|
||||
* register/connect interrupt handlers with this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a ecm 08/16/01 First release
|
||||
* 1.00a rpm 01/09/02 Removed the AckLocation argument from XIntc_Connect().
|
||||
* This information is now internal in xintc_g.c.
|
||||
* 1.00b jhl 02/13/02 Repartitioned the driver for smaller files
|
||||
* 1.00b jhl 04/24/02 Made LookupConfig function global and relocated config
|
||||
* data type
|
||||
* 1.00c rpm 10/17/03 New release. Support the static vector table created
|
||||
* in the xintc_g.c configuration table. Moved vector
|
||||
* table and options out of instance structure and into
|
||||
* the configuration table.
|
||||
* 1.10c mta 03/21/07 Updated to new coding style
|
||||
* 1.11a sv 11/21/07 Updated driver to support access through a DCR bridge
|
||||
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs and _m is removed from
|
||||
* all the macro names/definitions.
|
||||
* 2.01a sdm 04/27/10 Updated the tcl so that the defintions are generated in
|
||||
* the xparameters.h to know whether the optional registers
|
||||
* SIE, CIE and IVR are enabled in the HW - Refer CR 555392.
|
||||
* This driver doesnot make use of these definitions and does
|
||||
* not use the optional registers.
|
||||
* 2.03a hvm 05/24/11 Updated the tcl to generate vector Ids for external
|
||||
* interrupts. CR565336
|
||||
* 2.04a bss 01/13/12 Added XIntc_ConnectFastHandler API for Fast Interrupt
|
||||
* and XIntc_SetNormalIntrMode for setting to normal
|
||||
* interrupt mode.
|
||||
* 2.04a asa 03/19/12 Changed the XIntc_Config struct. The order of entries
|
||||
* declared in the structure now matches with the
|
||||
* XIntc_ConfigTable generated by the driver tcl.
|
||||
* 2.05a bss 08/16/12 Updated to support relocatable vectors in Microblaze,
|
||||
* added IntVectorAddr to XIntc_Config for this.
|
||||
* Added XIntc_RegisterFastHandler API to register fast
|
||||
* interrupt handlers using base address.
|
||||
* 2.06a bss 01/28/13 To support Cascade mode:
|
||||
* Added XIN_INTC_NOCASCADE,XIN_INTC_PRIMARY,
|
||||
* XIN_INTC_SECONDARY,XIN_INTC_LAST and
|
||||
* XIN_CONTROLLER_MAX_INTRS macros
|
||||
* Added NumberofIntrs and IntcType fields in XIntc_Config
|
||||
* structure.
|
||||
* Modified XIntc_Initialize,XIntc_Start,XIntc_Connect
|
||||
* XIntc_Disconnect,XIntc_Enable,XIntc_Disable,
|
||||
* XIntc_Acknowledge,XIntc_ConnectFastHandler and
|
||||
* XIntc_SetNormalIntrMode APIs.Added XIntc_InitializeSlaves
|
||||
* API in xintc.c
|
||||
* Modified XIntc_DeviceInterruptHandler,
|
||||
* XIntc_SetIntrSvcOption,XIntc_RegisterHandler and
|
||||
* XIntc_RegisterFastHandler APIs.Added XIntc_CascadeHandler
|
||||
* API in xintc_l.c.
|
||||
* Modified XIntc_SetOptions API in xintc_options.c.
|
||||
* Modified XIntc_SimulateIntr API in xintc_selftest.c.
|
||||
* Modified driver tcl:
|
||||
* to check for Cascade mode and generate XPAR_INTC_TYPE
|
||||
* for each controller.
|
||||
* Generate XPAR_INTC_MAX_NUM_INTR_INPUTS by adding all
|
||||
* interrupt sources of all Controllers in Cascade mode.
|
||||
* 2.07a bss 10/18/13 To support Nested interrupts:
|
||||
* Modified XIntc_DeviceInterruptHandler API.
|
||||
* Added XIN_ILR_OFFSET macro in xintc_l.h.
|
||||
* Modified driver tcl to generate HAS_ILR parameter in
|
||||
* xparameters.h
|
||||
* 3.0 bss 01/28/13 Modified xintc.c to initialize IVAR register with
|
||||
* XPAR_MICROBLAZE_BASE_VECTORS + 0x10 to fix
|
||||
* CR#765931.
|
||||
* Modified driver tcl to generate XPAR_AXI_INTC_0_TYPE
|
||||
* correctly(CR#764865).
|
||||
*
|
||||
* @note
|
||||
* For Cascade mode, Interrupt IDs are generated in xparameters.h
|
||||
* as shown below:
|
||||
*
|
||||
* Master/Primary INTC
|
||||
* ______
|
||||
* | |-0 Secondary INTC
|
||||
* | |-. ______
|
||||
* | |-. | |-32 Last INTC
|
||||
* | |-. | |-. ______
|
||||
* |______|<-31------| |-. | |-64
|
||||
* | |-. | |-.
|
||||
* |______|<-63-------| |-.
|
||||
* | |-.
|
||||
* |______|-95
|
||||
*
|
||||
* All driver functions has to be called using DeviceId/
|
||||
* InstancePtr/BaseAddress of Primary/Master Controller and
|
||||
* Interrupts IDs generated in xparameters.h only.
|
||||
* Driver functions takes care of Slave Controllers based on
|
||||
* Interrupt ID passed. User must not use Interrupt source/ID
|
||||
* 31 of Primary and Secondary controllers to call driver
|
||||
* functions.
|
||||
*
|
||||
* For nested interrupts, XIntc_DeviceInterruptHandler saves
|
||||
* microblaze r14 register on entry and restores on exit. This is
|
||||
* required since compiler does not support nesting. It enables
|
||||
* Microblaze interrupts after blocking further interrupts from
|
||||
* the current interrupt number and interrupts below current
|
||||
* interrupt proirity by writing to Interrupt Level Register of
|
||||
* INTC on entry. On exit, it disables microblaze interrupts and
|
||||
* restores ILR register default value(0xFFFFFFFF)back. It is
|
||||
* recommended to increase STACK_SIZE in linker script for nested
|
||||
* interrupts.
|
||||
* 3.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
* 3.0 adk 17/02/14 Fixed the CR:771287 Changes are made in the intc
|
||||
* driver tcl.
|
||||
* 3.1 adk 8/4/14 Fixed the CR:783248 Changes are made in
|
||||
* the test-app tcl
|
||||
* 3.2 bss 4/8/14 Fixed driver tcl to handle external interrupt pins
|
||||
* correctly (CR#799609).
|
||||
* 3.3 adk 11/3/14 added generation of C_HAS_ILR parameter to
|
||||
* xparameters.h.Changes are made in the driver tcl file
|
||||
* (CR#828046).
|
||||
* 3.5 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XINTC_H /* prevent circular inclusions */
|
||||
#define XINTC_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xparameters.h"
|
||||
#include "xstatus.h"
|
||||
#include "xintc_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* These options are used in XIntc_SetOptions() to configure the device.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* <pre>
|
||||
* XIN_SVC_SGL_ISR_OPTION Service the highest priority pending interrupt
|
||||
* and then return.
|
||||
* XIN_SVC_ALL_ISRS_OPTION Service all of the pending interrupts and then
|
||||
* return.
|
||||
* </pre>
|
||||
*/
|
||||
#define XIN_SVC_SGL_ISR_OPTION 1UL
|
||||
#define XIN_SVC_ALL_ISRS_OPTION 2UL
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* @name Start modes
|
||||
* One of these values is passed to XIntc_Start() to start the device.
|
||||
* @{
|
||||
*/
|
||||
/** Simulation only mode, no hardware interrupts recognized */
|
||||
#define XIN_SIMULATION_MODE 0
|
||||
/** Real mode, no simulation allowed, hardware interrupts recognized */
|
||||
#define XIN_REAL_MODE 1
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* @name Masks to specify Interrupt Controller Mode
|
||||
* @{
|
||||
*/
|
||||
#define XIN_INTC_NOCASCADE 0 /* Normal - No Cascade Mode */
|
||||
#define XIN_INTC_PRIMARY 1 /* Master/Primary controller */
|
||||
#define XIN_INTC_SECONDARY 2 /* Secondary Slave Controllers */
|
||||
#define XIN_INTC_LAST 3 /* Last Slave Controller */
|
||||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* @name Mask to specify maximum number of interrupt sources per controller
|
||||
* @{
|
||||
*/
|
||||
#define XIN_CONTROLLER_MAX_INTRS 32 /* Each Controller has 32
|
||||
interrupt pins */
|
||||
/*@}*/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
UINTPTR BaseAddress; /**< Register base address */
|
||||
u32 AckBeforeService; /**< Ack location per interrupt */
|
||||
int FastIntr; /**< Fast Interrupt enabled */
|
||||
u32 IntVectorAddr; /**< Interrupt Vector Address */
|
||||
int NumberofIntrs; /**< Number of Interrupt sources */
|
||||
u32 Options; /**< Device options */
|
||||
int IntcType; /**< Intc type 0 - No Cascade Mode
|
||||
1 - primary instance
|
||||
2 - secondary instance
|
||||
3 - last instance */
|
||||
|
||||
/** Static vector table of interrupt handlers */
|
||||
#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE
|
||||
XIntc_VectorTableEntry HandlerTable[XIN_CONTROLLER_MAX_INTRS];
|
||||
#else
|
||||
XIntc_VectorTableEntry HandlerTable[XPAR_INTC_MAX_NUM_INTR_INPUTS];
|
||||
#endif
|
||||
|
||||
} XIntc_Config;
|
||||
|
||||
/**
|
||||
* The XIntc driver instance data. The user is required to allocate a
|
||||
* variable of this type for every intc device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
UINTPTR BaseAddress; /**< Base address of registers */
|
||||
u32 IsReady; /**< Device is initialized and ready */
|
||||
u32 IsStarted; /**< Device has been started */
|
||||
u32 UnhandledInterrupts; /**< Intc Statistics */
|
||||
XIntc_Config *CfgPtr; /**< Pointer to instance config entry */
|
||||
|
||||
} XIntc;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Required functions in xintc.c
|
||||
*/
|
||||
int XIntc_Initialize(XIntc * InstancePtr, u16 DeviceId);
|
||||
|
||||
int XIntc_Start(XIntc * InstancePtr, u8 Mode);
|
||||
void XIntc_Stop(XIntc * InstancePtr);
|
||||
|
||||
int XIntc_Connect(XIntc * InstancePtr, u8 Id,
|
||||
XInterruptHandler Handler, void *CallBackRef);
|
||||
void XIntc_Disconnect(XIntc * InstancePtr, u8 Id);
|
||||
|
||||
void XIntc_Enable(XIntc * InstancePtr, u8 Id);
|
||||
void XIntc_Disable(XIntc * InstancePtr, u8 Id);
|
||||
|
||||
void XIntc_Acknowledge(XIntc * InstancePtr, u8 Id);
|
||||
|
||||
XIntc_Config *XIntc_LookupConfig(u16 DeviceId);
|
||||
|
||||
int XIntc_ConnectFastHandler(XIntc *InstancePtr, u8 Id,
|
||||
XFastInterruptHandler Handler);
|
||||
void XIntc_SetNormalIntrMode(XIntc *InstancePtr, u8 Id);
|
||||
|
||||
/*
|
||||
* Interrupt functions in xintr_intr.c
|
||||
*/
|
||||
void XIntc_VoidInterruptHandler(void);
|
||||
void XIntc_InterruptHandler(XIntc * InstancePtr);
|
||||
|
||||
/*
|
||||
* Options functions in xintc_options.c
|
||||
*/
|
||||
int XIntc_SetOptions(XIntc * InstancePtr, u32 Options);
|
||||
u32 XIntc_GetOptions(XIntc * InstancePtr);
|
||||
|
||||
/*
|
||||
* Self-test functions in xintc_selftest.c
|
||||
*/
|
||||
int XIntc_SelfTest(XIntc * InstancePtr);
|
||||
int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
@ -0,0 +1,78 @@
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by HSI.
|
||||
* Version:
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
|
||||
*Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
*of this software and associated documentation files (the Software), to deal
|
||||
*in the Software without restriction, including without limitation the rights
|
||||
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
*copies of the Software, and to permit persons to whom the Software is
|
||||
*furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*The above copyright notice and this permission notice shall be included in
|
||||
*all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
*(a) running on a Xilinx device, or
|
||||
*(b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
*in advertising or otherwise to promote the sale, use or other dealings in
|
||||
*this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
|
||||
*
|
||||
* Description: Driver configuration
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xintc.h"
|
||||
|
||||
|
||||
extern void XNullHandler (void *);
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XIntc_Config XIntc_ConfigTable[] =
|
||||
{
|
||||
{
|
||||
XPAR_AXI_INTC_0_DEVICE_ID,
|
||||
XPAR_AXI_INTC_0_BASEADDR,
|
||||
XPAR_AXI_INTC_0_KIND_OF_INTR,
|
||||
XPAR_AXI_INTC_0_HAS_FAST,
|
||||
XPAR_AXI_INTC_0_IVAR_RESET_VALUE,
|
||||
XPAR_AXI_INTC_0_NUM_INTR_INPUTS,
|
||||
XIN_SVC_SGL_ISR_OPTION,
|
||||
XPAR_AXI_INTC_0_TYPE,
|
||||
{
|
||||
{
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
},
|
||||
{
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
},
|
||||
{
|
||||
XNullHandler,
|
||||
(void *) XNULL
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
@ -0,0 +1,93 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xintc_i.h
|
||||
* @addtogroup intc_v3_4
|
||||
* @{
|
||||
*
|
||||
* This file contains data which is shared between files and internal to the
|
||||
* XIntc component. It is intended for internal use only.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00b jhl 02/06/02 First release
|
||||
* 1.00b jhl 04/24/02 Moved register definitions to xintc_l.h
|
||||
* 1.00c rpm 10/17/03 New release. Removed extern of global, single instance
|
||||
* pointer.
|
||||
* 1.10c mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XINTC_I_H /* prevent circular inclusions */
|
||||
#define XINTC_I_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xintc.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern u32 XIntc_BitPosMask[];
|
||||
|
||||
extern XIntc_Config XIntc_ConfigTable[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/** @} */
|
@ -0,0 +1,176 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xintc_intr.c
|
||||
* @addtogroup intc_v3_4
|
||||
* @{
|
||||
*
|
||||
* This file contains the interrupt processing for the XIntc component which
|
||||
* is the driver for the Xilinx Interrupt Controller. The interrupt
|
||||
* processing is partitioned seperately such that users are not required to
|
||||
* use the provided interrupt processing. This file requires other files of
|
||||
* the driver to be linked in also.
|
||||
*
|
||||
* Two different interrupt handlers are provided for this driver such that the
|
||||
* user must select the appropriate handler for the application. The first
|
||||
* interrupt handler, XIntc_VoidInterruptHandler, is provided for systems
|
||||
* which use only a single interrupt controller or for systems that cannot
|
||||
* otherwise provide an argument to the XIntc interrupt handler (e.g., the RTOS
|
||||
* interrupt vector handler may not provide such a facility). The constant
|
||||
* XPAR_INTC_SINGLE_DEVICE_ID must be defined for this handler to be included in
|
||||
* the driver. The second interrupt handler, XIntc_InterruptHandler, uses an
|
||||
* input argument which is an instance pointer to an interrupt controller driver
|
||||
* such that multiple interrupt controllers can be supported. This handler
|
||||
* requires the calling function to pass it the appropriate argument, so another
|
||||
* level of indirection may be required.
|
||||
*
|
||||
* Note that both of these handlers are now only provided for backward
|
||||
* compatibility. The handler defined in xintc_l.c is the recommended handler.
|
||||
*
|
||||
* The interrupt processing may be used by connecting one of the interrupt
|
||||
* handlers to the interrupt system. These handlers do not save and restore
|
||||
* the processor context but only handle the processing of the Interrupt
|
||||
* Controller. The two handlers are provided as working examples. The user is
|
||||
* encouraged to supply their own interrupt handler when performance tuning is
|
||||
* deemed necessary.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 1.00b jhl 02/13/02 First release
|
||||
* 1.00c rpm 10/17/03 New release. Support the static vector table created
|
||||
* in the xintc_g.c configuration table. Collapse handlers
|
||||
* to use the XIntc_DeviceInterruptHandler() in xintc_l.c.
|
||||
* 1.00c rpm 04/09/04 Added conditional compilation around the old handler
|
||||
* XIntc_VoidInterruptHandler(). This handler will only be
|
||||
* include/compiled if XPAR_INTC_SINGLE_DEVICE_ID is defined.
|
||||
* 1.10c mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* This driver assumes that the context of the processor has been saved prior to
|
||||
* the calling of the Interrupt Controller interrupt handler and then restored
|
||||
* after the handler returns. This requires either the running RTOS to save the
|
||||
* state of the machine or that a wrapper be used as the destination of the
|
||||
* interrupt vector to save the state of the processor and restore the state
|
||||
* after the interrupt handler returns.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xparameters.h"
|
||||
#include "xintc.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Interrupt handler for the driver used when there can be no argument passed
|
||||
* to the handler. This function is provided mostly for backward compatibility.
|
||||
* The user should use XIntc_DeviceInterruptHandler(), defined in xintc_l.c,
|
||||
* if possible.
|
||||
*
|
||||
* The user must connect this function to the interrupt system such that it is
|
||||
* called whenever the devices which are connected to it cause an interrupt.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The constant XPAR_INTC_SINGLE_DEVICE_ID must be defined for this handler
|
||||
* to be included in the driver compilation.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifdef XPAR_INTC_SINGLE_DEVICE_ID
|
||||
void XIntc_VoidInterruptHandler(void)
|
||||
{
|
||||
/* Use the single instance to call the main interrupt handler */
|
||||
XIntc_DeviceInterruptHandler((void *) XPAR_INTC_SINGLE_DEVICE_ID);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* The interrupt handler for the driver. This function is provided mostly for
|
||||
* backward compatibility. The user should use XIntc_DeviceInterruptHandler(),
|
||||
* defined in xintc_l.c when possible and pass the device ID of the interrupt
|
||||
* controller device as its argument.
|
||||
*
|
||||
* The user must connect this function to the interrupt system such that it is
|
||||
* called whenever the devices which are connected to it cause an interrupt.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIntc_InterruptHandler(XIntc * InstancePtr)
|
||||
{
|
||||
/* Assert that the pointer to the instance is valid
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
/* Use the instance's device ID to call the main interrupt handler.
|
||||
* (the casts are to avoid a compiler warning)
|
||||
*/
|
||||
XIntc_DeviceInterruptHandler((void *)
|
||||
((u32) (InstancePtr->CfgPtr->DeviceId)));
|
||||
}
|
||||
/** @} */
|
@ -0,0 +1,669 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xintc_l.c
|
||||
* @addtogroup intc_v3_4
|
||||
* @{
|
||||
*
|
||||
* This file contains low-level driver functions that can be used to access the
|
||||
* device. The user should refer to the hardware device specification for more
|
||||
* details of the device operation.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00b jhl 04/24/02 First release
|
||||
* 1.00c rpm 10/17/03 New release. Support the static vector table created
|
||||
* in the xintc_g.c configuration table.
|
||||
* 1.00c rpm 04/09/04 Added conditional compilation around the old handler
|
||||
* XIntc_LowLevelInterruptHandler(). This handler will only
|
||||
* be include/compiled if XPAR_INTC_SINGLE_DEVICE_ID is
|
||||
* defined.
|
||||
* 1.10c mta 03/21/07 Updated to new coding style
|
||||
* 1.10c ecm 07/09/07 Read the ISR after the Acknowledge in the interrupt
|
||||
* handler to support architectures with posted write bus
|
||||
* access issues.
|
||||
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs and _m is removed
|
||||
* from all the macro definitions.
|
||||
* 2.04a bss 01/13/12 Removed the unused Register variable for warnings.
|
||||
* 2.05a bss 08/18/12 Added XIntc_RegisterFastHandler API to register fast
|
||||
* interrupt handlers using base address.
|
||||
* 2.06a bss 01/28/13 To support Cascade mode:
|
||||
* Modified XIntc_DeviceInterruptHandler,
|
||||
* XIntc_SetIntrSvcOption,XIntc_RegisterHandler and
|
||||
* XIntc_RegisterFastHandler APIs.
|
||||
* Added XIntc_CascadeHandler API.
|
||||
* 2.07a bss 10/18/13 Modified XIntc_DeviceInterruptHandler to support
|
||||
* nested interrupts.
|
||||
* 3.5 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototypes of LookupConfigByBaseAddress,
|
||||
* XIntc_SetIntrSvcOption, XIntc_RegisterHandler,
|
||||
* XIntc_RegisterFastHandler APIs.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xintc.h"
|
||||
#include "xintc_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static XIntc_Config *LookupConfigByBaseAddress(UINTPTR BaseAddress);
|
||||
|
||||
#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE
|
||||
static void XIntc_CascadeHandler(void *DeviceId);
|
||||
#endif
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This is the interrupt handler for the driver interface provided in this file
|
||||
* when there can be no argument passed to the handler. In this case, we just
|
||||
* use the globally defined device ID for the interrupt controller. This function
|
||||
* is provided mostly for backward compatibility. The user should use
|
||||
* XIntc_DeviceInterruptHandler() if possible.
|
||||
*
|
||||
* This function does not support multiple interrupt controller instances to be
|
||||
* handled.
|
||||
*
|
||||
* The user must connect this function to the interrupt system such that it is
|
||||
* called whenever the devices which are connected to it cause an interrupt.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The constant XPAR_INTC_SINGLE_DEVICE_ID must be defined for this handler
|
||||
* to be included in the driver compilation.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifdef XPAR_INTC_SINGLE_DEVICE_ID
|
||||
void XIntc_LowLevelInterruptHandler(void)
|
||||
{
|
||||
/*
|
||||
* A level of indirection here because the interrupt handler used with
|
||||
* the driver interface given in this file needs to remain void - no
|
||||
* arguments. So we need the globally defined device ID of THE
|
||||
* interrupt controller.
|
||||
*/
|
||||
XIntc_DeviceInterruptHandler((void *) XPAR_INTC_SINGLE_DEVICE_ID);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is the primary interrupt handler for the driver. It must be
|
||||
* connected to the interrupt source such that is called when an interrupt of
|
||||
* the interrupt controller is active. It will resolve which interrupts are
|
||||
* active and enabled and call the appropriate interrupt handler. It uses
|
||||
* the AckBeforeService flag in the configuration data to determine when to
|
||||
* acknowledge the interrupt. Highest priority interrupts are serviced first.
|
||||
* This function assumes that an interrupt vector table has been previously
|
||||
* initialized.It does not verify that entries in the table are valid before
|
||||
* calling an interrupt handler. In Cascade mode this function calls
|
||||
* XIntc_CascadeHandler to handle interrupts of Master and Slave controllers.
|
||||
* This functions also handles interrupts nesting by saving and restoring link
|
||||
* register of Microblaze and Interrupt Level register of interrupt controller
|
||||
* properly.
|
||||
|
||||
* @param DeviceId is the zero-based device ID defined in xparameters.h
|
||||
* of the interrupting interrupt controller. It is used as a direct
|
||||
* index into the configuration data, which contains the vector
|
||||
* table for the interrupt controller. Note that even though the
|
||||
* argument is a void pointer, the value is not a pointer but the
|
||||
* actual device ID. The void pointer type is necessary to meet
|
||||
* the XInterruptHandler typedef for interrupt handlers.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note For nested interrupts, this function saves microblaze r14
|
||||
* register on entry and restores on exit. This is required since
|
||||
* compiler does not support nesting. This function enables
|
||||
* Microblaze interrupts after blocking further interrupts
|
||||
* from the current interrupt number and interrupts below current
|
||||
* interrupt proirity by writing to Interrupt Level Register of
|
||||
* INTC on entry. On exit, it disables microblaze interrupts and
|
||||
* restores ILR register default value(0xFFFFFFFF)back. It is
|
||||
* recommended to increase STACK_SIZE in linker script for nested
|
||||
* interrupts.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIntc_DeviceInterruptHandler(void *DeviceId)
|
||||
{
|
||||
u32 IntrStatus;
|
||||
u32 IntrMask = 1;
|
||||
int IntrNumber;
|
||||
XIntc_Config *CfgPtr;
|
||||
u32 Imr;
|
||||
|
||||
/* Get the configuration data using the device ID */
|
||||
CfgPtr = &XIntc_ConfigTable[(u32)DeviceId];
|
||||
|
||||
#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE
|
||||
if (CfgPtr->IntcType != XIN_INTC_NOCASCADE) {
|
||||
XIntc_CascadeHandler(DeviceId);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{ /* This extra brace is required for compilation in Cascade Mode */
|
||||
|
||||
#if XPAR_XINTC_HAS_ILR == TRUE
|
||||
#ifdef __MICROBLAZE__
|
||||
volatile u32 R14_register;
|
||||
/* Save r14 register */
|
||||
R14_register = mfgpr(r14);
|
||||
#endif
|
||||
volatile u32 ILR_reg;
|
||||
/* Save ILR register */
|
||||
ILR_reg = Xil_In32(CfgPtr->BaseAddress + XIN_ILR_OFFSET);
|
||||
#endif
|
||||
/* Get the interrupts that are waiting to be serviced */
|
||||
IntrStatus = XIntc_GetIntrStatus(CfgPtr->BaseAddress);
|
||||
|
||||
/* Mask the Fast Interrupts */
|
||||
if (CfgPtr->FastIntr == TRUE) {
|
||||
Imr = XIntc_In32(CfgPtr->BaseAddress + XIN_IMR_OFFSET);
|
||||
IntrStatus &= ~Imr;
|
||||
}
|
||||
|
||||
/* Service each interrupt that is active and enabled by
|
||||
* checking each bit in the register from LSB to MSB which
|
||||
* corresponds to an interrupt input signal
|
||||
*/
|
||||
for (IntrNumber = 0; IntrNumber < CfgPtr->NumberofIntrs;
|
||||
IntrNumber++) {
|
||||
if (IntrStatus & 1) {
|
||||
XIntc_VectorTableEntry *TablePtr;
|
||||
#if XPAR_XINTC_HAS_ILR == TRUE
|
||||
/* Write to ILR the current interrupt
|
||||
* number
|
||||
*/
|
||||
Xil_Out32(CfgPtr->BaseAddress +
|
||||
XIN_ILR_OFFSET, IntrNumber);
|
||||
|
||||
/* Read back ILR to ensure the value
|
||||
* has been updated and it is safe to
|
||||
* enable interrupts
|
||||
*/
|
||||
|
||||
Xil_In32(CfgPtr->BaseAddress +
|
||||
XIN_ILR_OFFSET);
|
||||
|
||||
/* Enable interrupts */
|
||||
Xil_ExceptionEnable();
|
||||
#endif
|
||||
/* If the interrupt has been setup to
|
||||
* acknowledge it before servicing the
|
||||
* interrupt, then ack it */
|
||||
if (CfgPtr->AckBeforeService & IntrMask) {
|
||||
XIntc_AckIntr(CfgPtr->BaseAddress,
|
||||
IntrMask);
|
||||
}
|
||||
|
||||
/* The interrupt is active and enabled, call
|
||||
* the interrupt handler that was setup with
|
||||
* the specified parameter
|
||||
*/
|
||||
TablePtr = &(CfgPtr->HandlerTable[IntrNumber]);
|
||||
TablePtr->Handler(TablePtr->CallBackRef);
|
||||
|
||||
/* If the interrupt has been setup to
|
||||
* acknowledge it after it has been serviced
|
||||
* then ack it
|
||||
*/
|
||||
if ((CfgPtr->AckBeforeService &
|
||||
IntrMask) == 0) {
|
||||
XIntc_AckIntr(CfgPtr->BaseAddress,
|
||||
IntrMask);
|
||||
}
|
||||
|
||||
#if XPAR_XINTC_HAS_ILR == TRUE
|
||||
/* Disable interrupts */
|
||||
Xil_ExceptionDisable();
|
||||
/* Restore ILR */
|
||||
Xil_Out32(CfgPtr->BaseAddress + XIN_ILR_OFFSET,
|
||||
ILR_reg);
|
||||
#endif
|
||||
/*
|
||||
* Read the ISR again to handle architectures
|
||||
* with posted write bus access issues.
|
||||
*/
|
||||
XIntc_GetIntrStatus(CfgPtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* If only the highest priority interrupt is to
|
||||
* be serviced, exit loop and return after
|
||||
* servicing
|
||||
* the interrupt
|
||||
*/
|
||||
if (CfgPtr->Options == XIN_SVC_SGL_ISR_OPTION) {
|
||||
|
||||
#if XPAR_XINTC_HAS_ILR == TRUE
|
||||
#ifdef __MICROBLAZE__
|
||||
/* Restore r14 */
|
||||
mtgpr(r14, R14_register);
|
||||
#endif
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to the next interrupt to check */
|
||||
IntrMask <<= 1;
|
||||
IntrStatus >>= 1;
|
||||
|
||||
/* If there are no other bits set indicating that all
|
||||
* interrupts have been serviced, then exit the loop
|
||||
*/
|
||||
if (IntrStatus == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if XPAR_XINTC_HAS_ILR == TRUE
|
||||
#ifdef __MICROBLAZE__
|
||||
/* Restore r14 */
|
||||
mtgpr(r14, R14_register);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the interrupt service option, which can configure the driver so that it
|
||||
* services only a single interrupt at a time when an interrupt occurs, or
|
||||
* services all pending interrupts when an interrupt occurs. The default
|
||||
* behavior when using the driver interface given in xintc.h file is to service
|
||||
* only a single interrupt, whereas the default behavior when using the driver
|
||||
* interface given in this file is to service all outstanding interrupts when an
|
||||
* interrupt occurs. In Cascade mode same Option is set to Slave controllers.
|
||||
*
|
||||
* @param BaseAddress is the unique identifier for a device.
|
||||
* @param Option is XIN_SVC_SGL_ISR_OPTION if you want only a single
|
||||
* interrupt serviced when an interrupt occurs, or
|
||||
* XIN_SVC_ALL_ISRS_OPTION if you want all pending interrupts
|
||||
* serviced when an interrupt occurs.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Note that this function has no effect if the input base address is invalid.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIntc_SetIntrSvcOption(UINTPTR BaseAddress, int Option)
|
||||
{
|
||||
XIntc_Config *CfgPtr;
|
||||
|
||||
CfgPtr = LookupConfigByBaseAddress(BaseAddress);
|
||||
if (CfgPtr != NULL) {
|
||||
CfgPtr->Options = Option;
|
||||
/* If Cascade mode set the option for all Slaves */
|
||||
if (CfgPtr->IntcType != XIN_INTC_NOCASCADE) {
|
||||
int Index;
|
||||
for (Index = 1; Index <= XPAR_XINTC_NUM_INSTANCES - 1;
|
||||
Index++) {
|
||||
CfgPtr = XIntc_LookupConfig(Index);
|
||||
CfgPtr->Options = Option;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Register a handler function for a specific interrupt ID. The vector table
|
||||
* of the interrupt controller is updated, overwriting any previous handler.
|
||||
* The handler function will be called when an interrupt occurs for the given
|
||||
* interrupt ID.
|
||||
*
|
||||
* This function can also be used to remove a handler from the vector table
|
||||
* by passing in the XIntc_DefaultHandler() as the handler and NULL as the
|
||||
* callback reference.
|
||||
* In Cascade mode Interrupt Id is used to set Handler for corresponding Slave
|
||||
* Controller
|
||||
*
|
||||
* @param BaseAddress is the base address of the interrupt controller
|
||||
* whose vector table will be modified.
|
||||
* @param InterruptId is the interrupt ID to be associated with the input
|
||||
* handler.
|
||||
* @param Handler is the function pointer that will be added to
|
||||
* the vector table for the given interrupt ID.
|
||||
* @param CallBackRef is the argument that will be passed to the new
|
||||
* handler function when it is called. This is user-specific.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Note that this function has no effect if the input base address is invalid.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIntc_RegisterHandler(UINTPTR BaseAddress, int InterruptId,
|
||||
XInterruptHandler Handler, void *CallBackRef)
|
||||
{
|
||||
XIntc_Config *CfgPtr;
|
||||
|
||||
CfgPtr = LookupConfigByBaseAddress(BaseAddress);
|
||||
|
||||
if (CfgPtr != NULL) {
|
||||
|
||||
if (InterruptId > 31) {
|
||||
CfgPtr = XIntc_LookupConfig(InterruptId/32);
|
||||
CfgPtr->HandlerTable[InterruptId%32].Handler = Handler;
|
||||
CfgPtr->HandlerTable[InterruptId%32].CallBackRef =
|
||||
CallBackRef;
|
||||
}
|
||||
else {
|
||||
CfgPtr->HandlerTable[InterruptId].Handler = Handler;
|
||||
CfgPtr->HandlerTable[InterruptId].CallBackRef =
|
||||
CallBackRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Looks up the device configuration based on the base address of the device.
|
||||
* A table contains the configuration info for each device in the system.
|
||||
*
|
||||
* @param BaseAddress is the unique identifier for a device.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A pointer to the configuration structure for the specified device, or
|
||||
* NULL if the device was not found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static XIntc_Config *LookupConfigByBaseAddress(UINTPTR BaseAddress)
|
||||
{
|
||||
XIntc_Config *CfgPtr = NULL;
|
||||
int Index;
|
||||
|
||||
for (Index = 0; Index < XPAR_XINTC_NUM_INSTANCES; Index++) {
|
||||
if (XIntc_ConfigTable[Index].BaseAddress == BaseAddress) {
|
||||
CfgPtr = &XIntc_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CfgPtr;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Register a fast handler function for a specific interrupt ID. The handler
|
||||
* function will be called when an interrupt occurs for the given interrupt ID.
|
||||
* In Cascade mode Interrupt Id is used to set Handler for corresponding Slave
|
||||
* Controller
|
||||
*
|
||||
* @param BaseAddress is the base address of the interrupt controller
|
||||
* whose vector table will be modified.
|
||||
* @param InterruptId is the interrupt ID to be associated with the input
|
||||
* handler.
|
||||
* @param FastHandler is the function pointer that will be called when
|
||||
* interrupt occurs
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Note that this function has no effect if the input base address is invalid.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XIntc_RegisterFastHandler(UINTPTR BaseAddress, u8 Id,
|
||||
XFastInterruptHandler FastHandler)
|
||||
{
|
||||
u32 CurrentIER;
|
||||
u32 Mask;
|
||||
u32 Imr;
|
||||
XIntc_Config *CfgPtr;
|
||||
|
||||
|
||||
if (Id > 31) {
|
||||
/* Enable user required Id in Slave controller */
|
||||
CfgPtr = XIntc_LookupConfig(Id/32);
|
||||
|
||||
/* Get the Enabled Interrupts */
|
||||
CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET);
|
||||
|
||||
/* Convert from integer id to bit mask */
|
||||
Mask = XIntc_BitPosMask[(Id%32)];
|
||||
|
||||
/* Disable the Interrupt if it was enabled before calling
|
||||
* this function
|
||||
*/
|
||||
if (CurrentIER & Mask) {
|
||||
XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET,
|
||||
(CurrentIER & ~Mask));
|
||||
}
|
||||
|
||||
XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET +
|
||||
((Id%32) * 4), (u32) FastHandler);
|
||||
|
||||
/* Slave controllers in Cascade Mode should have all as Fast
|
||||
* interrupts or Normal interrupts, mixed interrupts are not
|
||||
* supported
|
||||
*/
|
||||
XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0xFFFFFFFF);
|
||||
|
||||
/* Enable the Interrupt if it was enabled before calling this
|
||||
* function
|
||||
*/
|
||||
if (CurrentIER & Mask) {
|
||||
XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET,
|
||||
(CurrentIER | Mask));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
|
||||
|
||||
/* Convert from integer id to bit mask */
|
||||
Mask = XIntc_BitPosMask[Id];
|
||||
|
||||
if (CurrentIER & Mask) {
|
||||
/* Disable Interrupt if it was enabled */
|
||||
CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
|
||||
XIntc_Out32(BaseAddress + XIN_IER_OFFSET,
|
||||
(CurrentIER & ~Mask));
|
||||
}
|
||||
|
||||
XIntc_Out32(BaseAddress + XIN_IVAR_OFFSET + (Id * 4),
|
||||
(u32) FastHandler);
|
||||
|
||||
Imr = XIntc_In32(BaseAddress + XIN_IMR_OFFSET);
|
||||
XIntc_Out32(BaseAddress + XIN_IMR_OFFSET, Imr | Mask);
|
||||
|
||||
|
||||
/* Enable Interrupt if it was enabled before calling
|
||||
* this function
|
||||
*/
|
||||
if (CurrentIER & Mask) {
|
||||
CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
|
||||
XIntc_Out32(BaseAddress + XIN_IER_OFFSET,
|
||||
(CurrentIER | Mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is called by primary interrupt handler for the driver to handle
|
||||
* all Controllers in Cascade mode.It will resolve which interrupts are active
|
||||
* and enabled and call the appropriate interrupt handler. It uses the
|
||||
* AckBeforeService flag in the configuration data to determine when to
|
||||
* acknowledge the interrupt. Highest priority interrupts are serviced first.
|
||||
* This function assumes that an interrupt vector table has been previously
|
||||
* initialized. It does not verify that entries in the table are valid before
|
||||
* calling an interrupt handler.This function calls itself recursively to handle
|
||||
* all interrupt controllers.
|
||||
*
|
||||
* @param DeviceId is the zero-based device ID defined in xparameters.h
|
||||
* of the interrupting interrupt controller. It is used as a direct
|
||||
* index into the configuration data, which contains the vector
|
||||
* table for the interrupt controller.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
static void XIntc_CascadeHandler(void *DeviceId)
|
||||
{
|
||||
u32 IntrStatus;
|
||||
u32 IntrMask = 1;
|
||||
int IntrNumber;
|
||||
u32 Imr;
|
||||
XIntc_Config *CfgPtr;
|
||||
static int Id = 0;
|
||||
|
||||
/* Get the configuration data using the device ID */
|
||||
CfgPtr = &XIntc_ConfigTable[(u32)DeviceId];
|
||||
|
||||
/* Get the interrupts that are waiting to be serviced */
|
||||
IntrStatus = XIntc_GetIntrStatus(CfgPtr->BaseAddress);
|
||||
|
||||
/* Mask the Fast Interrupts */
|
||||
if (CfgPtr->FastIntr == TRUE) {
|
||||
Imr = XIntc_In32(CfgPtr->BaseAddress + XIN_IMR_OFFSET);
|
||||
IntrStatus &= ~Imr;
|
||||
}
|
||||
|
||||
/* Service each interrupt that is active and enabled by
|
||||
* checking each bit in the register from LSB to MSB which
|
||||
* corresponds to an interrupt input signal
|
||||
*/
|
||||
for (IntrNumber = 0; IntrNumber < CfgPtr->NumberofIntrs; IntrNumber++) {
|
||||
if (IntrStatus & 1) {
|
||||
XIntc_VectorTableEntry *TablePtr;
|
||||
|
||||
/* In Cascade mode call this function recursively
|
||||
* for interrupt id 31 and until interrupts of last
|
||||
* instance/controller are handled
|
||||
*/
|
||||
if ((IntrNumber == 31) &&
|
||||
(CfgPtr->IntcType != XIN_INTC_LAST) &&
|
||||
(CfgPtr->IntcType != XIN_INTC_NOCASCADE)) {
|
||||
XIntc_CascadeHandler((void *)++Id);
|
||||
Id--;
|
||||
}
|
||||
|
||||
/* If the interrupt has been setup to
|
||||
* acknowledge it before servicing the
|
||||
* interrupt, then ack it */
|
||||
if (CfgPtr->AckBeforeService & IntrMask) {
|
||||
XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask);
|
||||
}
|
||||
|
||||
/* Handler of 31 interrupt Id has to be called only
|
||||
* for Last controller in cascade Mode
|
||||
*/
|
||||
if (!((IntrNumber == 31) &&
|
||||
(CfgPtr->IntcType != XIN_INTC_LAST) &&
|
||||
(CfgPtr->IntcType != XIN_INTC_NOCASCADE))) {
|
||||
|
||||
/* The interrupt is active and enabled, call
|
||||
* the interrupt handler that was setup with
|
||||
* the specified parameter
|
||||
*/
|
||||
TablePtr = &(CfgPtr->HandlerTable[IntrNumber]);
|
||||
TablePtr->Handler(TablePtr->CallBackRef);
|
||||
}
|
||||
/* If the interrupt has been setup to acknowledge it
|
||||
* after it has been serviced then ack it
|
||||
*/
|
||||
if ((CfgPtr->AckBeforeService & IntrMask) == 0) {
|
||||
XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the ISR again to handle architectures with
|
||||
* posted write bus access issues.
|
||||
*/
|
||||
XIntc_GetIntrStatus(CfgPtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* If only the highest priority interrupt is to be
|
||||
* serviced, exit loop and return after servicing
|
||||
* the interrupt
|
||||
*/
|
||||
if (CfgPtr->Options == XIN_SVC_SGL_ISR_OPTION) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to the next interrupt to check */
|
||||
IntrMask <<= 1;
|
||||
IntrStatus >>= 1;
|
||||
|
||||
/* If there are no other bits set indicating that all interrupts
|
||||
* have been serviced, then exit the loop
|
||||
*/
|
||||
if (IntrStatus == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
@ -0,0 +1,333 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xintc_l.h
|
||||
* @addtogroup intc_v3_4
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and low-level driver functions (or
|
||||
* macros) that can be used to access the device. The user should refer to the
|
||||
* hardware device specification for more details of the device operation.
|
||||
*
|
||||
*
|
||||
* Note that users of the driver interface given in this file can register
|
||||
* an interrupt handler dynamically (at run-time) using the
|
||||
* XIntc_RegisterHandler() function.
|
||||
* User of the driver interface given in xintc.h should still use
|
||||
* XIntc_Connect(), as always.
|
||||
* Also see the discussion of the interrupt vector tables in xintc.h.
|
||||
*
|
||||
* There are currently two interrupt handlers specified in this interface.
|
||||
*
|
||||
* - XIntc_LowLevelInterruptHandler() is a handler without any arguments that
|
||||
* is used in cases where there is a single interrupt controller device in
|
||||
* the system and the handler cannot be passed an argument. This function is
|
||||
* provided mostly for backward compatibility.
|
||||
*
|
||||
* - XIntc_DeviceInterruptHandler() is a handler that takes a device ID as an
|
||||
* argument, indicating which interrupt controller device in the system is
|
||||
* causing the interrupt - thereby supporting multiple interrupt controllers.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------------
|
||||
* 1.00b jhl 04/24/02 First release
|
||||
* 1.00c rpm 10/17/03 New release. Support the static vector table created
|
||||
* in the xintc_g.c configuration table.
|
||||
* 1.10c mta 03/21/07 Updated to new coding style
|
||||
* 1.11a sv 11/21/07 Updated driver to support access through a DCR bridge
|
||||
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. _m is removed from all
|
||||
* the macro definitions.
|
||||
* 2.04a bss 01/13/12 Updated for adding defines for IMR and IVAR for
|
||||
* the FAST Interrupt
|
||||
* 2.05a bss 08/18/12 Added XIntc_RegisterFastHandler API to register fast
|
||||
* interrupt handlers using base address.
|
||||
* 2.07a bss 10/18/13 Added XIN_ILR_OFFSET macro for nested interrupts.
|
||||
* 3.5 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototypes of XIntc_RegisterFastHandler,
|
||||
* XIntc_SetIntrSvcOption, XIntc_RegisterHandler APIs.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XINTC_L_H /* prevent circular inclusions */
|
||||
#define XINTC_L_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xparameters.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
/*
|
||||
* XPAR_XINTC_USE_DCR_BRIDGE has to be set to 1 if the Intc device will be
|
||||
* accessed through a DCR bus connected to a bridge.
|
||||
*/
|
||||
#define XPAR_XINTC_USE_DCR_BRIDGE 0
|
||||
|
||||
#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0))
|
||||
#include "xio_dcr.h"
|
||||
#endif
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/* define the offsets from the base address for all the registers of the
|
||||
* interrupt controller, some registers may be optional in the hardware device
|
||||
*/
|
||||
#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0))
|
||||
|
||||
#define XIN_ISR_OFFSET 0 /* Interrupt Status Register */
|
||||
#define XIN_IPR_OFFSET 1 /* Interrupt Pending Register */
|
||||
#define XIN_IER_OFFSET 2 /* Interrupt Enable Register */
|
||||
#define XIN_IAR_OFFSET 3 /* Interrupt Acknowledge Register */
|
||||
#define XIN_SIE_OFFSET 4 /* Set Interrupt Enable Register */
|
||||
#define XIN_CIE_OFFSET 5 /* Clear Interrupt Enable Register */
|
||||
#define XIN_IVR_OFFSET 6 /* Interrupt Vector Register */
|
||||
#define XIN_MER_OFFSET 7 /* Master Enable Register */
|
||||
#define XIN_IMR_OFFSET 8 /* Interrupt Mode Register , this is present
|
||||
* only for Fast Interrupt */
|
||||
#define XIN_IVAR_OFFSET 64 /* Interrupt Vector Address Register
|
||||
* Interrupt 0 Offest, this is present
|
||||
* only for Fast Interrupt */
|
||||
|
||||
#else /* ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) */
|
||||
|
||||
#define XIN_ISR_OFFSET 0 /* Interrupt Status Register */
|
||||
#define XIN_IPR_OFFSET 4 /* Interrupt Pending Register */
|
||||
#define XIN_IER_OFFSET 8 /* Interrupt Enable Register */
|
||||
#define XIN_IAR_OFFSET 12 /* Interrupt Acknowledge Register */
|
||||
#define XIN_SIE_OFFSET 16 /* Set Interrupt Enable Register */
|
||||
#define XIN_CIE_OFFSET 20 /* Clear Interrupt Enable Register */
|
||||
#define XIN_IVR_OFFSET 24 /* Interrupt Vector Register */
|
||||
#define XIN_MER_OFFSET 28 /* Master Enable Register */
|
||||
#define XIN_IMR_OFFSET 32 /* Interrupt Mode Register , this is present
|
||||
* only for Fast Interrupt */
|
||||
#define XIN_ILR_OFFSET 36 /* Interrupt level register */
|
||||
#define XIN_IVAR_OFFSET 0x100 /* Interrupt Vector Address Register
|
||||
* Interrupt 0 Offest, this is present
|
||||
* only for Fast Interrupt */
|
||||
|
||||
|
||||
|
||||
#endif /* ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) */
|
||||
|
||||
/* Bit definitions for the bits of the MER register */
|
||||
|
||||
#define XIN_INT_MASTER_ENABLE_MASK 0x1UL
|
||||
#define XIN_INT_HARDWARE_ENABLE_MASK 0x2UL /* once set cannot be cleared */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/* The following data type defines each entry in an interrupt vector table.
|
||||
* The callback reference is the base address of the interrupting device
|
||||
* for the driver interface given in this file and an instance pointer for the
|
||||
* driver interface given in xintc.h file.
|
||||
*/
|
||||
typedef struct {
|
||||
XInterruptHandler Handler;
|
||||
void *CallBackRef;
|
||||
} XIntc_VectorTableEntry;
|
||||
|
||||
typedef void (*XFastInterruptHandler) (void);
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*
|
||||
* Define the appropriate I/O access method to memory mapped I/O or DCR.
|
||||
*/
|
||||
#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0))
|
||||
|
||||
#define XIntc_In32 XIo_DcrIn
|
||||
#define XIntc_Out32 XIo_DcrOut
|
||||
|
||||
#else
|
||||
|
||||
#define XIntc_In32 Xil_In32
|
||||
#define XIntc_Out32 Xil_Out32
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable all interrupts in the Master Enable register of the interrupt
|
||||
* controller. The interrupt controller defaults to all interrupts disabled
|
||||
* from reset such that this macro must be used to enable interrupts.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XIntc_MasterEnable(u32 BaseAddress);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIntc_MasterEnable(BaseAddress) \
|
||||
XIntc_Out32((BaseAddress) + XIN_MER_OFFSET, \
|
||||
XIN_INT_MASTER_ENABLE_MASK | XIN_INT_HARDWARE_ENABLE_MASK)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable all interrupts in the Master Enable register of the interrupt
|
||||
* controller.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XIntc_MasterDisable(u32 BaseAddress);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIntc_MasterDisable(BaseAddress) \
|
||||
XIntc_Out32((BaseAddress) + XIN_MER_OFFSET, 0)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable specific interrupt(s) in the interrupt controller.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param EnableMask is the 32-bit value to write to the enable register.
|
||||
* Each bit of the mask corresponds to an interrupt input signal
|
||||
* that is connected to the interrupt controller (INT0 = LSB).
|
||||
* Only the bits which are set in the mask will enable interrupts.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XIntc_EnableIntr(u32 BaseAddress, u32 EnableMask);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIntc_EnableIntr(BaseAddress, EnableMask) \
|
||||
XIntc_Out32((BaseAddress) + XIN_IER_OFFSET, (EnableMask))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable specific interrupt(s) in the interrupt controller.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param DisableMask is the 32-bit value to write to the enable register.
|
||||
* Each bit of the mask corresponds to an interrupt input signal
|
||||
* that is connected to the interrupt controller (INT0 = LSB).
|
||||
* Only the bits which are set in the mask will disable interrupts.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XIntc_DisableIntr(u32 BaseAddress, u32 DisableMask);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIntc_DisableIntr(BaseAddress, DisableMask) \
|
||||
XIntc_Out32((BaseAddress) + XIN_IER_OFFSET, ~(DisableMask))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Acknowledge specific interrupt(s) in the interrupt controller.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param AckMask is the 32-bit value to write to the acknowledge
|
||||
* register. Each bit of the mask corresponds to an interrupt input
|
||||
* signal that is connected to the interrupt controller (INT0 =
|
||||
* LSB). Only the bits which are set in the mask will acknowledge
|
||||
* interrupts.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XIntc_AckIntr(u32 BaseAddress, u32 AckMask);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIntc_AckIntr(BaseAddress, AckMask) \
|
||||
XIntc_Out32((BaseAddress) + XIN_IAR_OFFSET, (AckMask))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the interrupt status from the interrupt controller which indicates
|
||||
* which interrupts are active and enabled.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return The 32-bit contents of the interrupt status register. Each bit
|
||||
* corresponds to an interrupt input signal that is connected to
|
||||
* the interrupt controller (INT0 = LSB). Bits which are set
|
||||
* indicate an active interrupt which is also enabled.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* u32 XIntc_GetIntrStatus(u32 BaseAddress);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIntc_GetIntrStatus(BaseAddress) \
|
||||
(XIntc_In32((BaseAddress) + XIN_ISR_OFFSET) & \
|
||||
XIntc_In32((BaseAddress) + XIN_IER_OFFSET))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Interrupt controller handlers, to be connected to processor exception
|
||||
* handling code.
|
||||
*/
|
||||
void XIntc_LowLevelInterruptHandler(void);
|
||||
void XIntc_DeviceInterruptHandler(void *DeviceId);
|
||||
|
||||
/* Various configuration functions */
|
||||
void XIntc_SetIntrSvcOption(UINTPTR BaseAddress, int Option);
|
||||
|
||||
void XIntc_RegisterHandler(UINTPTR BaseAddress, int InterruptId,
|
||||
XInterruptHandler Handler, void *CallBackRef);
|
||||
|
||||
void XIntc_RegisterFastHandler(UINTPTR BaseAddress, u8 Id,
|
||||
XFastInterruptHandler FastHandler);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
@ -0,0 +1,149 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xintc_options.c
|
||||
* @addtogroup intc_v3_4
|
||||
* @{
|
||||
*
|
||||
* Contains option functions for the XIntc driver. These functions allow the
|
||||
* user to configure an instance of the XIntc driver. This file requires other
|
||||
* files of the component to be linked in also.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------------
|
||||
* 1.00b jhl 02/21/02 First release
|
||||
* 1.00c rpm 10/17/03 New release. Support the relocation of the options flag
|
||||
* from the instance structure to the xintc_g.c
|
||||
* configuration table.
|
||||
* 1.10c mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs
|
||||
* 2.06a bss 01/28/13 To support Cascade mode:
|
||||
* Modified XIntc_SetOptions API.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xintc.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the options for the interrupt controller driver. In Cascade mode same
|
||||
* Option is set to Slave controllers.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
|
||||
* @param Options to be set. The available options are described in
|
||||
* xintc.h.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if the options were set successfully
|
||||
* - XST_INVALID_PARAM if the specified option was not valid
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int XIntc_SetOptions(XIntc * InstancePtr, u32 Options)
|
||||
{
|
||||
XIntc_Config *CfgPtr;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Make sure option request is valid
|
||||
*/
|
||||
if ((Options == XIN_SVC_SGL_ISR_OPTION) ||
|
||||
(Options == XIN_SVC_ALL_ISRS_OPTION)) {
|
||||
InstancePtr->CfgPtr->Options = Options;
|
||||
/* If Cascade mode set the option for all Slaves */
|
||||
if (InstancePtr->CfgPtr->IntcType != XIN_INTC_NOCASCADE) {
|
||||
int Index;
|
||||
for (Index = 1; Index <= XPAR_XINTC_NUM_INSTANCES - 1;
|
||||
Index++) {
|
||||
CfgPtr = XIntc_LookupConfig(Index);
|
||||
CfgPtr->Options = Options;
|
||||
}
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return XST_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Return the currently set options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
|
||||
*
|
||||
* @return The currently set options. The options are described in xintc.h.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
u32 XIntc_GetOptions(XIntc * InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
return InstancePtr->CfgPtr->Options;
|
||||
}
|
||||
/** @} */
|
@ -0,0 +1,255 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xintc_selftest.c
|
||||
* @addtogroup intc_v3_4
|
||||
* @{
|
||||
*
|
||||
* Contains diagnostic self-test functions for the XIntc component. This file
|
||||
* requires other files of the component to be linked in also.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 02/21/02 First release
|
||||
* 1.10c mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs
|
||||
* 2.04a bss 01/16/12 Removed CurrentMIE variable and reading of the
|
||||
* MER register to remove warnings
|
||||
* 2.06a bss 01/28/13 To support Cascade mode:
|
||||
* Modified XIntc_SimulateIntr API.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xintc.h"
|
||||
#include "xintc_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#define XIN_TEST_MASK 1
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Run a self-test on the driver/device. This is a destructive test.
|
||||
*
|
||||
* This involves forcing interrupts into the controller and verifying that they
|
||||
* are recognized and can be acknowledged. This test will not succeed if the
|
||||
* interrupt controller has been started in real mode such that interrupts
|
||||
* cannot be forced.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if self-test is successful.
|
||||
* - XST_INTC_FAIL_SELFTEST if the Interrupt controller fails the
|
||||
* self-test. It will fail the self test if the device has
|
||||
* previously been started in real mode.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIntc_SelfTest(XIntc * InstancePtr)
|
||||
{
|
||||
u32 CurrentISR;
|
||||
u32 Temp;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
|
||||
/*
|
||||
* Acknowledge all pending interrupts by reading the interrupt status
|
||||
* register and writing the value to the acknowledge register
|
||||
*/
|
||||
Temp = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
|
||||
|
||||
XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, Temp);
|
||||
|
||||
/*
|
||||
* Verify that there are no interrupts by reading the interrupt status
|
||||
*/
|
||||
CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
|
||||
|
||||
/*
|
||||
* ISR should be zero after all interrupts are acknowledged
|
||||
*/
|
||||
if (CurrentISR != 0) {
|
||||
return XST_INTC_FAIL_SELFTEST;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a bit in the ISR which simulates an interrupt
|
||||
*/
|
||||
XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, XIN_TEST_MASK);
|
||||
|
||||
/*
|
||||
* Verify that it was set
|
||||
*/
|
||||
CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
|
||||
|
||||
if (CurrentISR != XIN_TEST_MASK) {
|
||||
return XST_INTC_FAIL_SELFTEST;
|
||||
}
|
||||
|
||||
/*
|
||||
* Acknowledge the interrupt
|
||||
*/
|
||||
XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, XIN_TEST_MASK);
|
||||
|
||||
/*
|
||||
* Read back the ISR to verify that the interrupt is gone
|
||||
*/
|
||||
CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
|
||||
|
||||
if (CurrentISR != 0) {
|
||||
return XST_INTC_FAIL_SELFTEST;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Allows software to simulate an interrupt in the interrupt controller. This
|
||||
* function will only be successful when the interrupt controller has been
|
||||
* started in simulation mode. Once it has been started in real mode,
|
||||
* interrupts cannot be simulated. A simulated interrupt allows the interrupt
|
||||
* controller to be tested without any device to drive an interrupt input
|
||||
* signal into it. In Cascade mode writes to ISR of appropraite Slave
|
||||
* controller depending on Id.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
|
||||
* @param Id is the interrupt ID for which to simulate an interrupt.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful
|
||||
* - XST_FAILURE if the interrupt could not be
|
||||
* simulated because the interrupt controller is or
|
||||
* has previously been in real mode.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id)
|
||||
{
|
||||
u32 Mask;
|
||||
u32 MasterEnable;
|
||||
XIntc_Config *CfgPtr;
|
||||
int Index;
|
||||
int DeviceId;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);
|
||||
|
||||
|
||||
/* Get the contents of the master enable register and determine if
|
||||
* hardware interrupts have already been enabled, if so, this is a write
|
||||
* once bit such that simulation can't be done at this point because
|
||||
* the ISR register is no longer writable by software
|
||||
*/
|
||||
MasterEnable = XIntc_In32(InstancePtr->BaseAddress + XIN_MER_OFFSET);
|
||||
if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
if (Id > 31) {
|
||||
|
||||
DeviceId = Id/32;
|
||||
|
||||
CfgPtr = XIntc_LookupConfig(Id/32);
|
||||
Mask = XIntc_BitPosMask[Id%32];
|
||||
XIntc_Out32(CfgPtr->BaseAddress + XIN_ISR_OFFSET, Mask);
|
||||
|
||||
/* Generate interrupt for 31 by writing to Interrupt Status
|
||||
* register of parent controllers. Primary controller ISR
|
||||
* will be written last in the loop
|
||||
*/
|
||||
Mask = XIntc_BitPosMask[31];
|
||||
for (Index = DeviceId - 1; Index >= 0; Index--)
|
||||
{
|
||||
CfgPtr = XIntc_LookupConfig(Index);
|
||||
|
||||
XIntc_Out32(CfgPtr->BaseAddress + XIN_ISR_OFFSET,
|
||||
Mask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* The Id is used to create the appropriate mask for the
|
||||
* desired bit position.
|
||||
*/
|
||||
Mask = XIntc_BitPosMask[Id];
|
||||
|
||||
/*
|
||||
* Enable the selected interrupt source by reading the interrupt
|
||||
* enable register and then modifying only the specified
|
||||
* interrupt id enable
|
||||
*/
|
||||
XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, Mask);
|
||||
|
||||
}
|
||||
/* indicate the interrupt was successfully simulated */
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/** @} */
|
@ -0,0 +1,28 @@
|
||||
COMPILER=
|
||||
ARCHIVER=
|
||||
CP=cp
|
||||
COMPILER_FLAGS=
|
||||
EXTRA_COMPILER_FLAGS=
|
||||
LIB=libxil.a
|
||||
|
||||
RELEASEDIR=../../../lib
|
||||
INCLUDEDIR=../../../include
|
||||
INCLUDES=-I./. -I${INCLUDEDIR}
|
||||
|
||||
OUTS = *.o
|
||||
|
||||
LIBSOURCES=*.c
|
||||
INCLUDEFILES=*.h
|
||||
|
||||
libs:
|
||||
echo "Compiling tmrctr"
|
||||
$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES)
|
||||
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS}
|
||||
make clean
|
||||
|
||||
include:
|
||||
${CP} $(INCLUDEFILES) $(INCLUDEDIR)
|
||||
|
||||
clean:
|
||||
rm -rf ${OUTS}
|
||||
|
@ -0,0 +1,538 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr.c
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
*
|
||||
* Contains required functions for the XTmrCtr driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a ecm 08/16/01 First release
|
||||
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
|
||||
* 1.10b mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/30/09 Updated to use HAL API's. _m is removed from all the macro
|
||||
* definitions.
|
||||
* 2.05a adk 15/05/13 Fixed the CR:693066
|
||||
* Added the IsStartedTmrCtr0/IsStartedTmrCtr1 members to the
|
||||
* XTmrCtr instance structure.
|
||||
* The IsStartedTmrCtrX will be assigned XIL_COMPONENT_IS_STARTED in
|
||||
* the XTmrCtr_Start function.
|
||||
* The IsStartedTmrCtrX will be cleared in the XTmrCtr_Stop function.
|
||||
* There will be no Initialization done in the
|
||||
* XTmrCtr_Initialize if both the timers have already started and
|
||||
* the XST_DEVICE_IS_STARTED Status is returned.
|
||||
* Removed the logic in the XTmrCtr_Initialize function
|
||||
* which was checking the Register Value to know whether
|
||||
* a timer has started or not.
|
||||
* 4.0 als 09/30/15 Updated initialization API.
|
||||
* 4.1 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototype of XTmrCtr_CfgInitialize API.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "xparameters.h"
|
||||
#include "xtmrctr.h"
|
||||
#include "xtmrctr_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static void XTmrCtr_StubCallback(void *CallBackRef, u8 TmrCtrNumber);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function populates the timer counter's configuration structure and sets
|
||||
* some configurations defaults.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param ConfigPtr is a pointer to the configuration structure that will
|
||||
* be used to copy the settings from.
|
||||
* @param EffectiveAddr is the device base address in the virtual memory
|
||||
* space. If the address translation is not used, then the physical
|
||||
* address is passed.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Unexpected errors may occur if the address mapping is changed
|
||||
* after this function is invoked.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_CfgInitialize(XTmrCtr *InstancePtr, XTmrCtr_Config *ConfigPtr,
|
||||
UINTPTR EffectiveAddr)
|
||||
{
|
||||
/* Verify arguments. */
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(ConfigPtr != NULL);
|
||||
Xil_AssertVoid(EffectiveAddr != 0x0);
|
||||
|
||||
InstancePtr->IsReady = 0;
|
||||
InstancePtr->Config = *ConfigPtr;
|
||||
|
||||
InstancePtr->Config.BaseAddress = EffectiveAddr;
|
||||
InstancePtr->BaseAddress = EffectiveAddr;
|
||||
|
||||
InstancePtr->Handler = XTmrCtr_StubCallback;
|
||||
InstancePtr->CallBackRef = InstancePtr;
|
||||
InstancePtr->Stats.Interrupts = 0;
|
||||
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* (Re-)initialzes all timer counters which aren't started already.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if at least one timer counter is stopped.
|
||||
* - XST_DEVICE_IS_STARTED otherwise.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XTmrCtr_InitHw(XTmrCtr *InstancePtr)
|
||||
{
|
||||
int Status = XST_DEVICE_IS_STARTED;
|
||||
u8 TmrIndex;
|
||||
u32 TmrCtrStarted[XTC_DEVICE_TIMER_COUNT];
|
||||
|
||||
/* Verify arguments. */
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
TmrCtrStarted[0] = InstancePtr->IsStartedTmrCtr0;
|
||||
TmrCtrStarted[1] = InstancePtr->IsStartedTmrCtr1;
|
||||
|
||||
for (TmrIndex = 0; TmrIndex < XTC_DEVICE_TIMER_COUNT; TmrIndex++) {
|
||||
/* Only initialize timers counters which aren't started. */
|
||||
if (TmrCtrStarted[TmrIndex] == XIL_COMPONENT_IS_STARTED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set the compare register to 0. */
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrIndex,
|
||||
XTC_TLR_OFFSET, 0);
|
||||
/* Reset the timer and the interrupt. */
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrIndex,
|
||||
XTC_TCSR_OFFSET,
|
||||
XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);
|
||||
/* Release the reset. */
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrIndex,
|
||||
XTC_TCSR_OFFSET, 0);
|
||||
|
||||
/* Indicate that at least one timer is not running and has been
|
||||
* initialized. */
|
||||
Status = XST_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Initializes a specific timer/counter instance/driver. Initialize fields of
|
||||
* the XTmrCtr structure, then reset the timer/counter.If a timer is already
|
||||
* running then it is not initialized.
|
||||
*
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param DeviceId is the unique id of the device controlled by this
|
||||
* XTmrCtr component. Passing in a device id associates the
|
||||
* generic XTmrCtr component to a specific device, as chosen by
|
||||
* the caller or application developer.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if initialization was successful
|
||||
* - XST_DEVICE_IS_STARTED if the device has already been started
|
||||
* - XST_DEVICE_NOT_FOUND if the device doesn't exist
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XTmrCtr_Initialize(XTmrCtr *InstancePtr, u16 DeviceId)
|
||||
{
|
||||
XTmrCtr_Config *ConfigPtr;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
/* In case all timer counters are already started, don't proceed with
|
||||
* re-initialization. */
|
||||
if ((InstancePtr->IsStartedTmrCtr0 == XIL_COMPONENT_IS_STARTED) &&
|
||||
(InstancePtr->IsStartedTmrCtr1 == XIL_COMPONENT_IS_STARTED)) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/* Retrieve configuration of timer counter core with matching ID. */
|
||||
ConfigPtr = XTmrCtr_LookupConfig(DeviceId);
|
||||
if (!ConfigPtr) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
XTmrCtr_CfgInitialize(InstancePtr, ConfigPtr, ConfigPtr->BaseAddress);
|
||||
|
||||
return XTmrCtr_InitHw(InstancePtr);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Starts the specified timer counter of the device such that it starts running.
|
||||
* The timer counter is reset before it is started and the reset value is
|
||||
* loaded into the timer counter.
|
||||
*
|
||||
* If interrupt mode is specified in the options, it is necessary for the caller
|
||||
* to connect the interrupt handler of the timer/counter to the interrupt source,
|
||||
* typically an interrupt controller, and enable the interrupt within the
|
||||
* interrupt controller.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_Start(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
|
||||
{
|
||||
u32 ControlStatusReg;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Read the current register contents such that only the necessary bits
|
||||
* of the register are modified in the following operations
|
||||
*/
|
||||
ControlStatusReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TCSR_OFFSET);
|
||||
/*
|
||||
* Reset the timer counter such that it reloads from the compare
|
||||
* register and the interrupt is cleared simultaneously, the interrupt
|
||||
* can only be cleared after reset such that the interrupt condition is
|
||||
* cleared
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET,
|
||||
XTC_CSR_LOAD_MASK);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Indicate that the timer is started before enabling it
|
||||
*/
|
||||
if (TmrCtrNumber == 0) {
|
||||
InstancePtr->IsStartedTmrCtr0 = XIL_COMPONENT_IS_STARTED;
|
||||
} else {
|
||||
InstancePtr->IsStartedTmrCtr1 = XIL_COMPONENT_IS_STARTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Remove the reset condition such that the timer counter starts running
|
||||
* with the value loaded from the compare register
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET,
|
||||
ControlStatusReg | XTC_CSR_ENABLE_TMR_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Stops the timer counter by disabling it.
|
||||
*
|
||||
* It is the callers' responsibility to disconnect the interrupt handler of the
|
||||
* timer_counter from the interrupt source, typically an interrupt controller,
|
||||
* and disable the interrupt within the interrupt controller.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_Stop(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
|
||||
{
|
||||
u32 ControlStatusReg;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Read the current register contents
|
||||
*/
|
||||
ControlStatusReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TCSR_OFFSET);
|
||||
/*
|
||||
* Disable the timer counter such that it's not running
|
||||
*/
|
||||
ControlStatusReg &= ~(XTC_CSR_ENABLE_TMR_MASK);
|
||||
|
||||
/*
|
||||
* Write out the updated value to the actual register.
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET, ControlStatusReg);
|
||||
|
||||
/*
|
||||
* Indicate that the timer is stopped
|
||||
*/
|
||||
if (TmrCtrNumber == 0) {
|
||||
InstancePtr->IsStartedTmrCtr0 = 0;
|
||||
} else {
|
||||
InstancePtr->IsStartedTmrCtr1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the current value of the specified timer counter. The timer counter
|
||||
* may be either incrementing or decrementing based upon the current mode of
|
||||
* operation.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return The current value for the timer counter.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 XTmrCtr_GetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
|
||||
{
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
return XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TCR_OFFSET);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the reset value for the specified timer counter. This is the value
|
||||
* that is loaded into the timer counter when it is reset. This value is also
|
||||
* loaded when the timer counter is started.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
* @param ResetValue contains the value to be used to reset the timer
|
||||
* counter.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_SetResetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber,
|
||||
u32 ResetValue)
|
||||
{
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TLR_OFFSET, ResetValue);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Returns the timer counter value that was captured the last time the external
|
||||
* capture input was asserted.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return The current capture value for the indicated timer counter.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*******************************************************************************/
|
||||
u32 XTmrCtr_GetCaptureValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
|
||||
{
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
return XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TLR_OFFSET);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Resets the specified timer counter of the device. A reset causes the timer
|
||||
* counter to set it's value to the reset value.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_Reset(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
|
||||
{
|
||||
u32 CounterControlReg;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Read current contents of the register so it won't be destroyed
|
||||
*/
|
||||
CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TCSR_OFFSET);
|
||||
/*
|
||||
* Reset the timer by toggling the reset bit in the register
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET,
|
||||
CounterControlReg | XTC_CSR_LOAD_MASK);
|
||||
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET, CounterControlReg);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Checks if the specified timer counter of the device has expired. In capture
|
||||
* mode, expired is defined as a capture occurred. In compare mode, expired is
|
||||
* defined as the timer counter rolled over/under for up/down counting.
|
||||
*
|
||||
* When interrupts are enabled, the expiration causes an interrupt. This function
|
||||
* is typically used to poll a timer counter to determine when it has expired.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return TRUE if the timer has expired, and FALSE otherwise.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XTmrCtr_IsExpired(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
|
||||
{
|
||||
u32 CounterControlReg;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Check if timer is expired
|
||||
*/
|
||||
CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TCSR_OFFSET);
|
||||
|
||||
return ((CounterControlReg & XTC_CSR_INT_OCCURED_MASK) ==
|
||||
XTC_CSR_INT_OCCURED_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Default callback for the driver does nothing. It matches the signature of the
|
||||
* XTmrCtr_Handler type.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the callback's data.
|
||||
* @param TmrCtrNumber is the ID of the timer counter which a user-defined
|
||||
* callback would normally operate on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void XTmrCtr_StubCallback(void *CallBackRef, u8 TmrCtrNumber)
|
||||
{
|
||||
Xil_AssertVoid(CallBackRef != NULL);
|
||||
Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
}
|
||||
|
||||
/** @} */
|
@ -0,0 +1,305 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr.h
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* The Xilinx timer/counter component. This component supports the Xilinx
|
||||
* timer/counter. More detailed description of the driver operation can
|
||||
* be found in the xtmrctr.c file.
|
||||
*
|
||||
* The Xilinx timer/counter supports the following features:
|
||||
* - Polled mode.
|
||||
* - Interrupt driven mode
|
||||
* - enabling and disabling specific timers
|
||||
* - PWM operation
|
||||
* - Cascade Operation (This is to be used for getting a 64 bit timer and this
|
||||
* feature is present in the latest versions of the axi_timer IP)
|
||||
*
|
||||
* The driver does not currently support the PWM operation of the device.
|
||||
*
|
||||
* The timer counter operates in 2 primary modes, compare and capture. In
|
||||
* either mode, the timer counter may count up or down, with up being the
|
||||
* default.
|
||||
*
|
||||
* Compare mode is typically used for creating a single time period or multiple
|
||||
* repeating time periods in the auto reload mode, such as a periodic interrupt.
|
||||
* When started, the timer counter loads an initial value, referred to as the
|
||||
* compare value, into the timer counter and starts counting down or up. The
|
||||
* timer counter expires when it rolls over/under depending upon the mode of
|
||||
* counting. An external compare output signal may be configured such that a
|
||||
* pulse is generated with this signal when it hits the compare value.
|
||||
*
|
||||
* Capture mode is typically used for measuring the time period between
|
||||
* external events. This mode uses an external capture input signal to cause
|
||||
* the value of the timer counter to be captured. When started, the timer
|
||||
* counter loads an initial value, referred to as the compare value,
|
||||
|
||||
* The timer can be configured to either cause an interrupt when the count
|
||||
* reaches the compare value in compare mode or latch the current count
|
||||
* value in the capture register when an external input is asserted
|
||||
* in capture mode. The external capture input can be enabled/disabled using the
|
||||
* XTmrCtr_SetOptions function. While in compare mode, it is also possible to
|
||||
* drive an external output when the compare value is reached in the count
|
||||
* register The external compare output can be enabled/disabled using the
|
||||
* XTmrCtr_SetOptions function.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* It is the responsibility of the application to connect the interrupt
|
||||
* handler of the timer/counter to the interrupt source. The interrupt
|
||||
* handler function, XTmrCtr_InterruptHandler, is visible such that the user
|
||||
* can connect it to the interrupt source. Note that this interrupt handler
|
||||
* does not provide interrupt context save and restore processing, the user
|
||||
* must perform this processing.
|
||||
*
|
||||
* The driver services interrupts and passes timeouts to the upper layer
|
||||
* software through callback functions. The upper layer software must register
|
||||
* its callback functions during initialization. The driver requires callback
|
||||
* functions for timers.
|
||||
*
|
||||
* @note
|
||||
* The default settings for the timers are:
|
||||
* - Interrupt generation disabled
|
||||
* - Count up mode
|
||||
* - Compare mode
|
||||
* - Hold counter (will not reload the timer)
|
||||
* - External compare output disabled
|
||||
* - External capture input disabled
|
||||
* - Pulse width modulation disabled
|
||||
* - Timer disabled, waits for Start function to be called
|
||||
* <br><br>
|
||||
* A timer counter device may contain multiple timer counters. The symbol
|
||||
* XTC_DEVICE_TIMER_COUNT defines the number of timer counters in the device.
|
||||
* The device currently contains 2 timer counters.
|
||||
* <br><br>
|
||||
* This driver is intended to be RTOS and processor independent. It works with
|
||||
* physical addresses only. Any needs for dynamic memory management, threads
|
||||
* or thread mutual exclusion, virtual memory, or cache control must be
|
||||
* satisfied by the layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a ecm 08/16/01 First release
|
||||
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
|
||||
* 1.10b mta 03/21/07 Updated to new coding style.
|
||||
* 1.11a sdm 08/22/08 Removed support for static interrupt handlers from the MDD
|
||||
* file
|
||||
* 2.00a ktn 10/30/09 Updated to use HAL API's. _m is removed from all the macro
|
||||
* definitions.
|
||||
* 2.01a ktn 07/12/10 Renamed the macro XTimerCtr_ReadReg as XTmrCtr_ReadReg
|
||||
* for naming consistency (CR 559142).
|
||||
* 2.02a sdm 09/28/10 Updated the driver tcl to generate the xparameters
|
||||
* for the timer clock frequency (CR 572679).
|
||||
* 2.03a rvo 11/30/10 Added check to see if interrupt is enabled before further
|
||||
* processing for CR 584557.
|
||||
* 2.04a sdm 07/12/11 Added support for cascade mode operation.
|
||||
* The cascade mode of operation is present in the latest
|
||||
* versions of the axi_timer IP. Please check the HW
|
||||
* Datasheet to see whether this feature is present in the
|
||||
* version of the IP that you are using.
|
||||
* 2.05a adk 15/05/13 Fixed the CR:693066
|
||||
* Added the IsStartedTmrCtr0/IsStartedTmrCtr1 members to the
|
||||
* XTmrCtr instance structure.
|
||||
* The IsStartedTmrCtrX will be assigned XIL_COMPONENT_IS_STARTED in
|
||||
* the XTmrCtr_Start function.
|
||||
* The IsStartedTmrCtrX will be cleared in the XTmrCtr_Stop function.
|
||||
* There will be no Initialization done in the
|
||||
* XTmrCtr_Initialize if both the timers have already started and
|
||||
* the XST_DEVICE_IS_STARTED Status is returned.
|
||||
* Removed the logic in the XTmrCtr_Initialize function
|
||||
* which was checking the Register Value to know whether
|
||||
* a timer has started or not.
|
||||
* 3.0 adk 19/12/13 Updated as per the New Tcl API's
|
||||
* 4.0 als 09/30/15 Updated initialization API.
|
||||
* 4.1 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
|
||||
* Changed the prototype of XTmrCtr_CfgInitialize API.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XTMRCTR_H /* prevent circular inclusions */
|
||||
#define XTMRCTR_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xtmrctr_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* These options are used in XTmrCtr_SetOptions() and XTmrCtr_GetOptions()
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* Used to configure the timer counter device.
|
||||
* <pre>
|
||||
* XTC_CASCADE_MODE_OPTION Enables the Cascade Mode only valid for TCSRO.
|
||||
* XTC_ENABLE_ALL_OPTION Enables all timer counters at once.
|
||||
* XTC_DOWN_COUNT_OPTION Configures the timer counter to count down from
|
||||
* start value, the default is to count up.
|
||||
* XTC_CAPTURE_MODE_OPTION Configures the timer to capture the timer
|
||||
* counter value when the external capture line is
|
||||
* asserted. The default mode is compare mode.
|
||||
* XTC_INT_MODE_OPTION Enables the timer counter interrupt output.
|
||||
* XTC_AUTO_RELOAD_OPTION In compare mode, configures the timer counter to
|
||||
* reload from the compare value. The default mode
|
||||
* causes the timer counter to hold when the
|
||||
* compare value is hit.
|
||||
* In capture mode, configures the timer counter to
|
||||
* not hold the previous capture value if a new
|
||||
* event occurs. The default mode cause the timer
|
||||
* counter to hold the capture value until
|
||||
* recognized.
|
||||
* XTC_EXT_COMPARE_OPTION Enables the external compare output signal.
|
||||
* </pre>
|
||||
*/
|
||||
#define XTC_CASCADE_MODE_OPTION 0x00000080UL
|
||||
#define XTC_ENABLE_ALL_OPTION 0x00000040UL
|
||||
#define XTC_DOWN_COUNT_OPTION 0x00000020UL
|
||||
#define XTC_CAPTURE_MODE_OPTION 0x00000010UL
|
||||
#define XTC_INT_MODE_OPTION 0x00000008UL
|
||||
#define XTC_AUTO_RELOAD_OPTION 0x00000004UL
|
||||
#define XTC_EXT_COMPARE_OPTION 0x00000002UL
|
||||
/*@}*/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
UINTPTR BaseAddress; /**< Register base address */
|
||||
u32 SysClockFreqHz; /**< The AXI bus clock frequency */
|
||||
} XTmrCtr_Config;
|
||||
|
||||
/**
|
||||
* Signature for the callback function.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper layer
|
||||
* when setting the callback functions, and passed back to the
|
||||
* upper layer when the callback is invoked. Its type is
|
||||
* unimportant to the driver, so it is a void pointer.
|
||||
* @param TmrCtrNumber is the number of the timer/counter within the
|
||||
* device. The device typically contains at least two
|
||||
* timer/counters. The timer number is a zero based number with a
|
||||
* range of 0 to (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*/
|
||||
typedef void (*XTmrCtr_Handler) (void *CallBackRef, u8 TmrCtrNumber);
|
||||
|
||||
|
||||
/**
|
||||
* Timer/Counter statistics
|
||||
*/
|
||||
typedef struct {
|
||||
u32 Interrupts; /**< The number of interrupts that have occurred */
|
||||
} XTmrCtrStats;
|
||||
|
||||
/**
|
||||
* The XTmrCtr driver instance data. The user is required to allocate a
|
||||
* variable of this type for every timer/counter device in the system. A
|
||||
* pointer to a variable of this type is then passed to the driver API
|
||||
* functions.
|
||||
*/
|
||||
typedef struct {
|
||||
XTmrCtr_Config Config; /**< Core configuration. */
|
||||
XTmrCtrStats Stats; /**< Component Statistics */
|
||||
UINTPTR BaseAddress; /**< Base address of registers */
|
||||
u32 IsReady; /**< Device is initialized and ready */
|
||||
u32 IsStartedTmrCtr0; /**< Is Timer Counter 0 started */
|
||||
u32 IsStartedTmrCtr1; /**< Is Timer Counter 1 started */
|
||||
|
||||
XTmrCtr_Handler Handler; /**< Callback function */
|
||||
void *CallBackRef; /**< Callback reference for handler */
|
||||
} XTmrCtr;
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/* Required functions, in file xtmrctr.c */
|
||||
void XTmrCtr_CfgInitialize(XTmrCtr *InstancePtr, XTmrCtr_Config *ConfigPtr,
|
||||
UINTPTR EffectiveAddr);
|
||||
int XTmrCtr_InitHw(XTmrCtr *InstancePtr);
|
||||
int XTmrCtr_Initialize(XTmrCtr * InstancePtr, u16 DeviceId);
|
||||
void XTmrCtr_Start(XTmrCtr * InstancePtr, u8 TmrCtrNumber);
|
||||
void XTmrCtr_Stop(XTmrCtr * InstancePtr, u8 TmrCtrNumber);
|
||||
u32 XTmrCtr_GetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber);
|
||||
void XTmrCtr_SetResetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber,
|
||||
u32 ResetValue);
|
||||
u32 XTmrCtr_GetCaptureValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber);
|
||||
int XTmrCtr_IsExpired(XTmrCtr * InstancePtr, u8 TmrCtrNumber);
|
||||
void XTmrCtr_Reset(XTmrCtr * InstancePtr, u8 TmrCtrNumber);
|
||||
|
||||
/* Lookup configuration in xtmrctr_sinit.c */
|
||||
XTmrCtr_Config *XTmrCtr_LookupConfig(u16 DeviceId);
|
||||
|
||||
/* Functions for options, in file xtmrctr_options.c */
|
||||
void XTmrCtr_SetOptions(XTmrCtr * InstancePtr, u8 TmrCtrNumber, u32 Options);
|
||||
u32 XTmrCtr_GetOptions(XTmrCtr * InstancePtr, u8 TmrCtrNumber);
|
||||
|
||||
/* Functions for statistics, in file xtmrctr_stats.c */
|
||||
void XTmrCtr_GetStats(XTmrCtr * InstancePtr, XTmrCtrStats * StatsPtr);
|
||||
void XTmrCtr_ClearStats(XTmrCtr * InstancePtr);
|
||||
|
||||
/* Functions for self-test, in file xtmrctr_selftest.c */
|
||||
int XTmrCtr_SelfTest(XTmrCtr * InstancePtr, u8 TmrCtrNumber);
|
||||
|
||||
/* Functions for interrupts, in file xtmrctr_intr.c */
|
||||
void XTmrCtr_SetHandler(XTmrCtr * InstancePtr, XTmrCtr_Handler FuncPtr,
|
||||
void *CallBackRef);
|
||||
void XTmrCtr_InterruptHandler(void *InstancePtr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
@ -0,0 +1,56 @@
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by HSI.
|
||||
* Version:
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
|
||||
*Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
*of this software and associated documentation files (the Software), to deal
|
||||
*in the Software without restriction, including without limitation the rights
|
||||
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
*copies of the Software, and to permit persons to whom the Software is
|
||||
*furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*The above copyright notice and this permission notice shall be included in
|
||||
*all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
*(a) running on a Xilinx device, or
|
||||
*(b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
*in advertising or otherwise to promote the sale, use or other dealings in
|
||||
*this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
|
||||
*
|
||||
* Description: Driver configuration
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xtmrctr.h"
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XTmrCtr_Config XTmrCtr_ConfigTable[] =
|
||||
{
|
||||
{
|
||||
XPAR_AXI_TIMER_0_DEVICE_ID,
|
||||
XPAR_AXI_TIMER_0_BASEADDR,
|
||||
XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr_i.h
|
||||
* @addtogroup tmrctr_v3_0
|
||||
* @{
|
||||
*
|
||||
* This file contains data which is shared between files internal to the
|
||||
* XTmrCtr component. It is intended for internal use only.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 02/06/02 First release
|
||||
* 1.10b mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/30/09 _m is removed from all the macro definitions.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XTMRCTR_I_H /* prevent circular inclusions */
|
||||
#define XTMRCTR_I_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern u8 XTmrCtr_Offsets[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/** @} */
|
@ -0,0 +1,233 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr_intr.c
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
*
|
||||
* Contains interrupt-related functions for the XTmrCtr component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 02/06/02 First release
|
||||
* 1.10b mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/30/09 Updated to use HAL API's. _m is removed from all the macro
|
||||
* definitions.
|
||||
* 2.03a rvo 11/30/10 Added check to see if interrupt is enabled before further
|
||||
* processing for CR 584557.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xtmrctr.h"
|
||||
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Sets the timer callback function, which the driver calls when the specified
|
||||
* timer times out.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance .
|
||||
* @param CallBackRef is the upper layer callback reference passed back
|
||||
* when the callback function is invoked.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The handler is called within interrupt context so the function that is
|
||||
* called should either be short or pass the more extensive processing off
|
||||
* to another task to allow the interrupt to return and normal processing
|
||||
* to continue.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_SetHandler(XTmrCtr * InstancePtr, XTmrCtr_Handler FuncPtr,
|
||||
void *CallBackRef)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
InstancePtr->Handler = FuncPtr;
|
||||
InstancePtr->CallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Interrupt Service Routine (ISR) for the driver. This function only performs
|
||||
* processing for the device and does not save and restore the interrupt context.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the timer/counter instance for
|
||||
* the interrupt.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_InterruptHandler(void *InstancePtr)
|
||||
{
|
||||
XTmrCtr *TmrCtrPtr = NULL;
|
||||
u8 TmrCtrNumber;
|
||||
u32 ControlStatusReg;
|
||||
|
||||
/*
|
||||
* Verify that each of the inputs are valid.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Convert the non-typed pointer to an timer/counter instance pointer
|
||||
* such that there is access to the timer/counter
|
||||
*/
|
||||
TmrCtrPtr = (XTmrCtr *) InstancePtr;
|
||||
|
||||
/*
|
||||
* Loop thru each timer counter in the device and call the callback
|
||||
* function for each timer which has caused an interrupt
|
||||
*/
|
||||
for (TmrCtrNumber = 0;
|
||||
TmrCtrNumber < XTC_DEVICE_TIMER_COUNT; TmrCtrNumber++) {
|
||||
|
||||
ControlStatusReg = XTmrCtr_ReadReg(TmrCtrPtr->BaseAddress,
|
||||
TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET);
|
||||
/*
|
||||
* Check if interrupt is enabled
|
||||
*/
|
||||
if (ControlStatusReg & XTC_CSR_ENABLE_INT_MASK) {
|
||||
|
||||
/*
|
||||
* Check if timer expired and interrupt occured
|
||||
*/
|
||||
if (ControlStatusReg & XTC_CSR_INT_OCCURED_MASK) {
|
||||
/*
|
||||
* Increment statistics for the number of
|
||||
* interrupts and call the callback to handle
|
||||
* any application specific processing
|
||||
*/
|
||||
TmrCtrPtr->Stats.Interrupts++;
|
||||
TmrCtrPtr->Handler(TmrCtrPtr->CallBackRef,
|
||||
TmrCtrNumber);
|
||||
/*
|
||||
* Read the new Control/Status Register content.
|
||||
*/
|
||||
ControlStatusReg =
|
||||
XTmrCtr_ReadReg(TmrCtrPtr->BaseAddress,
|
||||
TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET);
|
||||
/*
|
||||
* If in compare mode and a single shot rather
|
||||
* than auto reload mode then disable the timer
|
||||
* and reset it such so that the interrupt can
|
||||
* be acknowledged, this should be only temporary
|
||||
* till the hardware is fixed
|
||||
*/
|
||||
if (((ControlStatusReg &
|
||||
XTC_CSR_AUTO_RELOAD_MASK) == 0) &&
|
||||
((ControlStatusReg &
|
||||
XTC_CSR_CAPTURE_MODE_MASK)== 0)) {
|
||||
/*
|
||||
* Disable the timer counter and
|
||||
* reset it such that the timer
|
||||
* counter is loaded with the
|
||||
* reset value allowing the
|
||||
* interrupt to be acknowledged
|
||||
*/
|
||||
ControlStatusReg &=
|
||||
~XTC_CSR_ENABLE_TMR_MASK;
|
||||
|
||||
XTmrCtr_WriteReg(
|
||||
TmrCtrPtr->BaseAddress,
|
||||
TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET,
|
||||
ControlStatusReg |
|
||||
XTC_CSR_LOAD_MASK);
|
||||
|
||||
/*
|
||||
* Clear the reset condition,
|
||||
* the reset bit must be
|
||||
* manually cleared by a 2nd write
|
||||
* to the register
|
||||
*/
|
||||
XTmrCtr_WriteReg(
|
||||
TmrCtrPtr->BaseAddress,
|
||||
TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET,
|
||||
ControlStatusReg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Acknowledge the interrupt by clearing the
|
||||
* interrupt bit in the timer control status
|
||||
* register, this is done after calling the
|
||||
* handler so the application could call
|
||||
* IsExpired, the interrupt is cleared by
|
||||
* writing a 1 to the interrupt bit of the
|
||||
* register without changing any of the other
|
||||
* bits
|
||||
*/
|
||||
XTmrCtr_WriteReg(TmrCtrPtr->BaseAddress,
|
||||
TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET,
|
||||
ControlStatusReg |
|
||||
XTC_CSR_INT_OCCURED_MASK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @} */
|
@ -0,0 +1,79 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr_l.c
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
*
|
||||
* This file contains low-level driver functions that can be used to access the
|
||||
* device. The user should refer to the hardware device specification for more
|
||||
* details of the device operation.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 04/24/02 First release
|
||||
* 1.10b mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/30/09 Updated to use HAL API's
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xtmrctr_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/* The following table contains the offset from the base address of a timer
|
||||
* counter device for each timer counter. A single device may contain multiple
|
||||
* timer counters and the functions specify which one to operate on.
|
||||
*/
|
||||
u8 XTmrCtr_Offsets[] = { 0, XTC_TIMER_COUNTER_OFFSET };
|
||||
/** @} */
|
@ -0,0 +1,429 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr_l.h
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and low-level driver functions (or
|
||||
* macros) that can be used to access the device. The user should refer to the
|
||||
* hardware device specification for more details of the device operation.
|
||||
* High-level driver functions are defined in xtmrctr.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 04/24/02 First release
|
||||
* 1.10b mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/30/09 Updated to use HAL API's. _m is removed from all the macro
|
||||
* definitions.
|
||||
* 2.01a ktn 07/12/10 Renamed the macro XTimerCtr_ReadReg as XTmrCtr_ReadReg
|
||||
* for naming consistency (CR 559142).
|
||||
* 2.04a sdm 07/12/11 Added the CASC mode bit in the TCSRO register for the
|
||||
* cascade mode operation.
|
||||
* The cascade mode of operation is present in the latest
|
||||
* versions of the axi_timer IP. Please check the HW
|
||||
* Datasheet to see whether this feature is present in the
|
||||
* version of the IP that you are using.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XTMRCTR_L_H /* prevent circular inclusions */
|
||||
#define XTMRCTR_L_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**
|
||||
* Defines the number of timer counters within a single hardware device. This
|
||||
* number is not currently parameterized in the hardware but may be in the
|
||||
* future.
|
||||
*/
|
||||
#define XTC_DEVICE_TIMER_COUNT 2
|
||||
|
||||
/* Each timer counter consumes 16 bytes of address space */
|
||||
|
||||
#define XTC_TIMER_COUNTER_OFFSET 16
|
||||
|
||||
/** @name Register Offset Definitions
|
||||
* Register offsets within a timer counter, there are multiple
|
||||
* timer counters within a single device
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XTC_TCSR_OFFSET 0 /**< Control/Status register */
|
||||
#define XTC_TLR_OFFSET 4 /**< Load register */
|
||||
#define XTC_TCR_OFFSET 8 /**< Timer counter register */
|
||||
|
||||
/* @} */
|
||||
|
||||
/** @name Control Status Register Bit Definitions
|
||||
* Control Status Register bit masks
|
||||
* Used to configure the timer counter device.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XTC_CSR_CASC_MASK 0x00000800 /**< Cascade Mode */
|
||||
#define XTC_CSR_ENABLE_ALL_MASK 0x00000400 /**< Enables all timer
|
||||
counters */
|
||||
#define XTC_CSR_ENABLE_PWM_MASK 0x00000200 /**< Enables the Pulse Width
|
||||
Modulation */
|
||||
#define XTC_CSR_INT_OCCURED_MASK 0x00000100 /**< If bit is set, an
|
||||
interrupt has occured.
|
||||
If set and '1' is
|
||||
written to this bit
|
||||
position, bit is
|
||||
cleared. */
|
||||
#define XTC_CSR_ENABLE_TMR_MASK 0x00000080 /**< Enables only the
|
||||
specific timer */
|
||||
#define XTC_CSR_ENABLE_INT_MASK 0x00000040 /**< Enables the interrupt
|
||||
output. */
|
||||
#define XTC_CSR_LOAD_MASK 0x00000020 /**< Loads the timer using
|
||||
the load value provided
|
||||
earlier in the Load
|
||||
Register,
|
||||
XTC_TLR_OFFSET. */
|
||||
#define XTC_CSR_AUTO_RELOAD_MASK 0x00000010 /**< In compare mode,
|
||||
configures
|
||||
the timer counter to
|
||||
reload from the
|
||||
Load Register. The
|
||||
default mode
|
||||
causes the timer counter
|
||||
to hold when the compare
|
||||
value is hit. In capture
|
||||
mode, configures the
|
||||
timer counter to not
|
||||
hold the previous
|
||||
capture value if a new
|
||||
event occurs. The
|
||||
default mode cause the
|
||||
timer counter to hold
|
||||
the capture value until
|
||||
recognized. */
|
||||
#define XTC_CSR_EXT_CAPTURE_MASK 0x00000008 /**< Enables the
|
||||
external input
|
||||
to the timer counter. */
|
||||
#define XTC_CSR_EXT_GENERATE_MASK 0x00000004 /**< Enables the
|
||||
external generate output
|
||||
for the timer. */
|
||||
#define XTC_CSR_DOWN_COUNT_MASK 0x00000002 /**< Configures the timer
|
||||
counter to count down
|
||||
from start value, the
|
||||
default is to count
|
||||
up.*/
|
||||
#define XTC_CSR_CAPTURE_MODE_MASK 0x00000001 /**< Enables the timer to
|
||||
capture the timer
|
||||
counter value when the
|
||||
external capture line is
|
||||
asserted. The default
|
||||
mode is compare mode.*/
|
||||
/* @} */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
extern u8 XTmrCtr_Offsets[];
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Read one of the timer counter registers.
|
||||
*
|
||||
* @param BaseAddress contains the base address of the timer counter
|
||||
* device.
|
||||
* @param TmrCtrNumber contains the specific timer counter within the
|
||||
* device, a zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
* @param RegOffset contains the offset from the 1st register of the timer
|
||||
* counter to select the specific register of the timer counter.
|
||||
*
|
||||
* @return The value read from the register, a 32 bit value.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XTmrCtr_ReadReg(u32 BaseAddress, u8 TimerNumber,
|
||||
unsigned RegOffset);
|
||||
******************************************************************************/
|
||||
#define XTmrCtr_ReadReg(BaseAddress, TmrCtrNumber, RegOffset) \
|
||||
Xil_In32((BaseAddress) + XTmrCtr_Offsets[(TmrCtrNumber)] + \
|
||||
(RegOffset))
|
||||
|
||||
#ifndef XTimerCtr_ReadReg
|
||||
#define XTimerCtr_ReadReg XTmrCtr_ReadReg
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Write a specified value to a register of a timer counter.
|
||||
*
|
||||
* @param BaseAddress is the base address of the timer counter device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
* @param RegOffset contain the offset from the 1st register of the timer
|
||||
* counter to select the specific register of the timer counter.
|
||||
* @param ValueToWrite is the 32 bit value to be written to the register.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XTmrCtr_WriteReg(u32 BaseAddress, u8 TimerNumber,
|
||||
* unsigned RegOffset, u32 ValueToWrite);
|
||||
******************************************************************************/
|
||||
#define XTmrCtr_WriteReg(BaseAddress, TmrCtrNumber, RegOffset, ValueToWrite)\
|
||||
Xil_Out32(((BaseAddress) + XTmrCtr_Offsets[(TmrCtrNumber)] + \
|
||||
(RegOffset)), (ValueToWrite))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the Control Status Register of a timer counter to the specified value.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
* @param RegisterValue is the 32 bit value to be written to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XTmrCtr_SetControlStatusReg(u32 BaseAddress,
|
||||
* u8 TmrCtrNumber,u32 RegisterValue);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_SetControlStatusReg(BaseAddress, TmrCtrNumber, RegisterValue)\
|
||||
XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \
|
||||
(RegisterValue))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the Control Status Register of a timer counter.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device,
|
||||
* a zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return The value read from the register, a 32 bit value.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XTmrCtr_GetControlStatusReg(u32 BaseAddress,
|
||||
* u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_GetControlStatusReg(BaseAddress, TmrCtrNumber) \
|
||||
XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the Timer Counter Register of a timer counter.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device,
|
||||
* a zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return The value read from the register, a 32 bit value.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XTmrCtr_GetTimerCounterReg(u32 BaseAddress,
|
||||
* u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_GetTimerCounterReg(BaseAddress, TmrCtrNumber) \
|
||||
XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), XTC_TCR_OFFSET) \
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the Load Register of a timer counter to the specified value.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
* @param RegisterValue is the 32 bit value to be written to the register.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XTmrCtr_SetLoadReg(u32 BaseAddress, u8 TmrCtrNumber,
|
||||
* u32 RegisterValue);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_SetLoadReg(BaseAddress, TmrCtrNumber, RegisterValue) \
|
||||
XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TLR_OFFSET, \
|
||||
(RegisterValue))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the Load Register of a timer counter.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return The value read from the register, a 32 bit value.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* u32 XTmrCtr_GetLoadReg(u32 BaseAddress, u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_GetLoadReg(BaseAddress, TmrCtrNumber) \
|
||||
XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), XTC_TLR_OFFSET)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable a timer counter such that it starts running.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XTmrCtr_Enable(u32 BaseAddress, u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_Enable(BaseAddress, TmrCtrNumber) \
|
||||
XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \
|
||||
(XTmrCtr_ReadReg((BaseAddress), ( TmrCtrNumber), \
|
||||
XTC_TCSR_OFFSET) | XTC_CSR_ENABLE_TMR_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable a timer counter such that it stops running.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device,
|
||||
* a zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XTmrCtr_Disable(u32 BaseAddress, u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_Disable(BaseAddress, TmrCtrNumber) \
|
||||
XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \
|
||||
(XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber),\
|
||||
XTC_TCSR_OFFSET) & ~ XTC_CSR_ENABLE_TMR_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable the interrupt for a timer counter.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XTmrCtr_EnableIntr(u32 BaseAddress, u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_EnableIntr(BaseAddress, TmrCtrNumber) \
|
||||
XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \
|
||||
(XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), \
|
||||
XTC_TCSR_OFFSET) | XTC_CSR_ENABLE_INT_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable the interrupt for a timer counter.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XTmrCtr_DisableIntr(u32 BaseAddress, u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_DisableIntr(BaseAddress, TmrCtrNumber) \
|
||||
XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \
|
||||
(XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), \
|
||||
XTC_TCSR_OFFSET) & ~ XTC_CSR_ENABLE_INT_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Cause the timer counter to load it's Timer Counter Register with the value
|
||||
* in the Load Register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* void XTmrCtr_LoadTimerCounterReg(u32 BaseAddress,
|
||||
u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_LoadTimerCounterReg(BaseAddress, TmrCtrNumber) \
|
||||
XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \
|
||||
(XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber),\
|
||||
XTC_TCSR_OFFSET) | XTC_CSR_LOAD_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Determine if a timer counter event has occurred. Events are defined to be
|
||||
* when a capture has occurred or the counter has roller over.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param TmrCtrNumber is the specific timer counter within the device, a
|
||||
* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @note C-Style signature:
|
||||
* int XTmrCtr_HasEventOccurred(u32 BaseAddress, u8 TmrCtrNumber);
|
||||
*****************************************************************************/
|
||||
#define XTmrCtr_HasEventOccurred(BaseAddress, TmrCtrNumber) \
|
||||
((XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), \
|
||||
XTC_TCSR_OFFSET) & XTC_CSR_INT_OCCURED_MASK) == \
|
||||
XTC_CSR_INT_OCCURED_MASK)
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
/************************** Variable Definitions *****************************/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
@ -0,0 +1,217 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr_options.c
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
*
|
||||
* Contains configuration options functions for the XTmrCtr component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 02/06/02 First release
|
||||
* 1.10b mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/30/09 Updated to use HAL API's. _m is removed from all the macro
|
||||
* definitions.
|
||||
* 2.04a sdm 07/12/11 Added support for the cascade mode operation.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xtmrctr.h"
|
||||
#include "xtmrctr_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The following data type maps an option to a register mask such that getting
|
||||
* and setting the options may be table driven.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 Option;
|
||||
u32 Mask;
|
||||
} Mapping;
|
||||
|
||||
/*
|
||||
* Create the table which contains options which are to be processed to get/set
|
||||
* the options. These options are table driven to allow easy maintenance and
|
||||
* expansion of the options.
|
||||
*/
|
||||
static Mapping OptionsTable[] = {
|
||||
{XTC_CASCADE_MODE_OPTION, XTC_CSR_CASC_MASK},
|
||||
{XTC_ENABLE_ALL_OPTION, XTC_CSR_ENABLE_ALL_MASK},
|
||||
{XTC_DOWN_COUNT_OPTION, XTC_CSR_DOWN_COUNT_MASK},
|
||||
{XTC_CAPTURE_MODE_OPTION, XTC_CSR_CAPTURE_MODE_MASK |
|
||||
XTC_CSR_EXT_CAPTURE_MASK},
|
||||
{XTC_INT_MODE_OPTION, XTC_CSR_ENABLE_INT_MASK},
|
||||
{XTC_AUTO_RELOAD_OPTION, XTC_CSR_AUTO_RELOAD_MASK},
|
||||
{XTC_EXT_COMPARE_OPTION, XTC_CSR_EXT_GENERATE_MASK}
|
||||
};
|
||||
|
||||
/* Create a constant for the number of entries in the table */
|
||||
|
||||
#define XTC_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(Mapping))
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enables the specified options for the specified timer counter. This function
|
||||
* sets the options without regard to the current options of the driver. To
|
||||
* prevent a loss of the current options, the user should call
|
||||
* XTmrCtr_GetOptions() prior to this function and modify the retrieved options
|
||||
* to pass into this function to prevent loss of the current options.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
* @param Options contains the desired options to be set or cleared.
|
||||
* Setting the option to '1' enables the option, clearing the to
|
||||
* '0' disables the option. The options are bit masks such that
|
||||
* multiple options may be set or cleared. The options are
|
||||
* described in xtmrctr.h.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_SetOptions(XTmrCtr * InstancePtr, u8 TmrCtrNumber, u32 Options)
|
||||
{
|
||||
u32 CounterControlReg = 0;
|
||||
u32 Index;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Loop through the Options table, turning the enable on or off
|
||||
* depending on whether the bit is set in the incoming Options flag.
|
||||
*/
|
||||
|
||||
for (Index = 0; Index < XTC_NUM_OPTIONS; Index++) {
|
||||
if (Options & OptionsTable[Index].Option) {
|
||||
|
||||
/*
|
||||
* Turn the option on
|
||||
*/
|
||||
CounterControlReg |= OptionsTable[Index].Mask;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Turn the option off
|
||||
*/
|
||||
CounterControlReg &= ~OptionsTable[Index].Mask;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the updated value to the actual register
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET, CounterControlReg);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the options for the specified timer counter.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The currently set options. An option which is set to a '1' is enabled and
|
||||
* set to a '0' is disabled. The options are bit masks such that multiple
|
||||
* options may be set or cleared. The options are described in xtmrctr.h.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 XTmrCtr_GetOptions(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
|
||||
{
|
||||
|
||||
u32 Options = 0;
|
||||
u32 CounterControlReg;
|
||||
u32 Index;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Read the current contents of the control status register to allow
|
||||
* the current options to be determined
|
||||
*/
|
||||
CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TCSR_OFFSET);
|
||||
/*
|
||||
* Loop through the Options table, turning the enable on or off
|
||||
* depending on whether the bit is set in the current register settings.
|
||||
*/
|
||||
for (Index = 0; Index < XTC_NUM_OPTIONS; Index++) {
|
||||
if (CounterControlReg & OptionsTable[Index].Mask) {
|
||||
Options |= OptionsTable[Index].Option; /* turn it on */
|
||||
}
|
||||
else {
|
||||
Options &= ~OptionsTable[Index].Option; /* turn it off */
|
||||
}
|
||||
}
|
||||
|
||||
return Options;
|
||||
}
|
||||
/** @} */
|
@ -0,0 +1,166 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr_selftest.c
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
*
|
||||
* Contains diagnostic/self-test functions for the XTmrCtr component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 02/06/02 First release
|
||||
* 1.10b mta 03/21/07 Updated to new coding style
|
||||
* 2.00a ktn 10/30/09 Updated to use HAL API's. _m is removed from all the macro
|
||||
* definitions.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_io.h"
|
||||
#include "xtmrctr.h"
|
||||
#include "xtmrctr_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Runs a self-test on the driver/device. This test verifies that the specified
|
||||
* timer counter of the device can be enabled and increments.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param TmrCtrNumber is the timer counter of the device to operate on.
|
||||
* Each device may contain multiple timer counters. The timer
|
||||
* number is a zero based number with a range of
|
||||
* 0 - (XTC_DEVICE_TIMER_COUNT - 1).
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if self-test was successful
|
||||
* - XST_FAILURE if the timer is not incrementing.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This is a destructive test using the provided timer. The current settings
|
||||
* of the timer are returned to the initialized values and all settings at the
|
||||
* time this function is called are overwritten.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XTmrCtr_SelfTest(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
|
||||
{
|
||||
u32 TimerCount1 = 0;
|
||||
u32 TimerCount2 = 0;
|
||||
u16 Count = 0;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Set the Capture register to 0
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TLR_OFFSET, 0);
|
||||
|
||||
/*
|
||||
* Reset the timer and the interrupt
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET,
|
||||
XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);
|
||||
|
||||
/*
|
||||
* Set the control/status register to enable timer
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET, XTC_CSR_ENABLE_TMR_MASK);
|
||||
|
||||
/*
|
||||
* Read the timer
|
||||
*/
|
||||
TimerCount1 = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TCR_OFFSET);
|
||||
/*
|
||||
* Make sure timer is incrementing if the Count rolls over to zero
|
||||
* and the timer still has not incremented an error is returned
|
||||
*/
|
||||
|
||||
do {
|
||||
TimerCount2 = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
|
||||
TmrCtrNumber, XTC_TCR_OFFSET);
|
||||
Count++;
|
||||
}
|
||||
while ((TimerCount1 == TimerCount2) && (Count != 0));
|
||||
|
||||
/*
|
||||
* Reset the timer and the interrupt
|
||||
*/
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET,
|
||||
XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK);
|
||||
|
||||
/*
|
||||
* Set the control/status register to 0 to complete initialization
|
||||
* this disables the timer completely and allows it to be used again
|
||||
*/
|
||||
|
||||
XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
|
||||
XTC_TCSR_OFFSET, 0);
|
||||
|
||||
if (TimerCount1 == TimerCount2) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
else {
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
}
|
||||
/** @} */
|
@ -0,0 +1,102 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr_sinit.c
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
*
|
||||
* This file contains static initialization methods for the XTmrCtr driver.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 4.0 als 09/30/15 Creation of this file. Moved LookupConfig from xtmrctr.c.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************* Include Files *******************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xtmrctr.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#ifndef XPAR_XTMRCTR_NUM_INSTANCES
|
||||
#define XPAR_XTMRCTR_NUM_INSTANCES 0
|
||||
#endif
|
||||
|
||||
/*************************** Variable Declarations ***************************/
|
||||
|
||||
/* A table of configuration structures containing the configuration information
|
||||
* for each timer core in the system. */
|
||||
extern XTmrCtr_Config XTmrCtr_ConfigTable[XPAR_XTMRCTR_NUM_INSTANCES];
|
||||
|
||||
/**************************** Function Definitions ***************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Looks up the device configuration based on the unique device ID. The table
|
||||
* TmrCtr_ConfigTable contains the configuration info for each device in the
|
||||
* system.
|
||||
*
|
||||
* @param DeviceId is the unique device ID to search for in the config
|
||||
* table.
|
||||
*
|
||||
* @return A pointer to the configuration that matches the given device
|
||||
* ID, or NULL if no match is found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XTmrCtr_Config *XTmrCtr_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XTmrCtr_Config *CfgPtr = NULL;
|
||||
int Index;
|
||||
|
||||
for (Index = 0; Index < XPAR_XTMRCTR_NUM_INSTANCES; Index++) {
|
||||
if (XTmrCtr_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XTmrCtr_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CfgPtr;
|
||||
}
|
||||
|
||||
/** @} */
|
@ -0,0 +1,115 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xtmrctr_stats.c
|
||||
* @addtogroup tmrctr_v4_0
|
||||
* @{
|
||||
*
|
||||
* Contains function to get and clear statistics for the XTmrCtr component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b jhl 02/06/02 First release.
|
||||
* 1.10b mta 03/21/07 Updated for new coding style.
|
||||
* 2.00a ktn 10/30/09 Updated to use HAL API's.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xtmrctr.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get a copy of the XTmrCtrStats structure, which contains the current
|
||||
* statistics for this driver.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
* @param StatsPtr is a pointer to a XTmrCtrStats structure which will get
|
||||
* a copy of current statistics.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_GetStats(XTmrCtr * InstancePtr, XTmrCtrStats * StatsPtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(StatsPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
StatsPtr->Interrupts = InstancePtr->Stats.Interrupts;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Clear the XTmrCtrStats structure for this driver.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XTmrCtr instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XTmrCtr_ClearStats(XTmrCtr * InstancePtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
InstancePtr->Stats.Interrupts = 0;
|
||||
}
|
||||
/** @} */
|
Binary file not shown.
@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MemInfo Version="1" Minor="1">
|
||||
<Processor Endianness="Little" InstPath="mb_subsystem_i/microblaze_0">
|
||||
<AddressSpace Name="mb_subsystem_i_microblaze_0.mb_subsystem_i_microblaze_0_local_memory_dlmb_bram_if_cntlr" Begin="0" End="65535">
|
||||
<BusBlock>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y23">
|
||||
<DataWidth MSB="7" LSB="6"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X3Y30">
|
||||
<DataWidth MSB="5" LSB="4"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y22">
|
||||
<DataWidth MSB="3" LSB="2"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X3Y26">
|
||||
<DataWidth MSB="1" LSB="0"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X3Y32">
|
||||
<DataWidth MSB="15" LSB="14"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X1Y26">
|
||||
<DataWidth MSB="13" LSB="12"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X3Y31">
|
||||
<DataWidth MSB="11" LSB="10"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y26">
|
||||
<DataWidth MSB="9" LSB="8"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y29">
|
||||
<DataWidth MSB="23" LSB="22"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y27">
|
||||
<DataWidth MSB="21" LSB="20"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X4Y25">
|
||||
<DataWidth MSB="19" LSB="18"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y28">
|
||||
<DataWidth MSB="17" LSB="16"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y25">
|
||||
<DataWidth MSB="31" LSB="30"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X2Y24">
|
||||
<DataWidth MSB="29" LSB="28"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X3Y27">
|
||||
<DataWidth MSB="27" LSB="26"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
<BitLane MemType="RAMB36" Placement="X3Y29">
|
||||
<DataWidth MSB="25" LSB="24"/>
|
||||
<AddressRange Begin="0" End="16383"/>
|
||||
<Parity ON="false" NumBits="0"/>
|
||||
</BitLane>
|
||||
</BusBlock>
|
||||
</AddressSpace>
|
||||
</Processor>
|
||||
<Config>
|
||||
<Option Name="Part" Val="xc7k325tffg900-2"/>
|
||||
</Config>
|
||||
</MemInfo>
|
Binary file not shown.
@ -1,213 +1,213 @@
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* This file is automatically generated by linker script generator.*/
|
||||
/* */
|
||||
/* Version: */
|
||||
/* */
|
||||
/* Copyright (c) 2010 Xilinx, Inc. All rights reserved. */
|
||||
/* */
|
||||
/* Description : MicroBlaze Linker Script */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
|
||||
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
|
||||
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x4;
|
||||
|
||||
/* Define Memories in the system */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
microblaze_0_local_memory_ilmb_bram_if_cntlr_microblaze_0_local_memory_dlmb_bram_if_cntlr : ORIGIN = 0x00000050, LENGTH = 0x0003FFB0
|
||||
mig_7series_0 : ORIGIN = 0x80000000, LENGTH = 0x40000000
|
||||
}
|
||||
|
||||
/* Specify the default entry point to the program */
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
/* Define the sections, and where they are mapped in memory */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.vectors.reset 0x00000000 : {
|
||||
KEEP (*(.vectors.reset))
|
||||
}
|
||||
|
||||
.vectors.sw_exception 0x00000008 : {
|
||||
KEEP (*(.vectors.sw_exception))
|
||||
}
|
||||
|
||||
.vectors.interrupt 0x00000010 : {
|
||||
KEEP (*(.vectors.interrupt))
|
||||
}
|
||||
|
||||
.vectors.hw_exception 0x00000020 : {
|
||||
KEEP (*(.vectors.hw_exception))
|
||||
}
|
||||
|
||||
.text : {
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
} > mig_7series_0
|
||||
|
||||
.init : {
|
||||
KEEP (*(.init))
|
||||
} > mig_7series_0
|
||||
|
||||
.fini : {
|
||||
KEEP (*(.fini))
|
||||
} > mig_7series_0
|
||||
|
||||
.ctors : {
|
||||
__CTOR_LIST__ = .;
|
||||
___CTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__CTOR_END__ = .;
|
||||
___CTORS_END___ = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.dtors : {
|
||||
__DTOR_LIST__ = .;
|
||||
___DTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
PROVIDE(__DTOR_END__ = .);
|
||||
PROVIDE(___DTORS_END___ = .);
|
||||
} > mig_7series_0
|
||||
|
||||
.rodata : {
|
||||
__rodata_start = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
__rodata_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.sdata2 : {
|
||||
. = ALIGN(8);
|
||||
__sdata2_start = .;
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
. = ALIGN(8);
|
||||
__sdata2_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.sbss2 : {
|
||||
__sbss2_start = .;
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
__sbss2_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.data : {
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
__data_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_microblaze_0_local_memory_dlmb_bram_if_cntlr
|
||||
|
||||
.got : {
|
||||
*(.got)
|
||||
} > mig_7series_0
|
||||
|
||||
.got1 : {
|
||||
*(.got1)
|
||||
} > mig_7series_0
|
||||
|
||||
.got2 : {
|
||||
*(.got2)
|
||||
} > mig_7series_0
|
||||
|
||||
.eh_frame : {
|
||||
*(.eh_frame)
|
||||
} > mig_7series_0
|
||||
|
||||
.jcr : {
|
||||
*(.jcr)
|
||||
} > mig_7series_0
|
||||
|
||||
.gcc_except_table : {
|
||||
*(.gcc_except_table)
|
||||
} > mig_7series_0
|
||||
|
||||
.sdata : {
|
||||
. = ALIGN(8);
|
||||
__sdata_start = .;
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
__sdata_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.sbss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
__sbss_start = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
. = ALIGN(8);
|
||||
__sbss_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.tdata : {
|
||||
__tdata_start = .;
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.gnu.linkonce.td.*)
|
||||
__tdata_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.tbss : {
|
||||
__tbss_start = .;
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
*(.gnu.linkonce.tb.*)
|
||||
__tbss_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_microblaze_0_local_memory_dlmb_bram_if_cntlr
|
||||
|
||||
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
|
||||
|
||||
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
|
||||
|
||||
/* Generate Stack and Heap definitions */
|
||||
|
||||
.heap (NOLOAD) : {
|
||||
. = ALIGN(8);
|
||||
_heap = .;
|
||||
_heap_start = .;
|
||||
. += _HEAP_SIZE;
|
||||
_heap_end = .;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_microblaze_0_local_memory_dlmb_bram_if_cntlr
|
||||
|
||||
.stack (NOLOAD) : {
|
||||
_stack_end = .;
|
||||
. += _STACK_SIZE;
|
||||
. = ALIGN(8);
|
||||
_stack = .;
|
||||
__stack = _stack;
|
||||
} > microblaze_0_local_memory_ilmb_bram_if_cntlr_microblaze_0_local_memory_dlmb_bram_if_cntlr
|
||||
|
||||
_end = .;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* This file is automatically generated by linker script generator.*/
|
||||
/* */
|
||||
/* Version: */
|
||||
/* */
|
||||
/* Copyright (c) 2010 Xilinx, Inc. All rights reserved. */
|
||||
/* */
|
||||
/* Description : MicroBlaze Linker Script */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
|
||||
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
|
||||
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x400;
|
||||
|
||||
/* Define Memories in the system */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
microblaze_0_local_memory_ilmb_bram_if_cntlr_microblaze_0_local_memory_dlmb_bram_if_cntlr : ORIGIN = 0x50, LENGTH = 0xFFB0
|
||||
mig_7series_0 : ORIGIN = 0x80000000, LENGTH = 0x20000000
|
||||
}
|
||||
|
||||
/* Specify the default entry point to the program */
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
/* Define the sections, and where they are mapped in memory */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.vectors.reset 0x0 : {
|
||||
KEEP (*(.vectors.reset))
|
||||
}
|
||||
|
||||
.vectors.sw_exception 0x8 : {
|
||||
KEEP (*(.vectors.sw_exception))
|
||||
}
|
||||
|
||||
.vectors.interrupt 0x10 : {
|
||||
KEEP (*(.vectors.interrupt))
|
||||
}
|
||||
|
||||
.vectors.hw_exception 0x20 : {
|
||||
KEEP (*(.vectors.hw_exception))
|
||||
}
|
||||
|
||||
.text : {
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
} > mig_7series_0
|
||||
|
||||
.init : {
|
||||
KEEP (*(.init))
|
||||
} > mig_7series_0
|
||||
|
||||
.fini : {
|
||||
KEEP (*(.fini))
|
||||
} > mig_7series_0
|
||||
|
||||
.ctors : {
|
||||
__CTOR_LIST__ = .;
|
||||
___CTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__CTOR_END__ = .;
|
||||
___CTORS_END___ = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.dtors : {
|
||||
__DTOR_LIST__ = .;
|
||||
___DTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
PROVIDE(__DTOR_END__ = .);
|
||||
PROVIDE(___DTORS_END___ = .);
|
||||
} > mig_7series_0
|
||||
|
||||
.rodata : {
|
||||
__rodata_start = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
__rodata_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.sdata2 : {
|
||||
. = ALIGN(8);
|
||||
__sdata2_start = .;
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
. = ALIGN(8);
|
||||
__sdata2_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.sbss2 : {
|
||||
__sbss2_start = .;
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
__sbss2_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.data : {
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
__data_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.got : {
|
||||
*(.got)
|
||||
} > mig_7series_0
|
||||
|
||||
.got1 : {
|
||||
*(.got1)
|
||||
} > mig_7series_0
|
||||
|
||||
.got2 : {
|
||||
*(.got2)
|
||||
} > mig_7series_0
|
||||
|
||||
.eh_frame : {
|
||||
*(.eh_frame)
|
||||
} > mig_7series_0
|
||||
|
||||
.jcr : {
|
||||
*(.jcr)
|
||||
} > mig_7series_0
|
||||
|
||||
.gcc_except_table : {
|
||||
*(.gcc_except_table)
|
||||
} > mig_7series_0
|
||||
|
||||
.sdata : {
|
||||
. = ALIGN(8);
|
||||
__sdata_start = .;
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
__sdata_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.sbss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
__sbss_start = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
. = ALIGN(8);
|
||||
__sbss_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.tdata : {
|
||||
__tdata_start = .;
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.gnu.linkonce.td.*)
|
||||
__tdata_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.tbss : {
|
||||
__tbss_start = .;
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
*(.gnu.linkonce.tb.*)
|
||||
__tbss_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
|
||||
|
||||
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
|
||||
|
||||
/* Generate Stack and Heap definitions */
|
||||
|
||||
.heap (NOLOAD) : {
|
||||
. = ALIGN(8);
|
||||
_heap = .;
|
||||
_heap_start = .;
|
||||
. += _HEAP_SIZE;
|
||||
_heap_end = .;
|
||||
} > mig_7series_0
|
||||
|
||||
.stack (NOLOAD) : {
|
||||
_stack_end = .;
|
||||
. += _STACK_SIZE;
|
||||
. = ALIGN(8);
|
||||
_stack = .;
|
||||
__stack = _stack;
|
||||
} > mig_7series_0
|
||||
|
||||
_end = .;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,494 @@
|
||||
/*
|
||||
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the MicroBlaze port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <string.h>
|
||||
|
||||
/* Hardware includes. */
|
||||
#include <xintc_i.h>
|
||||
#include <xil_exception.h>
|
||||
#include <microblaze_exceptions_g.h>
|
||||
|
||||
/* Tasks are started with a critical section nesting of 0 - however, prior to
|
||||
the scheduler being commenced interrupts should not be enabled, so the critical
|
||||
nesting variable is initialised to a non-zero value. */
|
||||
#define portINITIAL_NESTING_VALUE ( 0xff )
|
||||
|
||||
/* The bit within the MSR register that enabled/disables interrupts and
|
||||
exceptions respectively. */
|
||||
#define portMSR_IE ( 0x02U )
|
||||
#define portMSR_EE ( 0x100U )
|
||||
|
||||
/* If the floating point unit is included in the MicroBlaze build, then the
|
||||
FSR register is saved as part of the task context. portINITIAL_FSR is the value
|
||||
given to the FSR register when the initial context is set up for a task being
|
||||
created. */
|
||||
#define portINITIAL_FSR ( 0U )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the interrupt controller instance.
|
||||
*/
|
||||
static int32_t prvInitialiseInterruptController( void );
|
||||
|
||||
/* Ensure the interrupt controller instance variable is initialised before it is
|
||||
* used, and that the initialisation only happens once.
|
||||
*/
|
||||
static int32_t prvEnsureInterruptControllerIsInitialised( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
|
||||
maintains its own count, so this variable is saved as part of the task
|
||||
context. */
|
||||
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE;
|
||||
|
||||
/* This port uses a separate stack for interrupts. This prevents the stack of
|
||||
every task needing to be large enough to hold an entire interrupt stack on top
|
||||
of the task stack. */
|
||||
uint32_t *pulISRStack;
|
||||
|
||||
/* If an interrupt requests a context switch, then ulTaskSwitchRequested will
|
||||
get set to 1. ulTaskSwitchRequested is inspected just before the main interrupt
|
||||
handler exits. If, at that time, ulTaskSwitchRequested is set to 1, the kernel
|
||||
will call vTaskSwitchContext() to ensure the task that runs immediately after
|
||||
the interrupt exists is the highest priority task that is able to run. This is
|
||||
an unusual mechanism, but is used for this port because a single interrupt can
|
||||
cause the servicing of multiple peripherals - and it is inefficient to call
|
||||
vTaskSwitchContext() multiple times as each peripheral is serviced. */
|
||||
volatile uint32_t ulTaskSwitchRequested = 0UL;
|
||||
|
||||
/* The instance of the interrupt controller used by this port. This is required
|
||||
by the Xilinx library API functions. */
|
||||
static XIntc xInterruptControllerInstance;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been made.
|
||||
*
|
||||
* See the portable.h header file.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
extern void *_SDA2_BASE_, *_SDA_BASE_;
|
||||
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
|
||||
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
|
||||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
This is essential for the Microblaze port and these lines must
|
||||
not be omitted. */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000;
|
||||
pxTopOfStack--;
|
||||
|
||||
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||
/* The FSR value placed in the initial task context is just 0. */
|
||||
*pxTopOfStack = portINITIAL_FSR;
|
||||
pxTopOfStack--;
|
||||
#endif
|
||||
|
||||
/* The MSR value placed in the initial task context should have interrupts
|
||||
disabled. Each task will enable interrupts automatically when it enters
|
||||
the running state for the first time. */
|
||||
*pxTopOfStack = mfmsr() & ~portMSR_IE;
|
||||
|
||||
#if( MICROBLAZE_EXCEPTIONS_ENABLED == 1 )
|
||||
{
|
||||
/* Ensure exceptions are enabled for the task. */
|
||||
*pxTopOfStack |= portMSR_EE;
|
||||
}
|
||||
#endif
|
||||
|
||||
pxTopOfStack--;
|
||||
|
||||
/* First stack an initial value for the critical section nesting. This
|
||||
is initialised to zero. */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||
|
||||
/* R0 is always zero. */
|
||||
/* R1 is the SP. */
|
||||
|
||||
/* Place an initial value for all the general purpose registers. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) ulR2; /* R2 - read only small data area. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03; /* R3 - return values and temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04; /* R4 - return values and temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters;/* R5 contains the function call parameters. */
|
||||
|
||||
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06; /* R6 - other parameters and temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07; /* R7 - other parameters and temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08; /* R8 - other parameters and temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09; /* R9 - other parameters and temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x0a; /* R10 - other parameters and temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x0b; /* R11 - temporaries. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x0c; /* R12 - temporaries. */
|
||||
pxTopOfStack--;
|
||||
#else
|
||||
pxTopOfStack-= 8;
|
||||
#endif
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) ulR13; /* R13 - read/write small data area. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxCode; /* R14 - return address for interrupt. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) NULL; /* R15 - return address for subroutine. */
|
||||
|
||||
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10; /* R16 - return address for trap (debugger). */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11; /* R17 - return address for exceptions, if configured. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12; /* R18 - reserved for assembler and compiler temporaries. */
|
||||
pxTopOfStack--;
|
||||
#else
|
||||
pxTopOfStack -= 4;
|
||||
#endif
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R19 - must be saved across function calls. Callee-save. Seems to be interpreted as the frame pointer. */
|
||||
|
||||
#ifdef portPRE_LOAD_STACK_FOR_DEBUGGING
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x14; /* R20 - reserved for storing a pointer to the Global Offset Table (GOT) in Position Independent Code (PIC). Non-volatile in non-PIC code. Must be saved across function calls. Callee-save. Not used by FreeRTOS. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x15; /* R21 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x16; /* R22 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x17; /* R23 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x18; /* R24 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x19; /* R25 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x1a; /* R26 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x1b; /* R27 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x1c; /* R28 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x1d; /* R29 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x1e; /* R30 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x1f; /* R31 - must be saved across function calls. Callee-save. */
|
||||
pxTopOfStack--;
|
||||
#else
|
||||
pxTopOfStack -= 13;
|
||||
#endif
|
||||
|
||||
/* Return a pointer to the top of the stack that has been generated so this
|
||||
can be stored in the task control block for the task. */
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
extern void ( vPortStartFirstTask )( void );
|
||||
extern uint32_t _stack[];
|
||||
|
||||
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||
this function is called.
|
||||
|
||||
This port uses an application defined callback function to install the tick
|
||||
interrupt handler because the kernel will run on lots of different
|
||||
MicroBlaze and FPGA configurations - not all of which will have the same
|
||||
timer peripherals defined or available. An example definition of
|
||||
vApplicationSetupTimerInterrupt() is provided in the official demo
|
||||
application that accompanies this port. */
|
||||
vApplicationSetupTimerInterrupt();
|
||||
|
||||
/* Reuse the stack from main() as the stack for the interrupts/exceptions. */
|
||||
pulISRStack = ( uint32_t * ) _stack;
|
||||
|
||||
/* Ensure there is enough space for the functions called from the interrupt
|
||||
service routines to write back into the stack frame of the caller. */
|
||||
pulISRStack -= 2;
|
||||
|
||||
/* Restore the context of the first task that is going to run. From here
|
||||
on, the created tasks will be executing. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here as the tasks are now running! */
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Manual context switch called by portYIELD or taskYIELD.
|
||||
*/
|
||||
void vPortYield( void )
|
||||
{
|
||||
extern void VPortYieldASM( void );
|
||||
|
||||
/* Perform the context switch in a critical section to assure it is
|
||||
not interrupted by the tick ISR. It is not a problem to do this as
|
||||
each task maintains its own interrupt status. */
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
/* Jump directly to the yield function to ensure there is no
|
||||
compiler generated prologue code. */
|
||||
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
|
||||
"or r0, r0, r0 \n\t" );
|
||||
}
|
||||
portEXIT_CRITICAL();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnableInterrupt( uint8_t ucInterruptID )
|
||||
{
|
||||
int32_t lReturn;
|
||||
|
||||
/* An API function is provided to enable an interrupt in the interrupt
|
||||
controller because the interrupt controller instance variable is private
|
||||
to this file. */
|
||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
XIntc_Enable( &xInterruptControllerInstance, ucInterruptID );
|
||||
}
|
||||
|
||||
configASSERT( lReturn );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortDisableInterrupt( uint8_t ucInterruptID )
|
||||
{
|
||||
int32_t lReturn;
|
||||
|
||||
/* An API function is provided to disable an interrupt in the interrupt
|
||||
controller because the interrupt controller instance variable is private
|
||||
to this file. */
|
||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
XIntc_Disable( &xInterruptControllerInstance, ucInterruptID );
|
||||
}
|
||||
|
||||
configASSERT( lReturn );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef )
|
||||
{
|
||||
int32_t lReturn;
|
||||
|
||||
/* An API function is provided to install an interrupt handler because the
|
||||
interrupt controller instance variable is private to this file. */
|
||||
|
||||
lReturn = prvEnsureInterruptControllerIsInitialised();
|
||||
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
lReturn = XIntc_Connect( &xInterruptControllerInstance, ucInterruptID, pxHandler, pvCallBackRef );
|
||||
}
|
||||
|
||||
if( lReturn == XST_SUCCESS )
|
||||
{
|
||||
lReturn = pdPASS;
|
||||
}
|
||||
|
||||
configASSERT( lReturn == pdPASS );
|
||||
|
||||
return lReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static int32_t prvEnsureInterruptControllerIsInitialised( void )
|
||||
{
|
||||
static int32_t lInterruptControllerInitialised = pdFALSE;
|
||||
int32_t lReturn;
|
||||
|
||||
/* Ensure the interrupt controller instance variable is initialised before
|
||||
it is used, and that the initialisation only happens once. */
|
||||
if( lInterruptControllerInitialised != pdTRUE )
|
||||
{
|
||||
lReturn = prvInitialiseInterruptController();
|
||||
|
||||
if( lReturn == pdPASS )
|
||||
{
|
||||
lInterruptControllerInitialised = pdTRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lReturn = pdPASS;
|
||||
}
|
||||
|
||||
return lReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Handler for the timer interrupt. This is the handler that the application
|
||||
* defined callback function vApplicationSetupTimerInterrupt() should install.
|
||||
*/
|
||||
void vPortTickISR( void *pvUnused )
|
||||
{
|
||||
extern void vApplicationClearTimerInterrupt( void );
|
||||
|
||||
/* Ensure the unused parameter does not generate a compiler warning. */
|
||||
( void ) pvUnused;
|
||||
|
||||
/* This port uses an application defined callback function to clear the tick
|
||||
interrupt because the kernel will run on lots of different MicroBlaze and
|
||||
FPGA configurations - not all of which will have the same timer peripherals
|
||||
defined or available. An example definition of
|
||||
vApplicationClearTimerInterrupt() is provided in the official demo
|
||||
application that accompanies this port. */
|
||||
vApplicationClearTimerInterrupt();
|
||||
|
||||
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* Force vTaskSwitchContext() to be called as the interrupt exits. */
|
||||
ulTaskSwitchRequested = 1;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static int32_t prvInitialiseInterruptController( void )
|
||||
{
|
||||
int32_t lStatus;
|
||||
|
||||
lStatus = XIntc_Initialize( &xInterruptControllerInstance, configINTERRUPT_CONTROLLER_TO_USE );
|
||||
|
||||
if( lStatus == XST_SUCCESS )
|
||||
{
|
||||
/* Initialise the exception table. */
|
||||
Xil_ExceptionInit();
|
||||
|
||||
/* Service all pending interrupts each time the handler is entered. */
|
||||
XIntc_SetIntrSvcOption( xInterruptControllerInstance.BaseAddress, XIN_SVC_ALL_ISRS_OPTION );
|
||||
|
||||
/* Install exception handlers if the MicroBlaze is configured to handle
|
||||
exceptions, and the application defined constant
|
||||
configINSTALL_EXCEPTION_HANDLERS is set to 1. */
|
||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||
{
|
||||
vPortExceptionsInstallHandlers();
|
||||
}
|
||||
#endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
|
||||
|
||||
/* Start the interrupt controller. Interrupts are enabled when the
|
||||
scheduler starts. */
|
||||
lStatus = XIntc_Start( &xInterruptControllerInstance, XIN_REAL_MODE );
|
||||
|
||||
if( lStatus == XST_SUCCESS )
|
||||
{
|
||||
lStatus = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
lStatus = pdFAIL;
|
||||
}
|
||||
}
|
||||
|
||||
configASSERT( lStatus == pdPASS );
|
||||
|
||||
return lStatus;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -0,0 +1,324 @@
|
||||
/*
|
||||
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Hardware includes. */
|
||||
#include <microblaze_exceptions_i.h>
|
||||
#include <microblaze_exceptions_g.h>
|
||||
|
||||
/* The Xilinx library defined exception entry point stacks a number of
|
||||
registers. These definitions are offsets from the stack pointer to the various
|
||||
stacked register values. */
|
||||
#define portexR3_STACK_OFFSET 4
|
||||
#define portexR4_STACK_OFFSET 5
|
||||
#define portexR5_STACK_OFFSET 6
|
||||
#define portexR6_STACK_OFFSET 7
|
||||
#define portexR7_STACK_OFFSET 8
|
||||
#define portexR8_STACK_OFFSET 9
|
||||
#define portexR9_STACK_OFFSET 10
|
||||
#define portexR10_STACK_OFFSET 11
|
||||
#define portexR11_STACK_OFFSET 12
|
||||
#define portexR12_STACK_OFFSET 13
|
||||
#define portexR15_STACK_OFFSET 16
|
||||
#define portexR18_STACK_OFFSET 19
|
||||
#define portexMSR_STACK_OFFSET 20
|
||||
#define portexR19_STACK_OFFSET -1
|
||||
|
||||
/* This is defined to equal the size, in bytes, of the stack frame generated by
|
||||
the Xilinx standard library exception entry point. It is required to determine
|
||||
the stack pointer value prior to the exception being entered. */
|
||||
#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL
|
||||
|
||||
/* The number of bytes a MicroBlaze instruction consumes. */
|
||||
#define portexINSTRUCTION_SIZE 4
|
||||
|
||||
/* Exclude this entire file if the MicroBlaze is not configured to handle
|
||||
exceptions, or the application defined configuration constant
|
||||
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||
|
||||
/* This variable is set in the exception entry code, before
|
||||
vPortExceptionHandler is called. */
|
||||
uint32_t *pulStackPointerOnFunctionEntry = NULL;
|
||||
|
||||
/* This is the structure that is filled with the MicroBlaze context as it
|
||||
existed immediately prior to the exception occurrence. A pointer to this
|
||||
structure is passed into the vApplicationExceptionRegisterDump() callback
|
||||
function, if one is defined. */
|
||||
static xPortRegisterDump xRegisterDump;
|
||||
|
||||
/* This is the FreeRTOS exception handler that is installed for all exception
|
||||
types. It is called from vPortExceptionHanlderEntry() - which is itself defined
|
||||
in portasm.S. */
|
||||
void vPortExceptionHandler( void *pvExceptionID );
|
||||
extern void vPortExceptionHandlerEntry( void *pvExceptionID );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||
application can optionally define to receive a populated xPortRegisterDump
|
||||
structure. If the application chooses not to define a version of
|
||||
vApplicationExceptionRegisterDump() then this weekly defined default
|
||||
implementation will be called instead. */
|
||||
extern void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump ) __attribute__((weak));
|
||||
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
|
||||
{
|
||||
( void ) xRegisterDump;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
portNOP();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExceptionHandler( void *pvExceptionID )
|
||||
{
|
||||
extern void *pxCurrentTCB;
|
||||
|
||||
/* Fill an xPortRegisterDump structure with the MicroBlaze context as it
|
||||
was immediately before the exception occurrence. */
|
||||
|
||||
/* First fill in the name and handle of the task that was in the Running
|
||||
state when the exception occurred. */
|
||||
xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;
|
||||
xRegisterDump.pcCurrentTaskName = pcTaskGetName( NULL );
|
||||
|
||||
configASSERT( pulStackPointerOnFunctionEntry );
|
||||
|
||||
/* Obtain the values of registers that were stacked prior to this function
|
||||
being called, and may have changed since they were stacked. */
|
||||
xRegisterDump.ulR3 = pulStackPointerOnFunctionEntry[ portexR3_STACK_OFFSET ];
|
||||
xRegisterDump.ulR4 = pulStackPointerOnFunctionEntry[ portexR4_STACK_OFFSET ];
|
||||
xRegisterDump.ulR5 = pulStackPointerOnFunctionEntry[ portexR5_STACK_OFFSET ];
|
||||
xRegisterDump.ulR6 = pulStackPointerOnFunctionEntry[ portexR6_STACK_OFFSET ];
|
||||
xRegisterDump.ulR7 = pulStackPointerOnFunctionEntry[ portexR7_STACK_OFFSET ];
|
||||
xRegisterDump.ulR8 = pulStackPointerOnFunctionEntry[ portexR8_STACK_OFFSET ];
|
||||
xRegisterDump.ulR9 = pulStackPointerOnFunctionEntry[ portexR9_STACK_OFFSET ];
|
||||
xRegisterDump.ulR10 = pulStackPointerOnFunctionEntry[ portexR10_STACK_OFFSET ];
|
||||
xRegisterDump.ulR11 = pulStackPointerOnFunctionEntry[ portexR11_STACK_OFFSET ];
|
||||
xRegisterDump.ulR12 = pulStackPointerOnFunctionEntry[ portexR12_STACK_OFFSET ];
|
||||
xRegisterDump.ulR15_return_address_from_subroutine = pulStackPointerOnFunctionEntry[ portexR15_STACK_OFFSET ];
|
||||
xRegisterDump.ulR18 = pulStackPointerOnFunctionEntry[ portexR18_STACK_OFFSET ];
|
||||
xRegisterDump.ulR19 = pulStackPointerOnFunctionEntry[ portexR19_STACK_OFFSET ];
|
||||
xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];
|
||||
|
||||
/* Obtain the value of all other registers. */
|
||||
xRegisterDump.ulR2_small_data_area = mfgpr( R2 );
|
||||
xRegisterDump.ulR13_read_write_small_data_area = mfgpr( R13 );
|
||||
xRegisterDump.ulR14_return_address_from_interrupt = mfgpr( R14 );
|
||||
xRegisterDump.ulR16_return_address_from_trap = mfgpr( R16 );
|
||||
xRegisterDump.ulR17_return_address_from_exceptions = mfgpr( R17 );
|
||||
xRegisterDump.ulR20 = mfgpr( R20 );
|
||||
xRegisterDump.ulR21 = mfgpr( R21 );
|
||||
xRegisterDump.ulR22 = mfgpr( R22 );
|
||||
xRegisterDump.ulR23 = mfgpr( R23 );
|
||||
xRegisterDump.ulR24 = mfgpr( R24 );
|
||||
xRegisterDump.ulR25 = mfgpr( R25 );
|
||||
xRegisterDump.ulR26 = mfgpr( R26 );
|
||||
xRegisterDump.ulR27 = mfgpr( R27 );
|
||||
xRegisterDump.ulR28 = mfgpr( R28 );
|
||||
xRegisterDump.ulR29 = mfgpr( R29 );
|
||||
xRegisterDump.ulR30 = mfgpr( R30 );
|
||||
xRegisterDump.ulR31 = mfgpr( R31 );
|
||||
xRegisterDump.ulR1_SP = ( ( uint32_t ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE;
|
||||
xRegisterDump.ulEAR = mfear();
|
||||
xRegisterDump.ulESR = mfesr();
|
||||
xRegisterDump.ulEDR = mfedr();
|
||||
|
||||
/* Move the saved program counter back to the instruction that was executed
|
||||
when the exception occurred. This is only valid for certain types of
|
||||
exception. */
|
||||
xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_exceptions - portexINSTRUCTION_SIZE;
|
||||
|
||||
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||
{
|
||||
xRegisterDump.ulFSR = mffsr();
|
||||
}
|
||||
#else
|
||||
{
|
||||
xRegisterDump.ulFSR = 0UL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Also fill in a string that describes what type of exception this is.
|
||||
The string uses the same ID names as defined in the MicroBlaze standard
|
||||
library exception header files. */
|
||||
switch( ( uint32_t ) pvExceptionID )
|
||||
{
|
||||
case XEXC_ID_FSL :
|
||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FSL";
|
||||
break;
|
||||
|
||||
case XEXC_ID_UNALIGNED_ACCESS :
|
||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_UNALIGNED_ACCESS";
|
||||
break;
|
||||
|
||||
case XEXC_ID_ILLEGAL_OPCODE :
|
||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_ILLEGAL_OPCODE";
|
||||
break;
|
||||
|
||||
case XEXC_ID_M_AXI_I_EXCEPTION :
|
||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_I_EXCEPTION or XEXC_ID_IPLB_EXCEPTION";
|
||||
break;
|
||||
|
||||
case XEXC_ID_M_AXI_D_EXCEPTION :
|
||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_M_AXI_D_EXCEPTION or XEXC_ID_DPLB_EXCEPTION";
|
||||
break;
|
||||
|
||||
case XEXC_ID_DIV_BY_ZERO :
|
||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_DIV_BY_ZERO";
|
||||
break;
|
||||
|
||||
case XEXC_ID_STACK_VIOLATION :
|
||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
|
||||
break;
|
||||
|
||||
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||
|
||||
case XEXC_ID_FPU :
|
||||
xRegisterDump.pcExceptionCause = ( int8_t * const ) "XEXC_ID_FPU see ulFSR value";
|
||||
break;
|
||||
|
||||
#endif /* XPAR_MICROBLAZE_USE_FPU */
|
||||
}
|
||||
|
||||
/* vApplicationExceptionRegisterDump() is a callback function that the
|
||||
application can optionally define to receive the populated xPortRegisterDump
|
||||
structure. If the application chooses not to define a version of
|
||||
vApplicationExceptionRegisterDump() then the weekly defined default
|
||||
implementation within this file will be called instead. */
|
||||
vApplicationExceptionRegisterDump( &xRegisterDump );
|
||||
|
||||
/* Must not attempt to leave this function! */
|
||||
for( ;; )
|
||||
{
|
||||
portNOP();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExceptionsInstallHandlers( void )
|
||||
{
|
||||
static uint32_t ulHandlersAlreadyInstalled = pdFALSE;
|
||||
|
||||
if( ulHandlersAlreadyInstalled == pdFALSE )
|
||||
{
|
||||
ulHandlersAlreadyInstalled = pdTRUE;
|
||||
|
||||
#if XPAR_MICROBLAZE_UNALIGNED_EXCEPTIONS == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_UNALIGNED_ACCESS, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_UNALIGNED_ACCESS );
|
||||
#endif /* XPAR_MICROBLAZE_UNALIGNED_EXCEPTIONS*/
|
||||
|
||||
#if XPAR_MICROBLAZE_ILL_OPCODE_EXCEPTION == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_ILLEGAL_OPCODE, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_ILLEGAL_OPCODE );
|
||||
#endif /* XPAR_MICROBLAZE_ILL_OPCODE_EXCEPTION */
|
||||
|
||||
#if XPAR_MICROBLAZE_M_AXI_I_BUS_EXCEPTION == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_M_AXI_I_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_M_AXI_I_EXCEPTION );
|
||||
#endif /* XPAR_MICROBLAZE_M_AXI_I_BUS_EXCEPTION */
|
||||
|
||||
#if XPAR_MICROBLAZE_M_AXI_D_BUS_EXCEPTION == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_M_AXI_D_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_M_AXI_D_EXCEPTION );
|
||||
#endif /* XPAR_MICROBLAZE_M_AXI_D_BUS_EXCEPTION */
|
||||
|
||||
#if XPAR_MICROBLAZE_IPLB_BUS_EXCEPTION == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_IPLB_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_IPLB_EXCEPTION );
|
||||
#endif /* XPAR_MICROBLAZE_IPLB_BUS_EXCEPTION */
|
||||
|
||||
#if XPAR_MICROBLAZE_DPLB_BUS_EXCEPTION == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_DPLB_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_DPLB_EXCEPTION );
|
||||
#endif /* XPAR_MICROBLAZE_DPLB_BUS_EXCEPTION */
|
||||
|
||||
#if XPAR_MICROBLAZE_DIV_ZERO_EXCEPTION == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_DIV_BY_ZERO, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_DIV_BY_ZERO );
|
||||
#endif /* XPAR_MICROBLAZE_DIV_ZERO_EXCEPTION */
|
||||
|
||||
#if XPAR_MICROBLAZE_FPU_EXCEPTION == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_FPU, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FPU );
|
||||
#endif /* XPAR_MICROBLAZE_FPU_EXCEPTION */
|
||||
|
||||
#if XPAR_MICROBLAZE_FSL_EXCEPTION == 1
|
||||
microblaze_register_exception_handler( XEXC_ID_FSL, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FSL );
|
||||
#endif /* XPAR_MICROBLAZE_FSL_EXCEPTION */
|
||||
|
||||
microblaze_enable_exceptions();
|
||||
}
|
||||
}
|
||||
|
||||
/* Exclude the entire file if the MicroBlaze is not configured to handle
|
||||
exceptions, or the application defined configuration item
|
||||
configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
|
||||
#endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */
|
||||
|
||||
|
||||
|
@ -0,0 +1,370 @@
|
||||
/*
|
||||
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
/* Xilinx library includes. */
|
||||
#include "microblaze_exceptions_g.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/* The context is oversized to allow functions called from the ISR to write
|
||||
back into the caller stack. */
|
||||
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||
#define portCONTEXT_SIZE 136
|
||||
#define portMINUS_CONTEXT_SIZE -136
|
||||
#else
|
||||
#define portCONTEXT_SIZE 132
|
||||
#define portMINUS_CONTEXT_SIZE -132
|
||||
#endif
|
||||
|
||||
/* Offsets from the stack pointer at which saved registers are placed. */
|
||||
#define portR31_OFFSET 4
|
||||
#define portR30_OFFSET 8
|
||||
#define portR29_OFFSET 12
|
||||
#define portR28_OFFSET 16
|
||||
#define portR27_OFFSET 20
|
||||
#define portR26_OFFSET 24
|
||||
#define portR25_OFFSET 28
|
||||
#define portR24_OFFSET 32
|
||||
#define portR23_OFFSET 36
|
||||
#define portR22_OFFSET 40
|
||||
#define portR21_OFFSET 44
|
||||
#define portR20_OFFSET 48
|
||||
#define portR19_OFFSET 52
|
||||
#define portR18_OFFSET 56
|
||||
#define portR17_OFFSET 60
|
||||
#define portR16_OFFSET 64
|
||||
#define portR15_OFFSET 68
|
||||
#define portR14_OFFSET 72
|
||||
#define portR13_OFFSET 76
|
||||
#define portR12_OFFSET 80
|
||||
#define portR11_OFFSET 84
|
||||
#define portR10_OFFSET 88
|
||||
#define portR9_OFFSET 92
|
||||
#define portR8_OFFSET 96
|
||||
#define portR7_OFFSET 100
|
||||
#define portR6_OFFSET 104
|
||||
#define portR5_OFFSET 108
|
||||
#define portR4_OFFSET 112
|
||||
#define portR3_OFFSET 116
|
||||
#define portR2_OFFSET 120
|
||||
#define portCRITICAL_NESTING_OFFSET 124
|
||||
#define portMSR_OFFSET 128
|
||||
#define portFSR_OFFSET 132
|
||||
|
||||
.extern pxCurrentTCB
|
||||
.extern XIntc_DeviceInterruptHandler
|
||||
.extern vTaskSwitchContext
|
||||
.extern uxCriticalNesting
|
||||
.extern pulISRStack
|
||||
.extern ulTaskSwitchRequested
|
||||
.extern vPortExceptionHandler
|
||||
.extern pulStackPointerOnFunctionEntry
|
||||
|
||||
.global _interrupt_handler
|
||||
.global VPortYieldASM
|
||||
.global vPortStartFirstTask
|
||||
.global vPortExceptionHandlerEntry
|
||||
|
||||
|
||||
.macro portSAVE_CONTEXT
|
||||
|
||||
/* Make room for the context on the stack. */
|
||||
addik r1, r1, portMINUS_CONTEXT_SIZE
|
||||
|
||||
/* Stack general registers. */
|
||||
swi r31, r1, portR31_OFFSET
|
||||
swi r30, r1, portR30_OFFSET
|
||||
swi r29, r1, portR29_OFFSET
|
||||
swi r28, r1, portR28_OFFSET
|
||||
swi r27, r1, portR27_OFFSET
|
||||
swi r26, r1, portR26_OFFSET
|
||||
swi r25, r1, portR25_OFFSET
|
||||
swi r24, r1, portR24_OFFSET
|
||||
swi r23, r1, portR23_OFFSET
|
||||
swi r22, r1, portR22_OFFSET
|
||||
swi r21, r1, portR21_OFFSET
|
||||
swi r20, r1, portR20_OFFSET
|
||||
swi r19, r1, portR19_OFFSET
|
||||
swi r18, r1, portR18_OFFSET
|
||||
swi r17, r1, portR17_OFFSET
|
||||
swi r16, r1, portR16_OFFSET
|
||||
swi r15, r1, portR15_OFFSET
|
||||
/* R14 is saved later as it needs adjustment if a yield is performed. */
|
||||
swi r13, r1, portR13_OFFSET
|
||||
swi r12, r1, portR12_OFFSET
|
||||
swi r11, r1, portR11_OFFSET
|
||||
swi r10, r1, portR10_OFFSET
|
||||
swi r9, r1, portR9_OFFSET
|
||||
swi r8, r1, portR8_OFFSET
|
||||
swi r7, r1, portR7_OFFSET
|
||||
swi r6, r1, portR6_OFFSET
|
||||
swi r5, r1, portR5_OFFSET
|
||||
swi r4, r1, portR4_OFFSET
|
||||
swi r3, r1, portR3_OFFSET
|
||||
swi r2, r1, portR2_OFFSET
|
||||
|
||||
/* Stack the critical section nesting value. */
|
||||
lwi r18, r0, uxCriticalNesting
|
||||
swi r18, r1, portCRITICAL_NESTING_OFFSET
|
||||
|
||||
/* Stack MSR. */
|
||||
mfs r18, rmsr
|
||||
swi r18, r1, portMSR_OFFSET
|
||||
|
||||
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||
/* Stack FSR. */
|
||||
mfs r18, rfsr
|
||||
swi r18, r1, portFSR_OFFSET
|
||||
#endif
|
||||
|
||||
/* Save the top of stack value to the TCB. */
|
||||
lwi r3, r0, pxCurrentTCB
|
||||
sw r1, r0, r3
|
||||
|
||||
.endm
|
||||
|
||||
.macro portRESTORE_CONTEXT
|
||||
|
||||
/* Load the top of stack value from the TCB. */
|
||||
lwi r18, r0, pxCurrentTCB
|
||||
lw r1, r0, r18
|
||||
|
||||
/* Restore the general registers. */
|
||||
lwi r31, r1, portR31_OFFSET
|
||||
lwi r30, r1, portR30_OFFSET
|
||||
lwi r29, r1, portR29_OFFSET
|
||||
lwi r28, r1, portR28_OFFSET
|
||||
lwi r27, r1, portR27_OFFSET
|
||||
lwi r26, r1, portR26_OFFSET
|
||||
lwi r25, r1, portR25_OFFSET
|
||||
lwi r24, r1, portR24_OFFSET
|
||||
lwi r23, r1, portR23_OFFSET
|
||||
lwi r22, r1, portR22_OFFSET
|
||||
lwi r21, r1, portR21_OFFSET
|
||||
lwi r20, r1, portR20_OFFSET
|
||||
lwi r19, r1, portR19_OFFSET
|
||||
lwi r17, r1, portR17_OFFSET
|
||||
lwi r16, r1, portR16_OFFSET
|
||||
lwi r15, r1, portR15_OFFSET
|
||||
lwi r14, r1, portR14_OFFSET
|
||||
lwi r13, r1, portR13_OFFSET
|
||||
lwi r12, r1, portR12_OFFSET
|
||||
lwi r11, r1, portR11_OFFSET
|
||||
lwi r10, r1, portR10_OFFSET
|
||||
lwi r9, r1, portR9_OFFSET
|
||||
lwi r8, r1, portR8_OFFSET
|
||||
lwi r7, r1, portR7_OFFSET
|
||||
lwi r6, r1, portR6_OFFSET
|
||||
lwi r5, r1, portR5_OFFSET
|
||||
lwi r4, r1, portR4_OFFSET
|
||||
lwi r3, r1, portR3_OFFSET
|
||||
lwi r2, r1, portR2_OFFSET
|
||||
|
||||
/* Reload the rmsr from the stack. */
|
||||
lwi r18, r1, portMSR_OFFSET
|
||||
mts rmsr, r18
|
||||
|
||||
#if( XPAR_MICROBLAZE_USE_FPU != 0 )
|
||||
/* Reload the FSR from the stack. */
|
||||
lwi r18, r1, portFSR_OFFSET
|
||||
mts rfsr, r18
|
||||
#endif
|
||||
|
||||
/* Load the critical nesting value. */
|
||||
lwi r18, r1, portCRITICAL_NESTING_OFFSET
|
||||
swi r18, r0, uxCriticalNesting
|
||||
|
||||
/* Test the critical nesting value. If it is non zero then the task last
|
||||
exited the running state using a yield. If it is zero, then the task
|
||||
last exited the running state through an interrupt. */
|
||||
xori r18, r18, 0
|
||||
bnei r18, exit_from_yield
|
||||
|
||||
/* r18 was being used as a temporary. Now restore its true value from the
|
||||
stack. */
|
||||
lwi r18, r1, portR18_OFFSET
|
||||
|
||||
/* Remove the stack frame. */
|
||||
addik r1, r1, portCONTEXT_SIZE
|
||||
|
||||
/* Return using rtid so interrupts are re-enabled as this function is
|
||||
exited. */
|
||||
rtid r14, 0
|
||||
or r0, r0, r0
|
||||
|
||||
.endm
|
||||
|
||||
/* This function is used to exit portRESTORE_CONTEXT() if the task being
|
||||
returned to last left the Running state by calling taskYIELD() (rather than
|
||||
being preempted by an interrupt). */
|
||||
.text
|
||||
.align 4
|
||||
exit_from_yield:
|
||||
|
||||
/* r18 was being used as a temporary. Now restore its true value from the
|
||||
stack. */
|
||||
lwi r18, r1, portR18_OFFSET
|
||||
|
||||
/* Remove the stack frame. */
|
||||
addik r1, r1, portCONTEXT_SIZE
|
||||
|
||||
/* Return to the task. */
|
||||
rtsd r14, 0
|
||||
or r0, r0, r0
|
||||
|
||||
|
||||
.text
|
||||
.align 4
|
||||
_interrupt_handler:
|
||||
|
||||
portSAVE_CONTEXT
|
||||
|
||||
/* Stack the return address. */
|
||||
swi r14, r1, portR14_OFFSET
|
||||
|
||||
/* Switch to the ISR stack. */
|
||||
lwi r1, r0, pulISRStack
|
||||
|
||||
/* The parameter to the interrupt handler. */
|
||||
ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE
|
||||
|
||||
/* Execute any pending interrupts. */
|
||||
bralid r15, XIntc_DeviceInterruptHandler
|
||||
or r0, r0, r0
|
||||
|
||||
/* See if a new task should be selected to execute. */
|
||||
lwi r18, r0, ulTaskSwitchRequested
|
||||
or r18, r18, r0
|
||||
|
||||
/* If ulTaskSwitchRequested is already zero, then jump straight to
|
||||
restoring the task that is already in the Running state. */
|
||||
beqi r18, task_switch_not_requested
|
||||
|
||||
/* Set ulTaskSwitchRequested back to zero as a task switch is about to be
|
||||
performed. */
|
||||
swi r0, r0, ulTaskSwitchRequested
|
||||
|
||||
/* ulTaskSwitchRequested was not 0 when tested. Select the next task to
|
||||
execute. */
|
||||
bralid r15, vTaskSwitchContext
|
||||
or r0, r0, r0
|
||||
|
||||
task_switch_not_requested:
|
||||
|
||||
/* Restore the context of the next task scheduled to execute. */
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
|
||||
.text
|
||||
.align 4
|
||||
VPortYieldASM:
|
||||
|
||||
portSAVE_CONTEXT
|
||||
|
||||
/* Modify the return address so a return is done to the instruction after
|
||||
the call to VPortYieldASM. */
|
||||
addi r14, r14, 8
|
||||
swi r14, r1, portR14_OFFSET
|
||||
|
||||
/* Switch to use the ISR stack. */
|
||||
lwi r1, r0, pulISRStack
|
||||
|
||||
/* Select the next task to execute. */
|
||||
bralid r15, vTaskSwitchContext
|
||||
or r0, r0, r0
|
||||
|
||||
/* Restore the context of the next task scheduled to execute. */
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
.text
|
||||
.align 4
|
||||
vPortStartFirstTask:
|
||||
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
|
||||
|
||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
|
||||
|
||||
.text
|
||||
.align 4
|
||||
vPortExceptionHandlerEntry:
|
||||
|
||||
/* Take a copy of the stack pointer before vPortExecptionHandler is called,
|
||||
storing its value prior to the function stack frame being created. */
|
||||
swi r1, r0, pulStackPointerOnFunctionEntry
|
||||
bralid r15, vPortExceptionHandler
|
||||
or r0, r0, r0
|
||||
|
||||
#endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */
|
||||
|
||||
|
||||
|
@ -0,0 +1,411 @@
|
||||
/*
|
||||
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* BSP includes. */
|
||||
#include <mb_interface.h>
|
||||
#include <xparameters.h>
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Interrupt control macros and functions. */
|
||||
void microblaze_disable_interrupts( void );
|
||||
void microblaze_enable_interrupts( void );
|
||||
#define portDISABLE_INTERRUPTS() microblaze_disable_interrupts()
|
||||
#define portENABLE_INTERRUPTS() microblaze_enable_interrupts()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section macros. */
|
||||
void vPortEnterCritical( void );
|
||||
void vPortExitCritical( void );
|
||||
#define portENTER_CRITICAL() { \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
microblaze_disable_interrupts(); \
|
||||
uxCriticalNesting++; \
|
||||
}
|
||||
|
||||
#define portEXIT_CRITICAL() { \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
/* Interrupts are disabled, so we can */ \
|
||||
/* access the variable directly. */ \
|
||||
uxCriticalNesting--; \
|
||||
if( uxCriticalNesting == 0 ) \
|
||||
{ \
|
||||
/* The nesting has unwound and we \
|
||||
can enable interrupts again. */ \
|
||||
portENABLE_INTERRUPTS(); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The yield macro maps directly to the vPortYield() function. */
|
||||
void vPortYield( void );
|
||||
#define portYIELD() vPortYield()
|
||||
|
||||
/* portYIELD_FROM_ISR() does not directly call vTaskSwitchContext(), but instead
|
||||
sets a flag to say that a yield has been requested. The interrupt exit code
|
||||
then checks this flag, and calls vTaskSwitchContext() before restoring a task
|
||||
context, if the flag is not false. This is done to prevent multiple calls to
|
||||
vTaskSwitchContext() being made from a single interrupt, as a single interrupt
|
||||
can result in multiple peripherals being serviced. */
|
||||
extern volatile uint32_t ulTaskSwitchRequested;
|
||||
#define portYIELD_FROM_ISR( x ) if( ( x ) != pdFALSE ) ulTaskSwitchRequested = 1
|
||||
|
||||
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
/* Generic helper function. */
|
||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
/* Check the configuration. */
|
||||
#if( configMAX_PRIORITIES > 32 )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portNOP() asm volatile ( "NOP" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The following structure is used by the FreeRTOS exception handler. It is
|
||||
filled with the MicroBlaze context as it was at the time the exception occurred.
|
||||
This is done as an aid to debugging exception occurrences. */
|
||||
typedef struct PORT_REGISTER_DUMP
|
||||
{
|
||||
/* The following structure members hold the values of the MicroBlaze
|
||||
registers at the time the exception was raised. */
|
||||
uint32_t ulR1_SP;
|
||||
uint32_t ulR2_small_data_area;
|
||||
uint32_t ulR3;
|
||||
uint32_t ulR4;
|
||||
uint32_t ulR5;
|
||||
uint32_t ulR6;
|
||||
uint32_t ulR7;
|
||||
uint32_t ulR8;
|
||||
uint32_t ulR9;
|
||||
uint32_t ulR10;
|
||||
uint32_t ulR11;
|
||||
uint32_t ulR12;
|
||||
uint32_t ulR13_read_write_small_data_area;
|
||||
uint32_t ulR14_return_address_from_interrupt;
|
||||
uint32_t ulR15_return_address_from_subroutine;
|
||||
uint32_t ulR16_return_address_from_trap;
|
||||
uint32_t ulR17_return_address_from_exceptions; /* The exception entry code will copy the BTR into R17 if the exception occurred in the delay slot of a branch instruction. */
|
||||
uint32_t ulR18;
|
||||
uint32_t ulR19;
|
||||
uint32_t ulR20;
|
||||
uint32_t ulR21;
|
||||
uint32_t ulR22;
|
||||
uint32_t ulR23;
|
||||
uint32_t ulR24;
|
||||
uint32_t ulR25;
|
||||
uint32_t ulR26;
|
||||
uint32_t ulR27;
|
||||
uint32_t ulR28;
|
||||
uint32_t ulR29;
|
||||
uint32_t ulR30;
|
||||
uint32_t ulR31;
|
||||
uint32_t ulPC;
|
||||
uint32_t ulESR;
|
||||
uint32_t ulMSR;
|
||||
uint32_t ulEAR;
|
||||
uint32_t ulFSR;
|
||||
uint32_t ulEDR;
|
||||
|
||||
/* A human readable description of the exception cause. The strings used
|
||||
are the same as the #define constant names found in the
|
||||
microblaze_exceptions_i.h header file */
|
||||
int8_t *pcExceptionCause;
|
||||
|
||||
/* The human readable name of the task that was running at the time the
|
||||
exception occurred. This is the name that was given to the task when the
|
||||
task was created using the FreeRTOS xTaskCreate() API function. */
|
||||
char *pcCurrentTaskName;
|
||||
|
||||
/* The handle of the task that was running a the time the exception
|
||||
occurred. */
|
||||
void * xCurrentTaskHandle;
|
||||
|
||||
} xPortRegisterDump;
|
||||
|
||||
|
||||
/*
|
||||
* Installs pxHandler as the interrupt handler for the peripheral specified by
|
||||
* the ucInterruptID parameter.
|
||||
*
|
||||
* ucInterruptID:
|
||||
*
|
||||
* The ID of the peripheral that will have pxHandler assigned as its interrupt
|
||||
* handler. Peripheral IDs are defined in the xparameters.h header file, which
|
||||
* is itself part of the BSP project. For example, in the official demo
|
||||
* application for this port, xparameters.h defines the following IDs for the
|
||||
* four possible interrupt sources:
|
||||
*
|
||||
* XPAR_INTC_0_UARTLITE_1_VEC_ID - for the UARTlite peripheral.
|
||||
* XPAR_INTC_0_TMRCTR_0_VEC_ID - for the AXI Timer 0 peripheral.
|
||||
* XPAR_INTC_0_EMACLITE_0_VEC_ID - for the Ethernet lite peripheral.
|
||||
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||
*
|
||||
*
|
||||
* pxHandler:
|
||||
*
|
||||
* A pointer to the interrupt handler function itself. This must be a void
|
||||
* function that takes a (void *) parameter.
|
||||
*
|
||||
*
|
||||
* pvCallBackRef:
|
||||
*
|
||||
* The parameter passed into the handler function. In many cases this will not
|
||||
* be used and can be NULL. Some times it is used to pass in a reference to
|
||||
* the peripheral instance variable, so it can be accessed from inside the
|
||||
* handler function.
|
||||
*
|
||||
*
|
||||
* pdPASS is returned if the function executes successfully. Any other value
|
||||
* being returned indicates that the function did not execute correctly.
|
||||
*/
|
||||
BaseType_t xPortInstallInterruptHandler( uint8_t ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );
|
||||
|
||||
|
||||
/*
|
||||
* Enables the interrupt, within the interrupt controller, for the peripheral
|
||||
* specified by the ucInterruptID parameter.
|
||||
*
|
||||
* ucInterruptID:
|
||||
*
|
||||
* The ID of the peripheral that will have its interrupt enabled in the
|
||||
* interrupt controller. Peripheral IDs are defined in the xparameters.h header
|
||||
* file, which is itself part of the BSP project. For example, in the official
|
||||
* demo application for this port, xparameters.h defines the following IDs for
|
||||
* the four possible interrupt sources:
|
||||
*
|
||||
* XPAR_INTC_0_UARTLITE_1_VEC_ID - for the UARTlite peripheral.
|
||||
* XPAR_INTC_0_TMRCTR_0_VEC_ID - for the AXI Timer 0 peripheral.
|
||||
* XPAR_INTC_0_EMACLITE_0_VEC_ID - for the Ethernet lite peripheral.
|
||||
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||
*
|
||||
*/
|
||||
void vPortEnableInterrupt( uint8_t ucInterruptID );
|
||||
|
||||
/*
|
||||
* Disables the interrupt, within the interrupt controller, for the peripheral
|
||||
* specified by the ucInterruptID parameter.
|
||||
*
|
||||
* ucInterruptID:
|
||||
*
|
||||
* The ID of the peripheral that will have its interrupt disabled in the
|
||||
* interrupt controller. Peripheral IDs are defined in the xparameters.h header
|
||||
* file, which is itself part of the BSP project. For example, in the official
|
||||
* demo application for this port, xparameters.h defines the following IDs for
|
||||
* the four possible interrupt sources:
|
||||
*
|
||||
* XPAR_INTC_0_UARTLITE_1_VEC_ID - for the UARTlite peripheral.
|
||||
* XPAR_INTC_0_TMRCTR_0_VEC_ID - for the AXI Timer 0 peripheral.
|
||||
* XPAR_INTC_0_EMACLITE_0_VEC_ID - for the Ethernet lite peripheral.
|
||||
* XPAR_INTC_0_GPIO_1_VEC_ID - for the button inputs.
|
||||
*
|
||||
*/
|
||||
void vPortDisableInterrupt( uint8_t ucInterruptID );
|
||||
|
||||
/*
|
||||
* This is an application defined callback function used to install the tick
|
||||
* interrupt handler. It is provided as an application callback because the
|
||||
* kernel will run on lots of different MicroBlaze and FPGA configurations - not
|
||||
* all of which will have the same timer peripherals defined or available. This
|
||||
* example uses the AXI Timer 0. If that is available on your hardware platform
|
||||
* then this example callback implementation should not require modification.
|
||||
* The name of the interrupt handler that should be installed is vPortTickISR(),
|
||||
* which the function below declares as an extern.
|
||||
*/
|
||||
void vApplicationSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* This is an application defined callback function used to clear whichever
|
||||
* interrupt was installed by the the vApplicationSetupTimerInterrupt() callback
|
||||
* function - in this case the interrupt generated by the AXI timer. It is
|
||||
* provided as an application callback because the kernel will run on lots of
|
||||
* different MicroBlaze and FPGA configurations - not all of which will have the
|
||||
* same timer peripherals defined or available. This example uses the AXI Timer 0.
|
||||
* If that is available on your hardware platform then this example callback
|
||||
* implementation should not require modification provided the example definition
|
||||
* of vApplicationSetupTimerInterrupt() is also not modified.
|
||||
*/
|
||||
void vApplicationClearTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* vPortExceptionsInstallHandlers() is only available when the MicroBlaze
|
||||
* is configured to include exception functionality, and
|
||||
* configINSTALL_EXCEPTION_HANDLERS is set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* vPortExceptionsInstallHandlers() installs the FreeRTOS exception handler
|
||||
* for every possible exception cause.
|
||||
*
|
||||
* vPortExceptionsInstallHandlers() can be called explicitly from application
|
||||
* code. After that is done, the default FreeRTOS exception handler that will
|
||||
* have been installed can be replaced for any specific exception cause by using
|
||||
* the standard Xilinx library function microblaze_register_exception_handler().
|
||||
*
|
||||
* If vPortExceptionsInstallHandlers() is not called explicitly by the
|
||||
* application, it will be called automatically by the kernel the first time
|
||||
* xPortInstallInterruptHandler() is called. At that time, any exception
|
||||
* handlers that may have already been installed will be replaced.
|
||||
*
|
||||
* See the description of vApplicationExceptionRegisterDump() for information
|
||||
* on the processing performed by the FreeRTOS exception handler.
|
||||
*/
|
||||
void vPortExceptionsInstallHandlers( void );
|
||||
|
||||
/*
|
||||
* The FreeRTOS exception handler fills an xPortRegisterDump structure (defined
|
||||
* in portmacro.h) with the MicroBlaze context, as it was at the time the
|
||||
* exception occurred. The exception handler then calls
|
||||
* vApplicationExceptionRegisterDump(), passing in the completed
|
||||
* xPortRegisterDump structure as its parameter.
|
||||
*
|
||||
* The FreeRTOS kernel provides its own implementation of
|
||||
* vApplicationExceptionRegisterDump(), but the kernel provided implementation
|
||||
* is declared as being 'weak'. The weak definition allows the application
|
||||
* writer to provide their own implementation, should they wish to use the
|
||||
* register dump information. For example, an implementation could be provided
|
||||
* that wrote the register dump data to a display, or a UART port.
|
||||
*/
|
||||
void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
Loading…
Reference in New Issue