arm: add uart echo app
This commit is contained in:
309
arm/hal/uart/xuartlite_intr.c
Normal file
309
arm/hal/uart/xuartlite_intr.c
Normal file
@@ -0,0 +1,309 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xuartlite_intr.c
|
||||
* @addtogroup uartlite_v3_7
|
||||
* @{
|
||||
*
|
||||
* This file contains interrupt-related functions for the UART Lite component
|
||||
* (XUartLite).
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a ecm 08/31/01 First release
|
||||
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
|
||||
* 1.02a rpm 02/14/07 Added check for outstanding transmission before
|
||||
* calling the send callback (avoids extraneous
|
||||
* callback invocations)
|
||||
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. The macros have been
|
||||
* renamed to remove _m from the name.
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xuartlite.h"
|
||||
#include "xuartlite_i.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
/************************** Constant Definitions ****************************/
|
||||
|
||||
/**************************** Type Definitions ******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions ********************/
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
static void ReceiveDataHandler(XUartLite *InstancePtr);
|
||||
static void SendDataHandler(XUartLite *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions ****************************/
|
||||
|
||||
typedef void (*Handler)(XUartLite *InstancePtr);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the handler that will be called when an event (interrupt)
|
||||
* occurs in the driver. The purpose of the handler is to allow application
|
||||
* specific processing to be performed.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XUartLite instance.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
* @param CallBackRef is the upper layer callback reference passed back
|
||||
* when the callback function is invoked.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note There is no assert on the CallBackRef since the driver doesn't
|
||||
* know what it is (nor should it)
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XUartLite_SetRecvHandler(XUartLite *InstancePtr,
|
||||
XUartLite_Handler FuncPtr, void *CallBackRef)
|
||||
{
|
||||
/*
|
||||
* Assert validates the input arguments
|
||||
* CallBackRef not checked, no way to know what is valid
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
InstancePtr->RecvHandler = FuncPtr;
|
||||
InstancePtr->RecvCallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sets the handler that will be called when an event (interrupt)
|
||||
* occurs in the driver. The purpose of the handler is to allow application
|
||||
* specific processing to be performed.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XUartLite instance .
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
* @param CallBackRef is the upper layer callback reference passed back
|
||||
* when the callback function is invoked.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note There is no assert on the CallBackRef since the driver doesn't
|
||||
* know what it is (nor should it)
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XUartLite_SetSendHandler(XUartLite *InstancePtr,
|
||||
XUartLite_Handler FuncPtr, void *CallBackRef)
|
||||
{
|
||||
/*
|
||||
* Assert validates the input arguments
|
||||
* CallBackRef not checked, no way to know what is valid
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(FuncPtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
InstancePtr->SendHandler = FuncPtr;
|
||||
InstancePtr->SendCallBackRef = CallBackRef;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is the interrupt handler for the UART lite driver.
|
||||
* It must be connected to an interrupt system by the user such that it is
|
||||
* called when an interrupt for any UART lite occurs. This function
|
||||
* does not save or restore the processor context such that the user must
|
||||
* ensure this occurs.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the instance of the UART that
|
||||
* the interrupt is for.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XUartLite_InterruptHandler(XUartLite *InstancePtr)
|
||||
{
|
||||
u32 IsrStatus;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Read the status register to determine which, coulb be both
|
||||
* interrupt is active
|
||||
*/
|
||||
IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress,
|
||||
XUL_STATUS_REG_OFFSET);
|
||||
|
||||
if ((IsrStatus & (XUL_SR_RX_FIFO_FULL |
|
||||
XUL_SR_RX_FIFO_VALID_DATA)) != 0) {
|
||||
ReceiveDataHandler(InstancePtr);
|
||||
}
|
||||
|
||||
if (((IsrStatus & XUL_SR_TX_FIFO_EMPTY) != 0) &&
|
||||
(InstancePtr->SendBuffer.RequestedBytes > 0)) {
|
||||
SendDataHandler(InstancePtr);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function handles the interrupt when data is received, either a single
|
||||
* byte when FIFOs are not enabled, or multiple bytes with the FIFO.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XUartLite instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void ReceiveDataHandler(XUartLite *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* If there are bytes still to be received in the specified buffer
|
||||
* go ahead and receive them
|
||||
*/
|
||||
if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) {
|
||||
XUartLite_ReceiveBuffer(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the last byte of a message was received then call the application
|
||||
* handler, this code should not use an else from the previous check of
|
||||
* the number of bytes to receive because the call to receive the buffer
|
||||
* updates the bytes to receive
|
||||
*/
|
||||
if (InstancePtr->ReceiveBuffer.RemainingBytes == 0) {
|
||||
InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef,
|
||||
InstancePtr->ReceiveBuffer.RequestedBytes -
|
||||
InstancePtr->ReceiveBuffer.RemainingBytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the receive stats to reflect the receive interrupt
|
||||
*/
|
||||
InstancePtr->Stats.ReceiveInterrupts++;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function handles the interrupt when data has been sent, the transmit
|
||||
* FIFO is empty (transmitter holding register).
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XUartLite instance .
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void SendDataHandler(XUartLite *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* If there are not bytes to be sent from the specified buffer,
|
||||
* call the callback function
|
||||
*/
|
||||
if (InstancePtr->SendBuffer.RemainingBytes == 0) {
|
||||
int SaveReq;
|
||||
|
||||
/*
|
||||
* Save and zero the requested bytes since transmission
|
||||
* is complete
|
||||
*/
|
||||
SaveReq = InstancePtr->SendBuffer.RequestedBytes;
|
||||
InstancePtr->SendBuffer.RequestedBytes = 0;
|
||||
|
||||
/*
|
||||
* Call the application handler to indicate
|
||||
* the data has been sent
|
||||
*/
|
||||
InstancePtr->SendHandler(InstancePtr->SendCallBackRef, SaveReq);
|
||||
}
|
||||
/*
|
||||
* Otherwise there is still more data to send in the specified buffer
|
||||
* so go ahead and send it
|
||||
*/
|
||||
else {
|
||||
XUartLite_SendBuffer(InstancePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the transmit stats to reflect the transmit interrupt
|
||||
*/
|
||||
InstancePtr->Stats.TransmitInterrupts++;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function disables the UART interrupt. After calling this function,
|
||||
* data may still be received by the UART but no interrupt will be generated
|
||||
* since the hardware device has no way to disable the receiver.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XUartLite instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XUartLite_DisableInterrupt(XUartLite *InstancePtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Write to the control register to disable the interrupts, the only
|
||||
* other bits in this register are the FIFO reset bits such that
|
||||
* writing them to zero will not affect them.
|
||||
*/
|
||||
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
|
||||
XUL_CONTROL_REG_OFFSET, 0);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function enables the UART interrupt such that an interrupt will occur
|
||||
* when data is received or data has been transmitted. The device contains
|
||||
* 16 byte receive and transmit FIFOs such that an interrupt is generated
|
||||
* anytime there is data in the receive FIFO and when the transmit FIFO
|
||||
* transitions from not empty to empty.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XUartLite instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XUartLite_EnableInterrupt(XUartLite *InstancePtr)
|
||||
{
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Write to the control register to enable the interrupts, the only
|
||||
* other bits in this register are the FIFO reset bits such that
|
||||
* writing them to zero will not affect them.
|
||||
*/
|
||||
XUartLite_WriteReg(InstancePtr->RegBaseAddress,
|
||||
XUL_CONTROL_REG_OFFSET, XUL_CR_ENABLE_INTR);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
Reference in New Issue
Block a user