mirror of
https://github.com/Dev-KATECH/ADM.git
synced 2026-05-17 01:43:59 +09:00
2054 lines
88 KiB
C
2054 lines
88 KiB
C
/*==================================================================================================
|
|
* Project : RTD AUTOSAR 4.4
|
|
* Platform : CORTEXM
|
|
* Peripheral : FLEXIO
|
|
* Dependencies :
|
|
*
|
|
* Autosar Version : 4.4.0
|
|
* Autosar Revision : ASR_REL_4_4_REV_0000
|
|
* Autosar Conf.Variant :
|
|
* SW Version : 0.9.0
|
|
* Build Version : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326
|
|
*
|
|
* (c) Copyright 2020 - 2021 NXP Semiconductors
|
|
* All Rights Reserved.
|
|
*
|
|
* NXP Confidential. This software is owned or controlled by NXP and may only be
|
|
* used strictly in accordance with the applicable license terms. By expressly
|
|
* accepting such terms or by downloading, installing, activating and/or otherwise
|
|
* using the software, you are agreeing that you have read, and that you agree to
|
|
* comply with and are bound by, such license terms. If you do not agree to be
|
|
* bound by the applicable license terms, then you may not retain, install,
|
|
* activate or otherwise use the software.
|
|
==================================================================================================*/
|
|
/**
|
|
* @file Lpuart_Uart_Ip.c
|
|
* @defgroup lpuart_uart_ip Lpuart UART IPL
|
|
* @addtogroup lpuart_uart_ip Lpuart UART IPL
|
|
* @{
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"{
|
|
#endif
|
|
|
|
/*==================================================================================================
|
|
* INCLUDE FILES
|
|
* 1) system and project includes
|
|
* 2) needed interfaces from external units
|
|
* 3) internal and external interfaces from this unit
|
|
==================================================================================================*/
|
|
|
|
#include "Lpuart_Uart_Ip.h"
|
|
#include "Lpuart_Uart_Ip_HwAccess.h"
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
#include "Dma_Ip.h"
|
|
#endif
|
|
|
|
#ifdef LPUART_UART_IP_DEV_ERROR_DETECT
|
|
#if (LPUART_UART_IP_DEV_ERROR_DETECT == STD_ON)
|
|
#include "Devassert.h"
|
|
#endif /* (STD_ON == LPUART_UART_IP_DEV_ERROR_DETECT) */
|
|
#endif /* idfef LPUART_UART_IP_DEV_ERROR_DETECT */
|
|
|
|
/*==================================================================================================
|
|
* SOURCE FILE VERSION INFORMATION
|
|
==================================================================================================*/
|
|
|
|
#define LPUART_UART_IP_VENDOR_ID_C 43
|
|
#define LPUART_UART_IP_AR_RELEASE_MAJOR_VERSION_C 4
|
|
#define LPUART_UART_IP_AR_RELEASE_MINOR_VERSION_C 4
|
|
#define LPUART_UART_IP_AR_RELEASE_REVISION_VERSION_C 0
|
|
#define LPUART_UART_IP_SW_MAJOR_VERSION_C 0
|
|
#define LPUART_UART_IP_SW_MINOR_VERSION_C 9
|
|
#define LPUART_UART_IP_SW_PATCH_VERSION_C 0
|
|
|
|
/*==================================================================================================
|
|
* FILE VERSION CHECKS
|
|
==================================================================================================*/
|
|
/* Checks against Lpuart_Uart_Ip.h */
|
|
#if (LPUART_UART_IP_VENDOR_ID_C != LPUART_UART_IP_VENDOR_ID)
|
|
#error "Lpuart_Uart_Ip.c and Lpuart_Uart_Ip.h have different vendor ids"
|
|
#endif
|
|
#if ((LPUART_UART_IP_AR_RELEASE_MAJOR_VERSION_C != LPUART_UART_IP_AR_RELEASE_MAJOR_VERSION) || \
|
|
(LPUART_UART_IP_AR_RELEASE_MINOR_VERSION_C != LPUART_UART_IP_AR_RELEASE_MINOR_VERSION) || \
|
|
(LPUART_UART_IP_AR_RELEASE_REVISION_VERSION_C != LPUART_UART_IP_AR_RELEASE_REVISION_VERSION))
|
|
#error "AUTOSAR Version Numbers of Lpuart_Uart_Ip.c and Lpuart_Uart_Ip.h are different"
|
|
#endif
|
|
#if ((LPUART_UART_IP_SW_MAJOR_VERSION_C != LPUART_UART_IP_SW_MAJOR_VERSION) || \
|
|
(LPUART_UART_IP_SW_MINOR_VERSION_C != LPUART_UART_IP_SW_MINOR_VERSION) || \
|
|
(LPUART_UART_IP_SW_PATCH_VERSION_C != LPUART_UART_IP_SW_PATCH_VERSION))
|
|
#error "Software Version Numbers of Lpuart_Uart_Ip.c and Lpuart_Uart_Ip.h are different"
|
|
#endif
|
|
/*==================================================================================================
|
|
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL MACROS
|
|
==================================================================================================*/
|
|
|
|
#ifdef LPUART_UART_IP_DEV_ERROR_DETECT
|
|
#if (LPUART_UART_IP_DEV_ERROR_DETECT == STD_ON)
|
|
#define LPUART_UART_DEV_ASSERT(x) DevAssert(x)
|
|
#else
|
|
#define LPUART_UART_DEV_ASSERT(x) (void)(x)
|
|
#endif
|
|
#endif
|
|
|
|
/* @brief Address of the least significant byte or word in a 32-bit register (depends on endianness) */
|
|
#define LPUART_UART_IP_LSBW_ADDR(reg) ((uint32)(&(reg)))
|
|
|
|
/*==================================================================================================
|
|
* LOCAL CONSTANTS
|
|
==================================================================================================*/
|
|
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
#define LPUART_UART_DMA_CONFIG_LIST_DIMENSION (10U)
|
|
#define LPUART_UART_DMA_LEAST_CONFIG_LIST_DIMENSION (2U)
|
|
#endif
|
|
|
|
/*==================================================================================================
|
|
* LOCAL VARIABLES
|
|
==================================================================================================*/
|
|
#define UART_START_SEC_VAR_NO_INIT_UNSPECIFIED_NO_CACHEABLE
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
/** @brief Array of UART driver runtime state structures */
|
|
Lpuart_Uart_Ip_StateStructureType Lpuart_Uart_Ip_apStateStructure[LPUART_UART_IP_NUMBER_OF_INSTANCES];
|
|
|
|
#define UART_STOP_SEC_VAR_NO_INIT_UNSPECIFIED_NO_CACHEABLE
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
#define UART_START_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
/* Pointer to lpuart runtime state structure */
|
|
static Lpuart_Uart_Ip_StateStructureType * Lpuart_Uart_Ip_apStateStructuresArray[LPUART_UART_IP_NUMBER_OF_INSTANCES];
|
|
|
|
/** @brief User config structure. */
|
|
const Lpuart_Uart_Ip_UserConfigType * Lpuart_Uart_Ip_apUserConfig[LPUART_UART_IP_NUMBER_OF_INSTANCES];
|
|
|
|
#define UART_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
#define UART_START_SEC_CONST_UNSPECIFIED
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
/* Table of base addresses for lpuart instances. */
|
|
static LPUART_Type * const Lpuart_Uart_Ip_apBases[LPUART_UART_IP_NUMBER_OF_INSTANCES] = FEATURE_LPUART_IP_SPECIFIC_BASE_PTR;
|
|
|
|
#define UART_STOP_SEC_CONST_UNSPECIFIED
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
#define UART_START_SEC_CONST_BOOLEAN
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
/** @brief Table storing DMA capabilities for LPUART instances. */
|
|
static const boolean Lpuart_Uart_Ip_InstHasDma[LPUART_UART_IP_NUMBER_OF_INSTANCES] = FEATURE_LPUART_IP_INST_HAS_DMA;
|
|
|
|
#define UART_STOP_SEC_CONST_BOOLEAN
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
#endif
|
|
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL CONSTANTS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL VARIABLES
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL FUNCTION PROTOTYPES
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL FUNCTIONS
|
|
==================================================================================================*/
|
|
#define UART_START_SEC_CODE
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartSendDataUsingInt(uint32 u32Instance,
|
|
const uint8 * pTxBuff,
|
|
uint32 u32TxSize);
|
|
static void Lpuart_Uart_Ip_CompleteSendDataUsingInt(uint32 u32Instance);
|
|
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartReceiveDataUsingInt(uint32 u32Instance,
|
|
uint8 * pRxBuff,
|
|
uint32 u32RxSize);
|
|
static void Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(uint32 u32Instance);
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartSendDataUsingDma(uint32 u32Instance,
|
|
const uint8 * pTxBuff,
|
|
uint32 u32TxSize);
|
|
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartReceiveDataUsingDma(uint32 u32Instance,
|
|
uint8 * pRxBuff,
|
|
uint32 u32RxSize);
|
|
#endif
|
|
static void Lpuart_Uart_Ip_PutData(uint32 u32Instance);
|
|
static void Lpuart_Uart_Ip_GetData(uint32 u32Instance);
|
|
static void Lpuart_Uart_Ip_RxIrqHandler(uint32 u32Instance);
|
|
static void Lpuart_Uart_Ip_TxEmptyIrqHandler(uint32 u32Instance);
|
|
static void Lpuart_Uart_Ip_TxCompleteIrqHandler(uint32 u32Instance);
|
|
static void Lpuart_Uart_Ip_ErrIrqHandler(uint32 u32Instance);
|
|
static void Lpuart_Uart_Ip_StartGetData(LPUART_Type * pBase, uint32 u32Instance, uint32 u32StartTime);
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL FUNCTIONS
|
|
==================================================================================================*/
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_Init
|
|
* Description : This function initializes a LPUART instance for operation.
|
|
* This function will initialize the run-time state structure to keep track of
|
|
* the on-going transfers, ungate the clock to the LPUART module, initialize the
|
|
* module to user defined settings and default settings, configure the IRQ state
|
|
* structure and enable the module-level interrupt to the core, and enable the
|
|
* LPUART module transmitter and receiver.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_Init_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_Init_Activity*/
|
|
void Lpuart_Uart_Ip_Init(uint32 u32Instance, const Lpuart_Uart_Ip_UserConfigType * pUserConfig)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
LPUART_UART_DEV_ASSERT(pUserConfig != NULL_PTR);
|
|
/* Check if current instance is already initialized. */
|
|
LPUART_UART_DEV_ASSERT(Lpuart_Uart_Ip_apStateStructuresArray[u32Instance] == NULL_PTR);
|
|
/* Check if Baudrate parameters are valid value */
|
|
LPUART_UART_DEV_ASSERT(pUserConfig->u8BaudOverSamplingRatio <= 0x20U);
|
|
LPUART_UART_DEV_ASSERT((pUserConfig->u32BaudRateDivisor <= 0x1FFFU) && \
|
|
(pUserConfig->u32BaudRateDivisor >= 1U));
|
|
|
|
LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
Lpuart_Uart_Ip_StateStructureType *pUartStatePtr;
|
|
uint32 u32Index;
|
|
|
|
Lpuart_Uart_Ip_apStateStructuresArray[u32Instance] = pUserConfig->pStateStruct;
|
|
pUartStatePtr = Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
Lpuart_Uart_Ip_apUserConfig[u32Instance] = pUserConfig;
|
|
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
/* In DMA mode, only 7-bits and 8-bits chars are supported */
|
|
LPUART_UART_DEV_ASSERT((pUserConfig->eTransferType != LPUART_UART_IP_USING_DMA) || \
|
|
(((pUserConfig->eBitCountPerChar == LPUART_UART_IP_7_BITS_PER_CHAR) || \
|
|
(pUserConfig->eBitCountPerChar == LPUART_UART_IP_8_BITS_PER_CHAR)) && \
|
|
Lpuart_Uart_Ip_InstHasDma[u32Instance]));
|
|
|
|
#endif /* (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON) */
|
|
|
|
|
|
/* For 10 bits per char, parity bit cannot be enabled */
|
|
LPUART_UART_DEV_ASSERT((pUserConfig->eBitCountPerChar != LPUART_UART_IP_10_BITS_PER_CHAR) || \
|
|
(pUserConfig->eParityMode == LPUART_UART_IP_PARITY_DISABLED));
|
|
|
|
/* Clear the state struct for this instance. */
|
|
uint8 *pClearStructPtr = (uint8 *)pUartStatePtr;
|
|
for (u32Index = 0; u32Index < sizeof(Lpuart_Uart_Ip_StateStructureType); u32Index++)
|
|
{
|
|
pClearStructPtr[u32Index] = 0;
|
|
}
|
|
|
|
|
|
/* Initialize the LPUART instance */
|
|
LPUART_Uart_Init(pBase);
|
|
|
|
/* Check if osr is between 4x and 7x oversampling.
|
|
* If so, then "BOTHEDGE" sampling must be turned on */
|
|
if (pUserConfig->u8BaudOverSamplingRatio < 8U)
|
|
{
|
|
LPUART_Uart_EnableBothEdgeSamplingCmd(pBase);
|
|
}
|
|
|
|
/* Program the osr value (bit value is one less than actual value) */
|
|
LPUART_Uart_SetOversamplingRatio(pBase, (uint32)(pUserConfig->u8BaudOverSamplingRatio - 1U));
|
|
|
|
/* Write the sbr value to the BAUD registers */
|
|
LPUART_Uart_SetBaudRateDivisor(pBase, pUserConfig->u32BaudRateDivisor);
|
|
|
|
if (pUserConfig->eParityMode != LPUART_UART_IP_PARITY_DISABLED)
|
|
{
|
|
LPUART_Uart_SetBitCountPerChar(pBase, pUserConfig->eBitCountPerChar, TRUE);
|
|
}
|
|
else
|
|
{
|
|
LPUART_Uart_SetBitCountPerChar(pBase, pUserConfig->eBitCountPerChar, FALSE);
|
|
}
|
|
LPUART_Uart_SetParityMode(pBase, pUserConfig->eParityMode);
|
|
LPUART_Uart_SetStopBitCount(pBase, pUserConfig->eStopBitsCount);
|
|
|
|
/* Initialize last driver operation status */
|
|
pUartStatePtr->eTransmitStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
pUartStatePtr->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
/* Set the initial baudrate from user's structure */
|
|
pUartStatePtr->u32BaudRate = pUserConfig->u32BaudRate;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_Deinit
|
|
* Description : This function shuts down the UART by disabling interrupts and
|
|
* transmitter/receiver.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_Deinit_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_Deinit_Activity*/
|
|
void Lpuart_Uart_Ip_Deinit(uint32 u32Instance)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
uint32 u32StartTime;
|
|
LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
|
|
/* Check if current instance is already de-initialized or is gated.*/
|
|
LPUART_UART_DEV_ASSERT(Lpuart_Uart_Ip_apStateStructuresArray[u32Instance] != NULL_PTR);
|
|
|
|
u32StartTime = OsIf_GetCounter(LPUART_UART_IP_TIMEOUT_TYPE);
|
|
/* Wait until the data is completely shifted out of shift register */
|
|
while (!LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_COMPLETE) && \
|
|
!LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
|
|
{}
|
|
/* Disble Tx data register empty and transmission complete interrupt */
|
|
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE, FALSE);
|
|
|
|
/* Disble Rx data register full */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL, FALSE);
|
|
|
|
/* Disable error interrupts */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, FALSE);
|
|
|
|
/* Clear our saved pointer to the state structure */
|
|
Lpuart_Uart_Ip_apStateStructuresArray[u32Instance] = NULL_PTR;
|
|
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_SyncSend
|
|
* Description : Send out multiple bytes of data using polling method.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_SyncSend_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_SyncSend_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SyncSend(uint32 u32Instance,
|
|
const uint8 *pTxBuff,
|
|
uint32 u32TxSize)
|
|
{
|
|
/* Check the validity of the parameters */
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
LPUART_UART_DEV_ASSERT(pTxBuff != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(u32TxSize > 0U);
|
|
|
|
LPUART_Type * pBase;
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
uint32 u32StartTime;
|
|
boolean bIsReturn = FALSE;
|
|
Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
|
|
|
|
SchM_Enter_Uart_UART_EXCLUSIVE_AREA_00();
|
|
/* Check driver is not busy transmitting data from a previous asynchronous call */
|
|
if (pUartState->bIsTxBusy)
|
|
{
|
|
SchM_Exit_Uart_UART_EXCLUSIVE_AREA_00();
|
|
retVal = LPUART_UART_IP_STATUS_BUSY;
|
|
bIsReturn = TRUE;
|
|
}
|
|
if(!bIsReturn)
|
|
{
|
|
pUartState->bIsTxBusy = TRUE;
|
|
SchM_Exit_Uart_UART_EXCLUSIVE_AREA_00();
|
|
pUartState->pTxBuff = pTxBuff;
|
|
pUartState->u32TxSize = u32TxSize;
|
|
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_BUSY;
|
|
|
|
/* Disble Tx data register empty and transmission complete interrupt */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE, FALSE);
|
|
|
|
/* Enable the LPUART transmitter */
|
|
LPUART_Uart_SetTransmitterCmd(pBase, TRUE);
|
|
u32StartTime = OsIf_GetCounter(LPUART_UART_IP_TIMEOUT_TYPE);
|
|
|
|
while ((pUartState->u32TxSize > 0U) && \
|
|
!LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
|
|
{
|
|
Lpuart_Uart_Ip_PutData(u32Instance);
|
|
while (!LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_DATA_REG_EMPTY) && \
|
|
!LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
|
|
{}
|
|
}
|
|
|
|
/* Disable the LPUART transmitter */
|
|
LPUART_Uart_SetTransmitterCmd(pBase, FALSE);
|
|
|
|
/* Check if Timeout occur */
|
|
if(pUartState->u32TxSize > 0U)
|
|
{
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_TIMEOUT;
|
|
}else /* The transmit process is complete */
|
|
{
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
pUartState->bIsTxBusy = FALSE;
|
|
retVal = pUartState->eTransmitStatus;
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_AsyncSend
|
|
* Description : This function sends data out through the LPUART module using
|
|
* non-blocking method. The function will return immediately after calling this
|
|
* function.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_AsyncSend_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_AsyncSend_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_AsyncSend(uint32 u32Instance,
|
|
const uint8 * pTxBuff,
|
|
uint32 u32TxSize)
|
|
{
|
|
/* Check the validity of the parameters */
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
LPUART_UART_DEV_ASSERT(pTxBuff != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(u32TxSize > 0U);
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
boolean bIsReturn = FALSE;
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
|
|
|
|
SchM_Enter_Uart_UART_EXCLUSIVE_AREA_01();
|
|
/* Check it's not busy transmitting data from a previous function call */
|
|
if (pUartState->bIsTxBusy)
|
|
{
|
|
SchM_Exit_Uart_UART_EXCLUSIVE_AREA_01();
|
|
retVal = LPUART_UART_IP_STATUS_BUSY;
|
|
bIsReturn = TRUE;
|
|
}
|
|
if(!bIsReturn)
|
|
{
|
|
pUartState->bIsTxBusy = TRUE;
|
|
SchM_Exit_Uart_UART_EXCLUSIVE_AREA_01();
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT((pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS) ||
|
|
(pUartUserCfg->eTransferType == LPUART_UART_IP_USING_DMA));
|
|
if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
|
|
{
|
|
/* Start the transmission process using interrupts */
|
|
retVal = Lpuart_Uart_Ip_StartSendDataUsingInt(u32Instance, pTxBuff, u32TxSize);
|
|
}
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
else
|
|
{
|
|
/* Start the transmission process using DMA */
|
|
retVal = Lpuart_Uart_Ip_StartSendDataUsingDma(u32Instance, pTxBuff, u32TxSize);
|
|
}
|
|
#endif
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_GetTransmitStatus
|
|
* Description : This function returns whether the previous LPUART transmit has
|
|
* finished. When performing non-blocking transmit, the user can call this
|
|
* function to ascertain the state of the current transmission:
|
|
* in progress (or busy) or complete (success). In addition, if the transmission
|
|
* is still in progress, the user can obtain the number of words that have been
|
|
* currently transferred.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_GetTransmitStatus_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_GetTransmitStatus_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_GetTransmitStatus(uint32 u32Instance, uint32 * pBytesRemaining)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
const Dma_Ip_LogicChannelInfoParamType eDmaLogicChnParam = DMA_IP_CH_GET_CURRENT_ITER_COUNT;
|
|
#endif
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
|
|
|
|
if (pBytesRemaining != NULL_PTR)
|
|
{
|
|
if (pUartState->bIsTxBusy)
|
|
{
|
|
/* Fill in the bytes not transferred yet. */
|
|
if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
|
|
{
|
|
/* In interrupt-based communication, the remaining bytes are retrieved
|
|
* from the state structure
|
|
*/
|
|
*pBytesRemaining = pUartState->u32TxSize;;
|
|
}
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
else
|
|
{
|
|
/* In DMA-based communication, the remaining bytes are retrieved
|
|
* from the current DMA major loop count
|
|
*/
|
|
Dma_Ip_GetLogicChannelParam(pUartUserCfg->u8TxDMAChannel, eDmaLogicChnParam, pBytesRemaining);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
*pBytesRemaining = 0;
|
|
}
|
|
}
|
|
|
|
return pUartState->eTransmitStatus;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_AbortSendingData
|
|
* Description : This function terminates an non-blocking LPUART transmission
|
|
* early. During a non-blocking LPUART transmission, the user has the option to
|
|
* terminate the transmission early if the transmission is still in progress.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_AbortSendingData_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_AbortSendingData_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_AbortSendingData(uint32 u32Instance)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
boolean bIsReturn = FALSE;
|
|
Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
|
|
|
|
/* Check if a transfer is running. */
|
|
if (!pUartState->bIsTxBusy)
|
|
{
|
|
retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
bIsReturn = TRUE;
|
|
}
|
|
if(!bIsReturn)
|
|
{
|
|
/* Update the tx status */
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_ABORTED;
|
|
|
|
/* Stop the running transfer. */
|
|
if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
|
|
{
|
|
Lpuart_Uart_Ip_CompleteSendDataUsingInt(u32Instance);
|
|
}
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
else
|
|
{
|
|
/* Release the DMA channel */
|
|
(void)Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8TxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
Lpuart_Uart_Ip_CompleteSendUsingDma(u32Instance);
|
|
}
|
|
#endif
|
|
/* Flush the Tx Buffer */
|
|
LPUART_Uart_FlushTxBuffer(pBase);
|
|
retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_SyncReceive
|
|
* Description : Receive multiple bytes of data using polling method.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_SyncReceive_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_SyncReceive_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SyncReceive(uint32 u32Instance,
|
|
uint8 *pRxBuff,
|
|
uint32 u32RxSize)
|
|
{
|
|
/* Check the validity of the parameters */
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
LPUART_UART_DEV_ASSERT(pRxBuff != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(u32RxSize > 0U);
|
|
|
|
LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
uint32 u32StartTime;
|
|
uint32 u32ElapsedTime;
|
|
uint32 u32TimeoutTicks;
|
|
boolean bIsReturn = FALSE;
|
|
Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
|
|
|
|
SchM_Enter_Uart_UART_EXCLUSIVE_AREA_02();
|
|
/* Check driver is not busy receiving data from a previous asynchronous call */
|
|
if (pUartState->bIsRxBusy)
|
|
{
|
|
SchM_Exit_Uart_UART_EXCLUSIVE_AREA_02();
|
|
retVal = LPUART_UART_IP_STATUS_BUSY;
|
|
bIsReturn = TRUE;
|
|
}
|
|
if(!bIsReturn)
|
|
{
|
|
pUartState->bIsRxBusy = TRUE;
|
|
SchM_Exit_Uart_UART_EXCLUSIVE_AREA_02();
|
|
pUartState->pRxBuff = pRxBuff;
|
|
pUartState->u32RxSize = u32RxSize;
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_BUSY;
|
|
|
|
/* Disble Rx data register full */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL, FALSE);
|
|
/* Enable the LPUART receiver */
|
|
LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, TRUE);
|
|
|
|
u32StartTime = OsIf_GetCounter(LPUART_UART_IP_TIMEOUT_TYPE);
|
|
|
|
Lpuart_Uart_Ip_StartGetData(pBase, u32Instance, u32StartTime);
|
|
|
|
u32ElapsedTime = OsIf_GetElapsed(&u32StartTime, LPUART_UART_IP_TIMEOUT_TYPE);
|
|
u32TimeoutTicks = OsIf_MicrosToTicks((uint32)LPUART_UART_IP_TIMEOUT_VALUE_US, LPUART_UART_IP_TIMEOUT_TYPE);
|
|
|
|
/* Check if Timeout occur */
|
|
if (u32ElapsedTime >= u32TimeoutTicks)
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_TIMEOUT;
|
|
}
|
|
|
|
/* Check other success receiving case*/
|
|
if (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_BUSY)
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
|
|
if ((pUartState->u32RxSize == 0U) && (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_RX_OVERRUN))
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
|
|
/* Disable the LPUART receiver */
|
|
LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
|
|
|
|
pUartState->bIsRxBusy = FALSE;
|
|
|
|
/* Read dummy to clear RDRF flag */
|
|
(void)LPUART_Uart_Getchar(pBase);
|
|
|
|
retVal = pUartState->eReceiveStatus;
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_StartGetData
|
|
* Description : Start Getting Data in SyncReceive mode
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_StartGetData(LPUART_Type * pBase, uint32 u32Instance, uint32 u32StartTime)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
while ((pUartState->u32RxSize > 0U) && \
|
|
!LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
|
|
{
|
|
/* Wait until data reception flag is set or timeout occurs if there is an error during reception */
|
|
while (!LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_DATA_REG_FULL) && \
|
|
!LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
|
|
{}
|
|
|
|
/* Check for errors on received data */
|
|
if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_RX_OVERRUN))
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_RX_OVERRUN;
|
|
/* Disable the LPUART receiver */
|
|
LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
|
|
/* Clear the flag */
|
|
LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_RX_OVERRUN);
|
|
break;
|
|
}
|
|
else if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_FRAME_ERR))
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_FRAMING_ERROR;
|
|
/* Disable the LPUART receiver */
|
|
LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
|
|
/* Clear the flag */
|
|
LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_FRAME_ERR);
|
|
break;
|
|
}
|
|
else if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_NOISE_DETECT))
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_NOISE_ERROR;
|
|
/* Disable the LPUART receiver */
|
|
LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
|
|
/* Clear the flag */
|
|
LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_NOISE_DETECT);
|
|
break;
|
|
}
|
|
else if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_PARITY_ERR))
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_PARITY_ERROR;
|
|
/* Disable the LPUART receiver */
|
|
LPUART_Uart_SetReceiverCmd((LPUART_Type *)pBase, FALSE);
|
|
/* Clear the flag */
|
|
LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_PARITY_ERR);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
/* Get received data */
|
|
Lpuart_Uart_Ip_GetData(u32Instance);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_ReceiveData
|
|
* Description : This function receives data from LPUART module using
|
|
* non-blocking method. This function returns immediately after initiating the
|
|
* receive function. The application has to get the receive status to see when
|
|
* the receive is complete. In other words, after calling non-blocking get
|
|
* function, the application must get the receive status to check if receive
|
|
* is completed or not.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_ReceiveData_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_AsyncReceive_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_AsyncReceive(uint32 u32Instance,
|
|
uint8 * pRxBuff,
|
|
uint32 u32RxSize)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
LPUART_UART_DEV_ASSERT(pRxBuff != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(u32RxSize > 0U);
|
|
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
boolean bIsReturn = FALSE;
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
|
|
|
|
SchM_Enter_Uart_UART_EXCLUSIVE_AREA_03();
|
|
/* Check it's not busy receiving data from a previous function call */
|
|
if (pUartState->bIsRxBusy)
|
|
{
|
|
SchM_Exit_Uart_UART_EXCLUSIVE_AREA_03();
|
|
retVal = LPUART_UART_IP_STATUS_BUSY;
|
|
bIsReturn = TRUE;
|
|
}
|
|
if(!bIsReturn)
|
|
{
|
|
pUartState->bIsRxBusy = TRUE;
|
|
SchM_Exit_Uart_UART_EXCLUSIVE_AREA_03();
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT((pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS) ||
|
|
(pUartUserCfg->eTransferType == LPUART_UART_IP_USING_DMA));
|
|
|
|
if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
|
|
{
|
|
/* Start the reception process using interrupts */
|
|
retVal = Lpuart_Uart_Ip_StartReceiveDataUsingInt(u32Instance, pRxBuff, u32RxSize);
|
|
}
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
else
|
|
{
|
|
/* Start the reception process using DMA */
|
|
retVal = Lpuart_Uart_Ip_StartReceiveDataUsingDma(u32Instance, pRxBuff, u32RxSize);
|
|
}
|
|
#endif
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_GetReceiveStatus
|
|
* Description : This function returns whether the previous LPUART receive is
|
|
* complete. When performing a non-blocking receive, the user can call this
|
|
* function to ascertain the state of the current receive progress: in progress
|
|
* or complete. In addition, if the receive is still in progress, the user can
|
|
* obtain the number of words that have been currently received.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_GetReceiveStatus_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_GetReceiveStatus_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_GetReceiveStatus(uint32 u32Instance, uint32 * pBytesRemaining)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
const Dma_Ip_LogicChannelInfoParamType eDmaLogicChnParam = DMA_IP_CH_GET_CURRENT_ITER_COUNT;
|
|
#endif
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
|
|
|
|
if (pBytesRemaining != NULL_PTR)
|
|
{
|
|
if (pUartState->bIsRxBusy)
|
|
{
|
|
/* Fill in the bytes transferred. */
|
|
if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
|
|
{
|
|
/* In interrupt-based communication, the remaining bytes are retrieved
|
|
* from the state structure
|
|
*/
|
|
*pBytesRemaining = pUartState->u32RxSize;
|
|
}
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
else
|
|
{
|
|
/* In DMA-based communication, the remaining bytes are retrieved
|
|
* from the current DMA major loop count
|
|
*/
|
|
Dma_Ip_GetLogicChannelParam(pUartUserCfg->u8RxDMAChannel, eDmaLogicChnParam, pBytesRemaining);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
*pBytesRemaining = 0;
|
|
}
|
|
}
|
|
|
|
return pUartState->eReceiveStatus;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_AbortReceivingData
|
|
* Description : Terminates a non-blocking receive early.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_AbortReceivingData_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_AbortReceivingData_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_AbortReceivingData(uint32 u32Instance)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
LPUART_UART_DEV_ASSERT(pUartState != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(pUartUserCfg != NULL_PTR);
|
|
boolean bIsReturn = FALSE;
|
|
Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_ERROR;
|
|
|
|
/* Check if a transfer is running. */
|
|
if (!pUartState->bIsRxBusy)
|
|
{
|
|
retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
bIsReturn = TRUE;
|
|
}
|
|
|
|
if(!bIsReturn)
|
|
{
|
|
/* Update the rx status */
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_ABORTED;
|
|
|
|
/* Stop the running transfer. */
|
|
if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
|
|
{
|
|
Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(u32Instance);
|
|
}
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
else
|
|
{
|
|
/* Release the DMA channel */
|
|
(void)Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
Lpuart_Uart_Ip_CompleteReceiveUsingDma(u32Instance);
|
|
}
|
|
#endif
|
|
/* Clear all the error flags */
|
|
LPUART_Uart_ClearErrorFlags(pBase);
|
|
/* Flush the Rx Buffer */
|
|
LPUART_Uart_FlushRxBuffer(pBase);
|
|
retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_SetBaudRate
|
|
* Description : Configures the LPUART baud rate.
|
|
* In some LPUART instances the user must disable the transmitter/receiver
|
|
* before calling this function.
|
|
* Generally, this may be applied to all LPUARTs to ensure safe operation.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_SetBaudRate_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_SetBaudRate_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SetBaudRate(uint32 u32Instance,
|
|
Lpuart_Uart_Ip_BaudrateType u32DesiredBaudrate,
|
|
uint32 u32ClockFrequency)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
|
|
uint16 sbr, sbrTemp, i;
|
|
uint32 osr, tempDiff, calculatedBaud, baudDiff, maxOsr;
|
|
LPUART_Type * pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
boolean bIsReturn = FALSE;
|
|
Lpuart_Uart_Ip_StatusType retVal = LPUART_UART_IP_STATUS_ERROR;
|
|
|
|
if (pUartState != NULL_PTR)
|
|
{
|
|
/* Check if there is an ongoing transfer */
|
|
if (pUartState->bIsTxBusy == TRUE)
|
|
{
|
|
retVal = LPUART_UART_IP_STATUS_BUSY;
|
|
bIsReturn = TRUE;
|
|
}
|
|
if ((pUartState->bIsRxBusy == TRUE) && (bIsReturn == FALSE))
|
|
{
|
|
retVal = LPUART_UART_IP_STATUS_BUSY;
|
|
bIsReturn = TRUE;
|
|
}
|
|
}
|
|
if(!bIsReturn)
|
|
{
|
|
/* Check if current instance is clock gated off. */
|
|
LPUART_UART_DEV_ASSERT(u32ClockFrequency > 0U);
|
|
/* Check if the desired baud rate can be configured with the current protocol clock. */
|
|
LPUART_UART_DEV_ASSERT(u32ClockFrequency >= (u32DesiredBaudrate * 5U));
|
|
|
|
/* This lpuart instantiation uses a slightly different baud rate calculation
|
|
* The idea is to use the best OSR (over-sampling rate) possible
|
|
* Note, osr is typically hard-set to 16 in other lpuart instantiations
|
|
* First calculate the baud rate using the minimum OSR possible (4) */
|
|
osr = 4;
|
|
sbr = (uint16)(u32ClockFrequency / (u32DesiredBaudrate * osr));
|
|
calculatedBaud = (u32ClockFrequency / (osr * sbr));
|
|
if (calculatedBaud > u32DesiredBaudrate)
|
|
{
|
|
baudDiff = calculatedBaud - u32DesiredBaudrate;
|
|
}
|
|
else
|
|
{
|
|
baudDiff = u32DesiredBaudrate - calculatedBaud;
|
|
}
|
|
/* find maximum osr */
|
|
maxOsr = u32ClockFrequency / u32DesiredBaudrate;
|
|
if (maxOsr > 32U)
|
|
{
|
|
maxOsr = 32U;
|
|
}
|
|
/* loop to find the best osr value possible, one that generates minimum baudDiff
|
|
* iterate through the rest of the supported values of osr */
|
|
if (maxOsr >= 5U)
|
|
{
|
|
for (i = 5U; i <= maxOsr; i++)
|
|
{
|
|
/* calculate the temporary sbr value */
|
|
sbrTemp = (uint16)(u32ClockFrequency / (u32DesiredBaudrate * i));
|
|
/* calculate the baud rate based on the temporary osr and sbr values */
|
|
calculatedBaud = (u32ClockFrequency / (i * sbrTemp));
|
|
|
|
if (calculatedBaud > u32DesiredBaudrate)
|
|
{
|
|
tempDiff = calculatedBaud - u32DesiredBaudrate;
|
|
}
|
|
else
|
|
{
|
|
tempDiff = u32DesiredBaudrate - calculatedBaud;
|
|
}
|
|
|
|
if (tempDiff <= baudDiff)
|
|
{
|
|
baudDiff = tempDiff;
|
|
osr = i; /* update and store the best osr value calculated */
|
|
sbr = sbrTemp; /* update store the best sbr value calculated */
|
|
}
|
|
}
|
|
}
|
|
/* Check if osr is between 4x and 7x oversampling.
|
|
* If so, then "BOTHEDGE" sampling must be turned on */
|
|
if (osr < 8U)
|
|
{
|
|
LPUART_Uart_EnableBothEdgeSamplingCmd(pBase);
|
|
}
|
|
|
|
/* program the osr value (bit value is one less than actual value) */
|
|
LPUART_Uart_SetOversamplingRatio(pBase, (osr - 1U));
|
|
|
|
/* write the sbr value to the BAUD registers */
|
|
LPUART_Uart_SetBaudRateDivisor(pBase, sbr);
|
|
|
|
pUartState->u32BaudRate = calculatedBaud;
|
|
|
|
retVal = LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_GetBaudRate
|
|
* Description : Returns the LPUART configured baud rate.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_GetBaudRate_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_GetBaudRate_Activity*/
|
|
void Lpuart_Uart_Ip_GetBaudRate(uint32 u32Instance, uint32 * pConfiguredBaudRate)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
LPUART_UART_DEV_ASSERT(pConfiguredBaudRate != NULL_PTR);
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
|
|
|
|
*pConfiguredBaudRate = pUartState->u32BaudRate;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_SetTxBuffer
|
|
* Description : Sets the driver internal reference to the tx buffer.
|
|
* Can be called from the tx callback to provide a different
|
|
* buffer for continuous transmission.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_SetTxBuffer_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_SetTxBuffer_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SetTxBuffer(uint32 u32Instance,
|
|
const uint8 * pTxBuff,
|
|
uint32 u32TxSize)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
LPUART_UART_DEV_ASSERT(pTxBuff != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(u32TxSize > 0U);
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
|
|
pUartState->pTxBuff = pTxBuff;
|
|
pUartState->u32TxSize = u32TxSize;
|
|
|
|
return LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_SetRxBuffer
|
|
* Description : Sets the driver internal reference to the rx buffer.
|
|
* Can be called from the rx callback to provide a different
|
|
* buffer for continuous reception.
|
|
*
|
|
* Implements : Lpuart_Uart_Ip_SetRxBuffer_Activity
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_SetRxBuffer_Activity*/
|
|
Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_SetRxBuffer(uint32 u32Instance,
|
|
uint8 * pRxBuff,
|
|
uint32 u32RxSize)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
LPUART_UART_DEV_ASSERT(pRxBuff != NULL_PTR);
|
|
LPUART_UART_DEV_ASSERT(u32RxSize > 0U);
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartState->pRxBuff = pRxBuff;
|
|
pUartState->u32RxSize = u32RxSize;
|
|
|
|
return LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_IRQHandler
|
|
* Description : Interrupt handler for LPUART.
|
|
* This handler uses the buffers stored in the Lpuart_Uart_Ip_StateStructureType structs to transfer
|
|
* data. This is not a public API as it is called by IRQ whenever an interrupt
|
|
* occurs.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements Lpuart_Uart_Ip_IRQHandler_Activity*/
|
|
void Lpuart_Uart_Ip_IRQHandler(uint32 u32Instance)
|
|
{
|
|
LPUART_UART_DEV_ASSERT(u32Instance < LPUART_UART_IP_NUMBER_OF_INSTANCES);
|
|
|
|
LPUART_Type * pBase;
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
boolean bIsReturn = FALSE;
|
|
/* Case of spurious interrupt when driver is not at all initialized or it is not in transmit/receive process*/
|
|
if (pUartState == NULL_PTR)
|
|
{
|
|
/* Read dummy to clear RDRF flag if it is set*/
|
|
(void)LPUART_Uart_Getchar(pBase);
|
|
/* Clear all the error flags */
|
|
LPUART_Uart_ClearErrorFlags(pBase);
|
|
/* Transmit flags can not be cleared, return to exit */
|
|
}
|
|
else
|
|
{
|
|
Lpuart_Uart_Ip_ErrIrqHandler(u32Instance);
|
|
/* Handle receive data full interrupt */
|
|
if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_DATA_REG_FULL))
|
|
{
|
|
if (LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL))
|
|
{
|
|
Lpuart_Uart_Ip_RxIrqHandler(u32Instance);
|
|
}
|
|
/* Case of spurious interrupt when the interupt enable flag is not set and respective interrupt status flag is set */
|
|
else
|
|
{
|
|
/* Read dummy to clear RDRF flag */
|
|
(void)LPUART_Uart_Getchar(pBase);
|
|
}
|
|
bIsReturn = TRUE;
|
|
}
|
|
/* Handle transmitter data register empty interrupt */
|
|
if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_DATA_REG_EMPTY) && (bIsReturn == FALSE))
|
|
{
|
|
if (LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY))
|
|
{
|
|
Lpuart_Uart_Ip_TxEmptyIrqHandler(u32Instance);
|
|
bIsReturn = TRUE;
|
|
}
|
|
/* Case of spurious interrupt when the interupt enable flag is not set and respective interrupt status flag is set */
|
|
else
|
|
{
|
|
/* Do nothing, because TDRE can not clear without affecting to normal operation*/
|
|
}
|
|
}
|
|
/* Handle transmission complete interrupt */
|
|
if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_COMPLETE) && (bIsReturn == FALSE))
|
|
{
|
|
if (LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE))
|
|
{
|
|
Lpuart_Uart_Ip_TxCompleteIrqHandler(u32Instance);
|
|
}
|
|
/* Case of spurious interrupt when the interupt enable flag is not set and respective interrupt status flag is set */
|
|
else
|
|
{
|
|
/* Do nothing, because TC can not clear without affecting to normal operation*/
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_RxIrqHandler
|
|
* Description : Rx Interrupt handler for LPUART.
|
|
* This function treats the rx full interrupt.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_RxIrqHandler(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
/* Get data and put in receive buffer */
|
|
Lpuart_Uart_Ip_GetData(u32Instance);
|
|
|
|
/* Check if this was the last byte in the current buffer */
|
|
if (pUartState->u32RxSize == 0U)
|
|
{
|
|
/* Invoke callback if there is one (callback may reset the rx buffer for continuous reception) */
|
|
if (pUartUserCfg->pfRxCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfRxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_RX_FULL, pUartUserCfg->pRxCallbackParam);
|
|
}
|
|
}
|
|
|
|
/* Finish reception if this was the last byte received */
|
|
if (pUartState->u32RxSize == 0U)
|
|
{
|
|
/* Complete transfer (disable rx logic) */
|
|
Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(u32Instance);
|
|
|
|
/* Invoke callback if there is one */
|
|
if (pUartUserCfg->pfRxCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfRxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_END_TRANSFER, pUartUserCfg->pRxCallbackParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_TxEmptyIrqHandler
|
|
* Description : Tx Empty Interrupt handler for LPUART.
|
|
* This function treats the tx empty interrupt.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_TxEmptyIrqHandler(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
/* Check if there are any more bytes to send */
|
|
if (pUartState->u32TxSize > 0U)
|
|
{
|
|
/* Transmit the data */
|
|
Lpuart_Uart_Ip_PutData(u32Instance);
|
|
|
|
/* Check if this was the last byte in the current buffer */
|
|
if ((pUartState->u32TxSize == 0U) && (pUartUserCfg->pfTxCallback != NULL_PTR))
|
|
{
|
|
/* Invoke callback if there is one (callback may reset the tx buffer for continuous transmission)*/
|
|
pUartUserCfg->pfTxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_TX_EMPTY, pUartUserCfg->pTxCallbackParam);
|
|
}
|
|
/* If there's no new data, disable tx empty interrupt and enable transmission complete interrupt */
|
|
if (pUartState->u32TxSize == 0U)
|
|
{
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_TxCompleteIrqHandler
|
|
* Description : Tx Complete Interrupt handler for LPUART.
|
|
* This function treats the tx complete interrupt.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_TxCompleteIrqHandler(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
if (pUartState->u32TxSize == 0U)
|
|
{
|
|
if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
|
|
{
|
|
/* Complete the interrupt based transfer */
|
|
Lpuart_Uart_Ip_CompleteSendDataUsingInt(u32Instance);
|
|
}
|
|
/* Invoke callback if there is one */
|
|
if (pUartUserCfg->pfTxCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfTxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_END_TRANSFER, pUartUserCfg->pTxCallbackParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_ErrIrqHandler
|
|
* Description : Error Interrupt handler for LPUART.
|
|
* This function treats the error interrupts.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_ErrIrqHandler(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase;
|
|
boolean bIsError = FALSE;
|
|
boolean bIsReturn = FALSE;
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
/* Handle receive overrun interrupt */
|
|
if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_RX_OVERRUN))
|
|
{
|
|
/* Clear the flag */
|
|
LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_RX_OVERRUN);
|
|
/* Case of spurious interrupt when interrupt enable bit is not set*/
|
|
if (!LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN))
|
|
{
|
|
bIsReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* Update the status */
|
|
bIsError = TRUE;
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_RX_OVERRUN;
|
|
}
|
|
}
|
|
/* Handle framing error interrupt */
|
|
if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_FRAME_ERR) && (bIsReturn == FALSE))
|
|
{
|
|
/* Clear the flag */
|
|
LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_FRAME_ERR);
|
|
/* Case of spurious interrupt when interrupt enable bit is not set*/
|
|
if (!LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG))
|
|
{
|
|
bIsReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* Update the status */
|
|
bIsError = TRUE;
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_FRAMING_ERROR;
|
|
}
|
|
}
|
|
/* Handle parity error interrupt */
|
|
if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_PARITY_ERR) && (bIsReturn == FALSE))
|
|
{
|
|
/* Clear the flag */
|
|
LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_PARITY_ERR);
|
|
/* Case of spurious interrupt when interrupt enable bit is not set*/
|
|
if (!LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG))
|
|
{
|
|
bIsReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* Update the status */
|
|
bIsError = TRUE;
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_PARITY_ERROR;
|
|
}
|
|
}
|
|
/* Handle noise error interrupt */
|
|
if (LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_NOISE_DETECT) && (bIsReturn == FALSE))
|
|
{
|
|
/* Clear the flag */
|
|
LPUART_Uart_ClearStatusFlag(pBase, LPUART_UART_IP_NOISE_DETECT);
|
|
/* Case of spurious interrupt when interrupt enable bit is not set*/
|
|
if (!LPUART_Uart_GetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG))
|
|
{
|
|
bIsReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* Update the internal status */
|
|
bIsError = TRUE;
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_NOISE_ERROR;
|
|
}
|
|
}
|
|
if(bIsReturn == FALSE)
|
|
{
|
|
if (bIsError == TRUE)
|
|
{
|
|
if (pUartUserCfg->eTransferType == LPUART_UART_IP_USING_INTERRUPTS)
|
|
{
|
|
/* Complete the transfer (disable rx logic) */
|
|
Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(u32Instance);
|
|
}
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
else
|
|
{
|
|
/* Complete the transfer (stop DMA channel) */
|
|
(void)Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
Lpuart_Uart_Ip_CompleteReceiveUsingDma(u32Instance);
|
|
}
|
|
#endif
|
|
/* Invoke callback if there is one */
|
|
if (pUartUserCfg->pfErrorCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfErrorCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_ERROR, pUartUserCfg->pErrorCallbackParam);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_StartSendDataUsingInt
|
|
* Description : Initiate (start) a transmit by beginning the process of
|
|
* sending data and enabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartSendDataUsingInt(uint32 u32Instance,
|
|
const uint8 * pTxBuff,
|
|
uint32 u32TxSize)
|
|
{
|
|
LPUART_Type * pBase;
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
|
|
/* initialize the module driver state structure */
|
|
pUartState->pTxBuff = pTxBuff;
|
|
pUartState->u32TxSize = u32TxSize;
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_BUSY;
|
|
|
|
/* Enable the LPUART transmitter */
|
|
LPUART_Uart_SetTransmitterCmd(pBase, TRUE);
|
|
|
|
/* Enable tx empty interrupt */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, TRUE);
|
|
|
|
return LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_StartSendDataUsingDma
|
|
* Description : Initiate (start) a transmit by beginning the process of
|
|
* sending data using DMA transfers.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartSendDataUsingDma(uint32 u32Instance,
|
|
const uint8 * pTxBuff,
|
|
uint32 u32TxSize)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase;
|
|
Dma_Ip_LogicChannelTransferListType dmaTransferList[LPUART_UART_DMA_CONFIG_LIST_DIMENSION];
|
|
Dma_Ip_ReturnType eDmaReturnStatus;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
/* Set up parameters for Dma_Ip_LogicChannelTransferListType */
|
|
dmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
|
|
dmaTransferList[0].Value = (uint32)pTxBuff;
|
|
dmaTransferList[1].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
|
|
dmaTransferList[1].Value = LPUART_UART_IP_LSBW_ADDR(pBase->DATA);
|
|
dmaTransferList[2].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
|
|
dmaTransferList[2].Value = 1;
|
|
dmaTransferList[3].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
|
|
dmaTransferList[3].Value = 0;
|
|
dmaTransferList[4].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
|
|
dmaTransferList[4].Value = u32TxSize;
|
|
dmaTransferList[5].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
|
|
dmaTransferList[5].Value = 1;
|
|
dmaTransferList[6].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
|
|
dmaTransferList[6].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
dmaTransferList[7].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
|
|
dmaTransferList[7].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
dmaTransferList[8].Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT;
|
|
dmaTransferList[8].Value = 1;
|
|
dmaTransferList[9].Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST;
|
|
dmaTransferList[9].Value = 1;
|
|
|
|
/* Update state structure */
|
|
pUartState->pTxBuff = pTxBuff;
|
|
pUartState->u32TxSize = 0U;
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_BUSY;
|
|
|
|
/* Configure the transfer control descriptor for the DMA channel */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(pUartUserCfg->u8TxDMAChannel, dmaTransferList, LPUART_UART_DMA_CONFIG_LIST_DIMENSION);
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
|
|
/* Start the DMA channel */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8TxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
/* Enable the LPUART transmitter */
|
|
LPUART_Uart_SetTransmitterCmd(pBase, TRUE);
|
|
|
|
/* Enable tx DMA requests for the current instance */
|
|
LPUART_Uart_SetTxDmaCmd(pBase, TRUE);
|
|
|
|
return LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_CompleteSendDataUsingInt
|
|
* Description : Finish up a transmit by completing the process of sending
|
|
* data and disabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_CompleteSendDataUsingInt(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
LPUART_Type * pBase;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
|
|
if (pUartState->eTransmitStatus == LPUART_UART_IP_STATUS_BUSY)
|
|
{
|
|
/* If the transfer is completed, update the transmit status */
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
/* If the transfer is aborted or timed out, disable tx empty interrupt */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_DATA_REG_EMPTY, FALSE);
|
|
}
|
|
|
|
/* Disable transmission complete interrupt */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_TX_COMPLETE, FALSE);
|
|
|
|
/* Disable transmitter */
|
|
LPUART_Uart_SetTransmitterCmd(pBase, FALSE);
|
|
|
|
/* Update the internal busy flag */
|
|
pUartState->bIsTxBusy = FALSE;
|
|
}
|
|
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_CompleteSendUsingDma
|
|
* Description : Finish up a transmit by completing the process of sending
|
|
* data and disabling the DMA requests. This is a callback for DMA major loop
|
|
* completion, so it must match the DMA callback signature.
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpuart_Uart_Ip_CompleteSendUsingDma(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase;
|
|
Dma_Ip_LogicChannelTransferListType dmaTransferList[LPUART_UART_DMA_CONFIG_LIST_DIMENSION];
|
|
Dma_Ip_ReturnType eDmaReturnStatus;
|
|
Dma_Ip_LogicChannelStatusType dmaStatus;
|
|
uint32 u32StartTime;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
/* Get Dma Ip Logic Channel Status */
|
|
(void)Dma_Ip_GetLogicChannelStatus(pUartUserCfg->u8TxDMAChannel, &dmaStatus);
|
|
if (dmaStatus.ChStateValue == DMA_IP_CH_ERROR_STATE)
|
|
{
|
|
/* Reset the Dma Channel Error status. */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8TxDMAChannel, DMA_IP_CH_CLEAR_ERROR);
|
|
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
/* Update transmit status */
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_ERROR;
|
|
/* Invoke callback if there is one */
|
|
if (pUartUserCfg->pfErrorCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfErrorCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_ERROR, pUartUserCfg->pErrorCallbackParam);
|
|
}
|
|
}
|
|
|
|
/* Invoke the callback when the buffer is finished;
|
|
* Application can provide another buffer inside the callback by calling Lpuart_Uart_Ip_SetTxBuffer */
|
|
if (pUartState->eTransmitStatus == LPUART_UART_IP_STATUS_BUSY)
|
|
{
|
|
/* Invoke callback if there is one (callback may reset the tx buffer for continuous transmission)*/
|
|
if (pUartUserCfg->pfTxCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfTxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_TX_EMPTY, pUartUserCfg->pTxCallbackParam);
|
|
}
|
|
}
|
|
|
|
/* If the callback has updated the tx buffer, update the DMA descriptor to continue the transfer;
|
|
* otherwise, stop the current transfer.
|
|
*/
|
|
if ((pUartState->u32TxSize > 0U) && (pUartState->eTransmitStatus != LPUART_UART_IP_STATUS_ERROR))
|
|
{
|
|
/* Set up parameters for Dma_Ip_LogicChannelTransferListType */
|
|
dmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
|
|
dmaTransferList[0].Value = (uint32)(pUartState->pTxBuff);
|
|
/* Update tx size and major loop count parameters for Dma_Ip_LogicChannelTransferListType */
|
|
dmaTransferList[1].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
|
|
dmaTransferList[1].Value = pUartState->u32TxSize;
|
|
|
|
/* Re-configure the transfer control descriptor for the DMA channel */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(pUartUserCfg->u8TxDMAChannel, dmaTransferList, LPUART_UART_DMA_LEAST_CONFIG_LIST_DIMENSION);
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
|
|
/* Now that this tx is set up, clear remaining bytes count */
|
|
pUartState->u32TxSize = 0U;
|
|
|
|
/* Re-start the channel */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8TxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
/* In Abort case, the transmission need to stop instantly */
|
|
if (pUartState->eTransmitStatus != LPUART_UART_IP_STATUS_ABORTED)
|
|
{
|
|
/* Wait until the last transmission complete */
|
|
u32StartTime = OsIf_GetCounter(LPUART_UART_IP_TIMEOUT_TYPE);
|
|
while (!LPUART_Uart_GetStatusFlag(pBase, LPUART_UART_IP_TX_COMPLETE) && \
|
|
!LPUART_Uart_CheckTimeout(u32StartTime, (uint32)LPUART_UART_IP_TIMEOUT_VALUE_US))
|
|
{}
|
|
}
|
|
/* Disable tx DMA requests for the current instance */
|
|
LPUART_Uart_SetTxDmaCmd(pBase, FALSE);
|
|
|
|
/* Disable the transmitter */
|
|
LPUART_Uart_SetTransmitterCmd(pBase, FALSE);
|
|
|
|
/* Update the busy flag */
|
|
pUartState->bIsTxBusy = FALSE;
|
|
|
|
/* If the current reception hasn't been aborted, update the status */
|
|
if (pUartState->eTransmitStatus == LPUART_UART_IP_STATUS_BUSY)
|
|
{
|
|
pUartState->eTransmitStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
/* Invoke callback if there is one */
|
|
if (pUartUserCfg->pfTxCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfTxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_END_TRANSFER, pUartUserCfg->pTxCallbackParam);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_StartReceiveDataUsingInt
|
|
* Description : Initiate (start) a receive by beginning the process of
|
|
* receiving data and enabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartReceiveDataUsingInt(uint32 u32Instance,
|
|
uint8 * pRxBuff,
|
|
uint32 u32RxSize)
|
|
{
|
|
LPUART_Type * pBase;
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
|
|
/* Initialize the module driver state struct to indicate transfer in progress
|
|
* and with the buffer and byte count data. */
|
|
pUartState->bIsRxBusy = TRUE;
|
|
pUartState->pRxBuff = pRxBuff;
|
|
pUartState->u32RxSize = u32RxSize;
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_BUSY;
|
|
|
|
/* Clear all the error flags */
|
|
LPUART_Uart_ClearErrorFlags(pBase);
|
|
/* Flush the Tx Buffer */
|
|
LPUART_Uart_FlushRxBuffer(pBase);
|
|
|
|
/* Enable the receiver */
|
|
LPUART_Uart_SetReceiverCmd(pBase, TRUE);
|
|
|
|
/* Enable error interrupts */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, TRUE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, TRUE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, TRUE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, TRUE);
|
|
|
|
/* Enable receive data full interrupt */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL, TRUE);
|
|
|
|
return LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_StartReceiveDataUsingDma
|
|
* Description : Initiate (start) a receive by beginning the process of
|
|
* receiving data using DMA transfers.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Lpuart_Uart_Ip_StatusType Lpuart_Uart_Ip_StartReceiveDataUsingDma(uint32 u32Instance,
|
|
uint8 * pRxBuff,
|
|
uint32 u32RxSize)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase;
|
|
Dma_Ip_LogicChannelTransferListType dmaTransferList[LPUART_UART_DMA_CONFIG_LIST_DIMENSION];
|
|
Dma_Ip_ReturnType eDmaReturnStatus;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
/* Clear all the error flags */
|
|
LPUART_Uart_ClearErrorFlags(pBase);
|
|
/* Flush the Tx Buffer */
|
|
LPUART_Uart_FlushRxBuffer(pBase);
|
|
|
|
/* Set up parameters for Dma_Ip_LogicChannelTransferListType */
|
|
dmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
|
|
dmaTransferList[0].Value = LPUART_UART_IP_LSBW_ADDR(pBase->DATA);
|
|
dmaTransferList[1].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
|
|
dmaTransferList[1].Value = (uint32)pRxBuff;
|
|
dmaTransferList[2].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
|
|
dmaTransferList[2].Value = 0;
|
|
dmaTransferList[3].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
|
|
dmaTransferList[3].Value = 1;
|
|
dmaTransferList[4].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
|
|
dmaTransferList[4].Value = u32RxSize;
|
|
dmaTransferList[5].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
|
|
dmaTransferList[5].Value = 1;
|
|
dmaTransferList[6].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
|
|
dmaTransferList[6].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
dmaTransferList[7].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
|
|
dmaTransferList[7].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
|
|
dmaTransferList[8].Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT;
|
|
dmaTransferList[8].Value = 1;
|
|
dmaTransferList[9].Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST;
|
|
dmaTransferList[9].Value = 1;
|
|
|
|
/* Update the state structure */
|
|
pUartState->pRxBuff = pRxBuff;
|
|
pUartState->u32RxSize = 0U;
|
|
pUartState->bIsRxBusy = TRUE;
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_BUSY;
|
|
|
|
/* Configure the transfer control descriptor for the DMA channel */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(pUartUserCfg->u8RxDMAChannel, dmaTransferList, LPUART_UART_DMA_CONFIG_LIST_DIMENSION);
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
|
|
/* Start the DMA channel */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
|
|
/* Enable the receiver */
|
|
LPUART_Uart_SetReceiverCmd(pBase, TRUE);
|
|
|
|
/* Enable error interrupts */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, TRUE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, TRUE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, TRUE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, TRUE);
|
|
|
|
/* Enable rx DMA requests for the current instance */
|
|
LPUART_Uart_SetRxDmaCmd(pBase, TRUE);
|
|
|
|
return LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_CompleteReceiveDataUsingInt
|
|
* Description : Finish up a receive by completing the process of receiving data
|
|
* and disabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(uint32 u32Instance)
|
|
{
|
|
LPUART_Type * pBase;
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
|
|
/* Disable receiver */
|
|
LPUART_Uart_SetReceiverCmd(pBase, FALSE);
|
|
|
|
/* Disable all error interrupts */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, FALSE);
|
|
|
|
/* Disable receive data full and rx overrun interrupt. */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_DATA_REG_FULL, FALSE);
|
|
|
|
/* Read dummy to clear RDRF flag */
|
|
(void)LPUART_Uart_Getchar(pBase);
|
|
|
|
/* Update the information of the module driver state */
|
|
pUartState->bIsRxBusy = FALSE;
|
|
if (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_BUSY)
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
|
|
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_CompleteReceiveUsingDma
|
|
* Description : Finish up a receive by completing the process of receiving data
|
|
* and disabling the DMA requests. This is a callback for DMA major loop
|
|
* completion, so it must match the DMA callback signature.
|
|
*
|
|
*END**************************************************************************/
|
|
void Lpuart_Uart_Ip_CompleteReceiveUsingDma(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase;
|
|
Dma_Ip_LogicChannelTransferListType dmaTransferList[LPUART_UART_DMA_CONFIG_LIST_DIMENSION];
|
|
Dma_Ip_ReturnType eDmaReturnStatus;
|
|
Dma_Ip_LogicChannelStatusType dmaStatus;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
/* Get Dma Ip Logic Channel Status */
|
|
(void)Dma_Ip_GetLogicChannelStatus(pUartUserCfg->u8RxDMAChannel, &dmaStatus);
|
|
|
|
if (dmaStatus.ChStateValue == DMA_IP_CH_ERROR_STATE)
|
|
{
|
|
/* Reset the Dma Channel Error status. */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_CLEAR_ERROR);
|
|
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
/* Update transmit status */
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_ERROR;
|
|
/* Invoke callback if there is one */
|
|
if (pUartUserCfg->pfErrorCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfErrorCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_ERROR, pUartUserCfg->pErrorCallbackParam);
|
|
}
|
|
}
|
|
|
|
/* Invoke the callback when the buffer is finished */
|
|
if (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_BUSY)
|
|
{
|
|
/* Application can provide another buffer inside the callback by calling Lpuart_Uart_Ip_SetRxBuffer */
|
|
if (pUartUserCfg->pfRxCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfRxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_RX_FULL, pUartUserCfg->pRxCallbackParam);
|
|
}
|
|
}
|
|
|
|
/* If the callback has updated the rx buffer, update the DMA descriptor to continue the transfer;
|
|
* otherwise, stop the current transfer.
|
|
*/
|
|
if ((pUartState->u32RxSize > 0U) && (pUartState->eReceiveStatus != LPUART_UART_IP_STATUS_ERROR))
|
|
{
|
|
/* Set up parameters for Dma_Ip_LogicChannelTransferListType */
|
|
dmaTransferList[0].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
|
|
dmaTransferList[0].Value = (uint32)(pUartState->pRxBuff);
|
|
dmaTransferList[1].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
|
|
dmaTransferList[1].Value = pUartState->u32RxSize;
|
|
|
|
/* Re-configure the transfer control descriptor for the DMA channel */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(pUartUserCfg->u8RxDMAChannel, dmaTransferList, LPUART_UART_DMA_LEAST_CONFIG_LIST_DIMENSION);
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
|
|
/* Now that this rx is set up, clear remaining bytes count */
|
|
pUartState->u32RxSize = 0U;
|
|
|
|
/* Re-start the channel */
|
|
eDmaReturnStatus = Dma_Ip_SetLogicChannelCommand(pUartUserCfg->u8RxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
LPUART_UART_DEV_ASSERT(eDmaReturnStatus == DMA_IP_STATUS_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
/* Disable receiver */
|
|
LPUART_Uart_SetReceiverCmd(pBase, FALSE);
|
|
|
|
/* Disable error interrupts */
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_RX_OVERRUN, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_PARITY_ERR_FLAG, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_NOISE_ERR_FLAG, FALSE);
|
|
LPUART_Uart_SetIntMode(pBase, LPUART_UART_IP_INT_FRAME_ERR_FLAG, FALSE);
|
|
|
|
/* Disable rx DMA requests for the current instance */
|
|
LPUART_Uart_SetRxDmaCmd(pBase, FALSE);
|
|
|
|
/* Read dummy to clear RDRF flag */
|
|
(void)LPUART_Uart_Getchar(pBase);
|
|
|
|
/* Update the information of the module driver state */
|
|
pUartState->bIsRxBusy = FALSE;
|
|
|
|
/* If the current reception hasn't been aborted, update the status and call the callback */
|
|
if (pUartState->eReceiveStatus == LPUART_UART_IP_STATUS_BUSY)
|
|
{
|
|
pUartState->eReceiveStatus = LPUART_UART_IP_STATUS_SUCCESS;
|
|
|
|
/* Call the callback to notify application that the transfer is complete */
|
|
if (pUartUserCfg->pfRxCallback != NULL_PTR)
|
|
{
|
|
pUartUserCfg->pfRxCallback(u32Instance, pUartState, LPUART_UART_IP_EVENT_END_TRANSFER, pUartUserCfg->pRxCallbackParam);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_PutData
|
|
* Description : Write data to the buffer register, according to configured
|
|
* word length.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_PutData(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase;
|
|
uint16 u16Data;
|
|
uint8 u8Data;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
if ((LPUART_UART_IP_7_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar) || (LPUART_UART_IP_8_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar))
|
|
{
|
|
u8Data = *(pUartState->pTxBuff);
|
|
/* Update the state structure */
|
|
++pUartState->pTxBuff;
|
|
--pUartState->u32TxSize;
|
|
/* Transmit the data */
|
|
LPUART_Uart_Putchar(pBase, u8Data);
|
|
}
|
|
else
|
|
{
|
|
u16Data = (uint16)(*pUartState->pTxBuff);
|
|
/* Update the state structure */
|
|
if(pUartState->u32TxSize == 1U)
|
|
{
|
|
++pUartState->pTxBuff;
|
|
--pUartState->u32TxSize;
|
|
}
|
|
else
|
|
{
|
|
++pUartState->pTxBuff;
|
|
u16Data |= (uint16)(((uint16)(*pUartState->pTxBuff)) << 8U);
|
|
|
|
++pUartState->pTxBuff;
|
|
pUartState->u32TxSize -= 2U;
|
|
}
|
|
|
|
/* Transmit the data */
|
|
if (pUartUserCfg->eBitCountPerChar == LPUART_UART_IP_9_BITS_PER_CHAR)
|
|
{
|
|
LPUART_Uart_Putchar9(pBase, u16Data);
|
|
}
|
|
else
|
|
{
|
|
LPUART_Uart_Putchar10(pBase, u16Data);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : Lpuart_Uart_Ip_GetData
|
|
* Description : Read data from the buffer register, according to configured
|
|
* word length.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static void Lpuart_Uart_Ip_GetData(uint32 u32Instance)
|
|
{
|
|
Lpuart_Uart_Ip_StateStructureType * pUartState;
|
|
const Lpuart_Uart_Ip_UserConfigType *pUartUserCfg;
|
|
LPUART_Type * pBase;
|
|
uint16 u16Data;
|
|
|
|
pBase = Lpuart_Uart_Ip_apBases[u32Instance];
|
|
pUartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[u32Instance];
|
|
pUartUserCfg = (Lpuart_Uart_Ip_UserConfigType*) Lpuart_Uart_Ip_apUserConfig[u32Instance];
|
|
|
|
if ((LPUART_UART_IP_7_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar) || (LPUART_UART_IP_8_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar))
|
|
{
|
|
/* Receive the data */
|
|
*(pUartState->pRxBuff) = LPUART_Uart_Getchar(pBase);
|
|
if (LPUART_UART_IP_7_BITS_PER_CHAR == pUartUserCfg->eBitCountPerChar)
|
|
{
|
|
*(pUartState->pRxBuff) &= 0x7FU;
|
|
}
|
|
/* Update the state structure */
|
|
++pUartState->pRxBuff;
|
|
--pUartState->u32RxSize;
|
|
}
|
|
else
|
|
{
|
|
if (pUartUserCfg->eBitCountPerChar == LPUART_UART_IP_9_BITS_PER_CHAR)
|
|
{
|
|
u16Data = LPUART_Uart_Getchar9(pBase);
|
|
}
|
|
else
|
|
{
|
|
u16Data = LPUART_Uart_Getchar10(pBase);
|
|
}
|
|
/* Get the data and update state structure */
|
|
if(pUartState->u32RxSize == 1U)
|
|
{
|
|
*(pUartState->pRxBuff) = (uint8)u16Data;
|
|
++pUartState->pRxBuff;
|
|
--pUartState->u32RxSize;
|
|
}
|
|
else
|
|
{
|
|
/* Write the least significant bits to the receive buffer */
|
|
*(pUartState->pRxBuff) = (uint8)(u16Data & 0xFFU);
|
|
++pUartState->pRxBuff;
|
|
/* Write the ninth bit to the subsequent byte in the rx buffer */
|
|
*pUartState->pRxBuff = (uint8)(u16Data >> 8U);
|
|
++pUartState->pRxBuff;
|
|
pUartState->u32RxSize -= 2U;
|
|
}
|
|
}
|
|
}
|
|
|
|
#define UART_STOP_SEC_CODE
|
|
/* @violates @ref Uart_c_REF_1 This violation is not fixed since the inclusion of Uart_MemMap.h is as per AUTOSAR requirement*/
|
|
#include "Uart_MemMap.h"
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
|
|
/** @} */
|
|
|
|
#endif
|