arm: add uart echo app
This commit is contained in:
446
arm/hal/lib/common/intr/xinterrupt_wrap.c
Normal file
446
arm/hal/lib/common/intr/xinterrupt_wrap.c
Normal file
@@ -0,0 +1,446 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xinterrupt_wrap.c
|
||||
*
|
||||
* The xinterrupt_wrap.c file contains interrupt related functions and macros.
|
||||
*
|
||||
* @{
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 7.2 mus 22/11/21 First release of xil interrupt support
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "xinterrupt_wrap.h"
|
||||
|
||||
#ifdef XIL_INTERRUPT
|
||||
|
||||
#if defined (XPAR_SCUGIC) /* available in xscugic.h */
|
||||
XScuGic XScuGicInstance;
|
||||
#endif
|
||||
|
||||
#if defined (XPAR_AXI_INTC) /* available in xintc.h */
|
||||
XIntc XIntcInstance ;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief Initializes the interrupt controller.
|
||||
*
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return XST_SUCCESS if initialization was successful
|
||||
* XST_FAILURE in case of failure
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XConfigInterruptCntrl(UINTPTR IntcParent) {
|
||||
int Status = XST_FAILURE;
|
||||
UINTPTR BaseAddr = XGet_BaseAddr(IntcParent);
|
||||
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
#if defined (XPAR_SCUGIC)
|
||||
XScuGic_Config *CfgPtr = NULL;
|
||||
if (XScuGicInstance.IsReady != XIL_COMPONENT_IS_READY) {
|
||||
CfgPtr = XScuGic_LookupConfigBaseAddr(BaseAddr);
|
||||
Status = XScuGic_CfgInitialize(&XScuGicInstance, CfgPtr, 0);
|
||||
} else {
|
||||
Status = XST_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
#else
|
||||
return XST_FAILURE;
|
||||
#endif
|
||||
} else {
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
if (XIntcInstance.IsStarted != XIL_COMPONENT_IS_STARTED)
|
||||
Status = XIntc_Initialize(&XIntcInstance, BaseAddr);
|
||||
else
|
||||
Status = XST_SUCCESS;
|
||||
return Status;
|
||||
#else
|
||||
return XST_FAILURE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief connects to the interrupt controller.
|
||||
*
|
||||
* @param IntrId: Interrupt Id.
|
||||
* @param IntrHandler: Interrupt handler.
|
||||
* @param CallBackRef: Callback reference for handler.
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return XST_SUCCESS if initialization was successful
|
||||
* XST_FAILURE in case of failure
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XConnectToInterruptCntrl(u32 IntrId, void *IntrHandler, void *CallBackRef, UINTPTR IntcParent)
|
||||
{
|
||||
int Status;
|
||||
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
|
||||
#if defined (XPAR_SCUGIC)
|
||||
u16 IntrNum = XGet_IntrId(IntrId);
|
||||
u16 Offset = XGet_IntrOffset(IntrId);
|
||||
|
||||
IntrNum += Offset;
|
||||
Status = XScuGic_Connect(&XScuGicInstance, IntrNum, \
|
||||
(Xil_ExceptionHandler) IntrHandler, CallBackRef);
|
||||
return Status;
|
||||
#else
|
||||
return XST_FAILURE;
|
||||
#endif
|
||||
} else {
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
Status = XIntc_Connect(&XIntcInstance, IntrId, \
|
||||
(XInterruptHandler)IntrHandler, CallBackRef);
|
||||
return Status;
|
||||
#else
|
||||
return XST_FAILURE;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief disconnects the interrupt controller.
|
||||
*
|
||||
* @param IntrId: Interrupt Id.
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return XST_SUCCESS if initialization was successful
|
||||
* XST_FAILURE in case of failure
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XDisconnectInterruptCntrl(u32 IntrId, UINTPTR IntcParent)
|
||||
{
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) {
|
||||
#if defined (XPAR_SCUGIC)
|
||||
u16 IntrNum = XGet_IntrId(IntrId);
|
||||
u16 Offset = XGet_IntrOffset(IntrId);
|
||||
|
||||
IntrNum += Offset;
|
||||
XScuGic_Disconnect(&XScuGicInstance, IntrNum);
|
||||
#else
|
||||
return XST_FAILURE;
|
||||
#endif
|
||||
} else {
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
XIntc_Disconnect(&XIntcInstance, IntrId);
|
||||
#else
|
||||
return XST_FAILURE;
|
||||
#endif
|
||||
}
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief Starts the interrupt controller.
|
||||
*
|
||||
* @param Mode: Interrupt controller mode type.
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return XST_SUCCESS if initialization was successful
|
||||
* XST_FAILURE in case of failure
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XStartInterruptCntrl(u32 Mode, UINTPTR IntcParent)
|
||||
{
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
int Status = XST_FAILURE;
|
||||
#else
|
||||
(void) Mode;
|
||||
#endif
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
/*
|
||||
* For XPAR_SCUGIC, XConfigInterruptCntrl starts controller
|
||||
* hence returning without doing anything
|
||||
*/
|
||||
return 0;
|
||||
} else {
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
if (XIntcInstance.IsStarted != XIL_COMPONENT_IS_STARTED)
|
||||
Status = XIntc_Start(&XIntcInstance, Mode);
|
||||
else
|
||||
Status = XST_SUCCESS;
|
||||
return Status;
|
||||
#else
|
||||
return XST_FAILURE;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief Enable the interrupt id.
|
||||
*
|
||||
* @param IntrId: Interrupt Id.
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XEnableIntrId( u32 IntrId, UINTPTR IntcParent)
|
||||
{
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
#if defined (XPAR_SCUGIC)
|
||||
u16 IntrNum = XGet_IntrId(IntrId);
|
||||
u16 Offset = XGet_IntrOffset(IntrId);
|
||||
IntrNum += Offset;
|
||||
XScuGic_Enable(&XScuGicInstance, IntrNum);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
XIntc_Enable(&XIntcInstance, IntrId);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief disable the interrupt id.
|
||||
*
|
||||
* @param IntrId: Interrupt Id.
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XDisableIntrId( u32 IntrId, UINTPTR IntcParent)
|
||||
{
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
#if defined (XPAR_SCUGIC)
|
||||
u16 IntrNum = XGet_IntrId(IntrId);
|
||||
u16 Offset = XGet_IntrOffset(IntrId);
|
||||
|
||||
IntrNum += Offset;
|
||||
XScuGic_Disable(&XScuGicInstance, IntrNum);
|
||||
#endif
|
||||
} else {
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
XIntc_Disable(&XIntcInstance, IntrId);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief Configures the priority and trigger type.
|
||||
*
|
||||
* @param IntrId: Interrupt Id.
|
||||
* @param Priority: Priority of the interrupt
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XSetPriorityTriggerType( u32 IntrId, u8 Priority, UINTPTR IntcParent)
|
||||
{
|
||||
#if defined (XPAR_SCUGIC)
|
||||
u8 Trigger = (((XGet_TriggerType(IntrId) == 1) || (XGet_TriggerType(IntrId) == 2)) ? XINTR_IS_EDGE_TRIGGERED
|
||||
: XINTR_IS_LEVEL_TRIGGERED);
|
||||
#else
|
||||
(void) Priority;
|
||||
#endif
|
||||
u16 IntrNum = XGet_IntrId(IntrId);
|
||||
u16 Offset = XGet_IntrOffset(IntrId);
|
||||
|
||||
IntrNum += Offset;
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
#if defined (XPAR_SCUGIC)
|
||||
XScuGic_SetPriorityTriggerType(&XScuGicInstance, IntrNum, Priority, Trigger);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief Gets the priority of the interrupt controller.
|
||||
*
|
||||
* @param IntrId: Interrupt Id.
|
||||
* @param Priority: Priority of the interrupt
|
||||
* @param Trigger: Trigger type of the interrupt
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XGetPriorityTriggerType( u32 IntrId, u8 *Priority, u8 *Trigger, UINTPTR IntcParent)
|
||||
{
|
||||
#if !defined (XPAR_SCUGIC)
|
||||
(void) IntrId;
|
||||
(void) Priority;
|
||||
(void) Trigger;
|
||||
#endif
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
#if defined (XPAR_SCUGIC)
|
||||
XScuGic_GetPriorityTriggerType(&XScuGicInstance, IntrId, Priority, Trigger);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief stops the interrupt controller.
|
||||
*
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XStopInterruptCntrl( UINTPTR IntcParent)
|
||||
{
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
#if defined (XPAR_SCUGIC)
|
||||
XScuGic_Stop(&XScuGicInstance);
|
||||
#endif
|
||||
} else {
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
XIntc_Stop(&XIntcInstance);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief Registers the interrupt handler.
|
||||
*
|
||||
* @param IntrHandler: Interrupt handler.
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XRegisterInterruptHandler(void *IntrHandler, UINTPTR IntcParent)
|
||||
{
|
||||
if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC)
|
||||
{
|
||||
#if defined (XPAR_SCUGIC)
|
||||
if (IntrHandler == NULL)
|
||||
{
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \
|
||||
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
|
||||
&XScuGicInstance);
|
||||
} else {
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \
|
||||
(Xil_ExceptionHandler) IntrHandler,
|
||||
&XScuGicInstance);
|
||||
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
if (IntrHandler == NULL)
|
||||
{
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \
|
||||
(Xil_ExceptionHandler) XIntc_InterruptHandler,
|
||||
&XIntcInstance);
|
||||
} else {
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \
|
||||
(Xil_ExceptionHandler) IntrHandler,
|
||||
&XIntcInstance);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @brief Setup the interrupt system.
|
||||
*
|
||||
* @param DriverInstance: Driver instance pointer.
|
||||
* @param IntrHandler: Interrupt handler funtion pointer.
|
||||
* @param IntrId: Interrupt Id.
|
||||
* @param IntcParent: Interrupt controller baseaddress and type.
|
||||
* @param Priority: Interrupt priority.
|
||||
*
|
||||
* @return XST_SUCCESS if initialization was successful
|
||||
* XST_FAILURE in case of failure
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XSetupInterruptSystem(void *DriverInstance, void *IntrHandler, u32 IntrId, UINTPTR IntcParent, u16 Priority)
|
||||
{
|
||||
int Status;
|
||||
|
||||
Status = XConfigInterruptCntrl(IntcParent);
|
||||
if (Status != XST_SUCCESS)
|
||||
return XST_FAILURE;
|
||||
XSetPriorityTriggerType( IntrId, Priority, IntcParent);
|
||||
Status = XConnectToInterruptCntrl( IntrId, (Xil_ExceptionHandler) IntrHandler, \
|
||||
DriverInstance, IntcParent);
|
||||
if (Status != XST_SUCCESS)
|
||||
return XST_FAILURE;
|
||||
#if defined (XPAR_AXI_INTC)
|
||||
XStartInterruptCntrl(XIN_REAL_MODE, IntcParent);
|
||||
#endif
|
||||
XEnableIntrId(IntrId, IntcParent);
|
||||
XRegisterInterruptHandler(NULL, IntcParent);
|
||||
Xil_ExceptionInit();
|
||||
Xil_ExceptionEnable();
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
#endif
|
74
arm/hal/lib/common/intr/xinterrupt_wrap.h
Normal file
74
arm/hal/lib/common/intr/xinterrupt_wrap.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2021 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xinterrupt_wrap.h
|
||||
*
|
||||
* The xinterrupt_wrap.h file contains interrupt related functions and macros.
|
||||
*
|
||||
* @{
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 7.2 mus 22/11/21 First release of xil interrupt support
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XINTERRUPT_WRAP_H /* prevent circular inclusions */
|
||||
#define XINTERRUPT_WRAP_H /* by using protection macros */
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xstatus.h"
|
||||
#include "xparameters.h"
|
||||
#include "xil_exception.h"
|
||||
|
||||
#ifdef XIL_INTERRUPT
|
||||
#if defined(XPAR_AXI_INTC)
|
||||
#include "xintc.h"
|
||||
#endif
|
||||
|
||||
#if defined(XPAR_SCUGIC)
|
||||
#include "xscugic.h"
|
||||
#define XSPI_INTR_OFFSET 32U
|
||||
#endif
|
||||
|
||||
#define XINTERRUPT_DEFAULT_PRIORITY 0xA0U /* AXI INTC doesnt support priority setting, it is default priority for GIC interrupts */
|
||||
#define XINTC_TYPE_IS_SCUGIC 0U
|
||||
#define XINTC_TYPE_IS_INTC 1U
|
||||
#define XINTR_IS_EDGE_TRIGGERED 3U
|
||||
#define XINTR_IS_LEVEL_TRIGGERED 1U
|
||||
|
||||
#define XINTC_TYPE_MASK 0x1
|
||||
#define XINTC_INTR_TYPE_MASK 0x100000
|
||||
#define XINTC_BASEADDR_MASK 0xFFFFFFFFFFFFFFFE
|
||||
#define XINTC_INTRID_MASK 0xFFF
|
||||
#define XINTC_TRIGGER_MASK 0xF000
|
||||
#define XINTC_TRIGGER_SHIFT 12
|
||||
#define XINTC_INTR_TYPE_SHIFT 20U
|
||||
#define XGet_IntcType(IntParent) (IntParent & XINTC_TYPE_MASK)
|
||||
#define XGet_IntrType(IntId) ((IntId & XINTC_INTR_TYPE_MASK) >> XINTC_INTR_TYPE_SHIFT)
|
||||
#define XGet_BaseAddr(IntParent) (IntParent & XINTC_BASEADDR_MASK)
|
||||
#define XGet_IntrId(IntId) (IntId & XINTC_INTRID_MASK)
|
||||
#define XGet_TriggerType(IntId) ((IntId & XINTC_TRIGGER_MASK) >> XINTC_TRIGGER_SHIFT)
|
||||
#define XGet_IntrOffset(IntId) (( XGet_IntrType(IntId) == 1) ? 16 : 32) /* For PPI offset is 16 and for SPI it is 32 */
|
||||
|
||||
extern int XConfigInterruptCntrl(UINTPTR IntcParent);
|
||||
extern int XConnectToInterruptCntrl(u32 IntrId, void *IntrHandler, void *CallBackRef, UINTPTR IntcParent);
|
||||
extern int XDisconnectInterruptCntrl(u32 IntrId, UINTPTR IntcParent);
|
||||
extern int XStartInterruptCntrl(u32 Mode, UINTPTR IntcParent);
|
||||
extern void XEnableIntrId( u32 IntrId, UINTPTR IntcParent);
|
||||
extern void XDisableIntrId( u32 IntrId, UINTPTR IntcParent);
|
||||
extern void XSetPriorityTriggerType( u32 IntrId, u8 Priority, UINTPTR IntcParent);
|
||||
extern void XGetPriorityTriggerType( u32 IntrId, u8 *Priority, u8 *Trigger, UINTPTR IntcParent);
|
||||
extern void XStopInterruptCntrl( UINTPTR IntcParent);
|
||||
extern void XRegisterInterruptHandler( void *IntrHandler, UINTPTR IntcParent);
|
||||
extern int XSetupInterruptSystem(void *DriverInstance, void *IntrHandler, u32 IntrId, UINTPTR IntcParent, u16 Priority);
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
Reference in New Issue
Block a user