MCUXpresso: Update the SDK LPUART drivers

Use the latest driver from K66F

Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
pull/11268/head
Mahesh Mahadevan 2019-08-22 08:26:11 -05:00
parent bff287580c
commit a184a86e90
12 changed files with 797 additions and 407 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -115,8 +115,17 @@ static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS;
#else
static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS;
#endif
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of LPUART clock name. */
static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS;
#if defined(LPUART_PERIPH_CLOCKS)
/* Array of LPUART functional clock name. */
static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS;
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* LPUART ISR for transactional APIs. */
static lpuart_isr_t s_lpuartIsr;
@ -128,7 +137,7 @@ uint32_t LPUART_GetInstance(LPUART_Type *base)
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < FSL_FEATURE_SOC_LPUART_COUNT; instance++)
for (instance = 0; instance < ARRAY_SIZE(s_lpuartBases); instance++)
{
if (s_lpuartBases[instance] == base)
{
@ -136,7 +145,7 @@ uint32_t LPUART_GetInstance(LPUART_Type *base)
}
}
assert(instance < FSL_FEATURE_SOC_LPUART_COUNT);
assert(instance < ARRAY_SIZE(s_lpuartBases));
return instance;
}
@ -280,11 +289,25 @@ status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t
return kStatus_LPUART_BaudrateNotSupport;
}
/* Enable lpuart clock */
CLOCK_EnableClock(s_lpuartClock[LPUART_GetInstance(base)]);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = LPUART_GetInstance(base);
/* Enable lpuart clock */
CLOCK_EnableClock(s_lpuartClock[instance]);
#if defined(LPUART_PERIPH_CLOCKS)
CLOCK_EnableClock(s_lpuartPeriphClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
/*Reset all internal logic and registers, except the Global Register */
LPUART_SoftwareReset(base);
#else
/* Disable LPUART TX RX before setting. */
base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
#endif
temp = base->BAUD;
@ -422,8 +445,17 @@ void LPUART_Deinit(LPUART_Type *base)
/* Disable the module. */
base->CTRL = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = LPUART_GetInstance(base);
/* Disable lpuart clock */
CLOCK_DisableClock(s_lpuartClock[LPUART_GetInstance(base)]);
CLOCK_DisableClock(s_lpuartClock[instance]);
#if defined(LPUART_PERIPH_CLOCKS)
CLOCK_DisableClock(s_lpuartPeriphClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void LPUART_GetDefaultConfig(lpuart_config_t *config)
@ -861,7 +893,6 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
size_t bytesToReceive;
/* How many bytes currently have received. */
size_t bytesCurrentReceived;
uint32_t regPrimask = 0U;
/* How to get data:
1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
@ -885,8 +916,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
/* If RX ring buffer is used. */
if (handle->rxRingBuffer)
{
/* Disable IRQ, protect ring buffer. */
regPrimask = DisableGlobalIRQ();
/* Disable LPUART RX IRQ, protect ring buffer. */
LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
/* How many bytes in RX ring buffer currently. */
bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle);
@ -923,8 +954,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
handle->rxDataSizeAll = bytesToReceive;
handle->rxState = kLPUART_RxBusy;
}
/* Enable IRQ if previously enabled. */
EnableGlobalIRQ(regPrimask);
/* Enable LPUART RX IRQ if previously enabled. */
LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
/* Call user callback since all data are received. */
if (0 == bytesToReceive)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -37,29 +37,27 @@
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPUART driver version 2.2.1. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 1))
/*! @brief LPUART driver version 2.2.3. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 3))
/*@}*/
/*! @brief Error codes for the LPUART driver. */
enum _lpuart_status
{
kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */
kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */
kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */
kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */
kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */
kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */
kStatus_LPUART_FlagCannotClearManually =
MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */
kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */
kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */
kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */
kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */
kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */
kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */
kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */
kStatus_LPUART_FlagCannotClearManually = MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */
kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */
kStatus_LPUART_RxRingBufferOverrun =
MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */
kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */
@ -67,7 +65,7 @@ enum _lpuart_status
kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */
kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */
kStatus_LPUART_BaudrateNotSupport =
MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */
MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */
};
/*! @brief LPUART parity mode. */
@ -81,9 +79,9 @@ typedef enum _lpuart_parity_mode
/*! @brief LPUART data bits count. */
typedef enum _lpuart_data_bits
{
kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */
kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */
kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */
#endif
} lpuart_data_bits_t;
@ -168,13 +166,13 @@ enum _lpuart_flags
#endif
};
/*! @brief LPUART configure structure. */
/*! @brief LPUART configuration structure. */
typedef struct _lpuart_config
{
uint32_t baudRate_Bps; /*!< LPUART baud rate */
lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
uint32_t baudRate_Bps; /*!< LPUART baud rate */
lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */
bool isMsb; /*!< Data bits order, LSB (default), MSB */
bool isMsb; /*!< Data bits order, LSB (default), MSB */
#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
#endif
@ -233,35 +231,58 @@ struct _lpuart_handle
extern "C" {
#endif /* _cplusplus */
#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
/*!
* @name Software Reset
* @{
*/
/*!
* @brief Resets the LPUART using software.
*
* This function resets all internal logic and registers except the Global Register.
* Remains set until cleared by software.
*
* @param base LPUART peripheral base address.
*/
static inline void LPUART_SoftwareReset(LPUART_Type *base)
{
base->GLOBAL |= LPUART_GLOBAL_RST_MASK;
base->GLOBAL &= ~LPUART_GLOBAL_RST_MASK;
}
/* @} */
#endif /*FSL_FEATURE_LPUART_HAS_GLOBAL*/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
*
* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
* The example below shows how to use this API to configure the LPUART.
* @code
* lpuart_config_t lpuartConfig;
* lpuartConfig.baudRate_Bps = 115200U;
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
* lpuartConfig.dataBitsCount = kLPUART_EightDataBits;
* lpuartConfig.isMsb = false;
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
* lpuartConfig.txFifoWatermark = 0;
* lpuartConfig.rxFifoWatermark = 1;
* LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
* @endcode
*
* @param base LPUART peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @param srcClock_Hz LPUART clock source frequency in HZ.
* @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success LPUART initialize succeed
*/
* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
*
* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
* The example below shows how to use this API to configure the LPUART.
* @code
* lpuart_config_t lpuartConfig;
* lpuartConfig.baudRate_Bps = 115200U;
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
* lpuartConfig.dataBitsCount = kLPUART_EightDataBits;
* lpuartConfig.isMsb = false;
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
* lpuartConfig.txFifoWatermark = 0;
* lpuartConfig.rxFifoWatermark = 1;
* LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
* @endcode
*
* @param base LPUART peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @param srcClock_Hz LPUART clock source frequency in HZ.
* @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success LPUART initialize succeed
*/
status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz);
/*!
@ -536,10 +557,10 @@ static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data)
}
/*!
* @brief Reads the RX register.
* @brief Reads the receiver register.
*
* This function reads data from the receiver register directly. The upper layer must
* ensure that the RX register is full or that the RX FIFO has data before calling this function.
* ensure that the receiver register is full or that the RX FIFO has data before calling this function.
*
* @param base LPUART peripheral base address.
* @return Data read from data register.
@ -548,8 +569,9 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
{
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
uint32_t ctrl = base->CTRL;
bool isSevenDataBits = ((ctrl & LPUART_CTRL_M7_MASK) ||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
bool isSevenDataBits =
((ctrl & LPUART_CTRL_M7_MASK) ||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
if (isSevenDataBits)
{
@ -565,10 +587,10 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
}
/*!
* @brief Writes to transmitter register using a blocking method.
* @brief Writes to the transmitter register using a blocking method.
*
* This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have
* room and then writes data to the transmitter buffer.
* room, and writes data to the transmitter buffer.
*
* @note This function does not check whether all data has been sent out to the bus.
* Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is
@ -581,10 +603,10 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
/*!
* @brief Reads the RX data register using a blocking method.
* @brief Reads the receiver data register using a blocking method.
*
* This function polls the RX register, waits for the RX register full or RX FIFO
* has data then reads data from the TX register.
* This function polls the receiver register, waits for the receiver register full or receiver FIFO
* has data, and reads data from the TX register.
*
* @param base LPUART peripheral base address.
* @param data Start address of the buffer to store the received data.
@ -670,7 +692,7 @@ void LPUART_TransferStartRingBuffer(LPUART_Type *base,
size_t ringBufferSize);
/*!
* @brief Abort the background transfer and uninstall the ring buffer.
* @brief Aborts the background transfer and uninstalls the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
@ -683,7 +705,7 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle);
* @brief Aborts the interrupt-driven data transmit.
*
* This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
* how many bytes are still not sent out.
* how many bytes are not sent out.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
@ -691,10 +713,10 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle);
void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to LPUART TX register.
* @brief Gets the number of bytes that have been written to the LPUART transmitter register.
*
* This function gets the number of bytes that have been written to LPUART TX
* register by interrupt method.
* register by an interrupt method.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
@ -748,7 +770,7 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been received.
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -219,6 +219,9 @@ status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart
EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base),
sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral);
/* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
handle->nbytes = sizeof(uint8_t);
/* Submit transfer. */
EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->txEdmaHandle);
@ -257,6 +260,9 @@ status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpu
EDMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data,
sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory);
/* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
handle->nbytes = sizeof(uint8_t);
/* Submit transfer. */
EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->rxEdmaHandle);
@ -309,7 +315,9 @@ status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handl
return kStatus_NoTransferInProgress;
}
*count = handle->rxDataSizeAll - EDMA_GetRemainingBytes(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
*count = handle->rxDataSizeAll -
(uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
return kStatus_Success;
}
@ -325,7 +333,9 @@ status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t
return kStatus_NoTransferInProgress;
}
*count = handle->txDataSizeAll - EDMA_GetRemainingBytes(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
*count = handle->txDataSizeAll -
(uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
return kStatus_Success;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -39,7 +39,6 @@
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
@ -66,6 +65,8 @@ struct _lpuart_edma_handle
edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */
edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
@ -93,11 +94,11 @@ extern "C" {
* @param rxEdmaHandle User requested DMA handle for RX DMA transfer.
*/
void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle);
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle);
/*!
* @brief Sends data using eDMA.
@ -150,9 +151,9 @@ void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handl
void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to LPUART TX register.
* @brief Gets the number of bytes written to the LPUART TX register.
*
* This function gets the number of bytes that have been written to LPUART TX
* This function gets the number of bytes written to the LPUART TX
* register by DMA.
*
* @param base LPUART peripheral base address.
@ -165,9 +166,9 @@ void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *ha
status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count);
/*!
* @brief Get the number of bytes that have been received.
* @brief Gets the number of received bytes.
*
* This function gets the number of bytes that have been received.
* This function gets the number of received bytes.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -115,8 +115,17 @@ static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS;
#else
static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS;
#endif
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of LPUART clock name. */
static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS;
#if defined(LPUART_PERIPH_CLOCKS)
/* Array of LPUART functional clock name. */
static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS;
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* LPUART ISR for transactional APIs. */
static lpuart_isr_t s_lpuartIsr;
@ -128,7 +137,7 @@ uint32_t LPUART_GetInstance(LPUART_Type *base)
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < FSL_FEATURE_SOC_LPUART_COUNT; instance++)
for (instance = 0; instance < ARRAY_SIZE(s_lpuartBases); instance++)
{
if (s_lpuartBases[instance] == base)
{
@ -136,7 +145,7 @@ uint32_t LPUART_GetInstance(LPUART_Type *base)
}
}
assert(instance < FSL_FEATURE_SOC_LPUART_COUNT);
assert(instance < ARRAY_SIZE(s_lpuartBases));
return instance;
}
@ -280,11 +289,25 @@ status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t
return kStatus_LPUART_BaudrateNotSupport;
}
/* Enable lpuart clock */
CLOCK_EnableClock(s_lpuartClock[LPUART_GetInstance(base)]);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = LPUART_GetInstance(base);
/* Enable lpuart clock */
CLOCK_EnableClock(s_lpuartClock[instance]);
#if defined(LPUART_PERIPH_CLOCKS)
CLOCK_EnableClock(s_lpuartPeriphClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
/*Reset all internal logic and registers, except the Global Register */
LPUART_SoftwareReset(base);
#else
/* Disable LPUART TX RX before setting. */
base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
#endif
temp = base->BAUD;
@ -422,8 +445,17 @@ void LPUART_Deinit(LPUART_Type *base)
/* Disable the module. */
base->CTRL = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = LPUART_GetInstance(base);
/* Disable lpuart clock */
CLOCK_DisableClock(s_lpuartClock[LPUART_GetInstance(base)]);
CLOCK_DisableClock(s_lpuartClock[instance]);
#if defined(LPUART_PERIPH_CLOCKS)
CLOCK_DisableClock(s_lpuartPeriphClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void LPUART_GetDefaultConfig(lpuart_config_t *config)
@ -861,7 +893,6 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
size_t bytesToReceive;
/* How many bytes currently have received. */
size_t bytesCurrentReceived;
uint32_t regPrimask = 0U;
/* How to get data:
1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
@ -885,8 +916,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
/* If RX ring buffer is used. */
if (handle->rxRingBuffer)
{
/* Disable IRQ, protect ring buffer. */
regPrimask = DisableGlobalIRQ();
/* Disable LPUART RX IRQ, protect ring buffer. */
LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
/* How many bytes in RX ring buffer currently. */
bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle);
@ -923,8 +954,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
handle->rxDataSizeAll = bytesToReceive;
handle->rxState = kLPUART_RxBusy;
}
/* Enable IRQ if previously enabled. */
EnableGlobalIRQ(regPrimask);
/* Enable LPUART RX IRQ if previously enabled. */
LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
/* Call user callback since all data are received. */
if (0 == bytesToReceive)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -37,29 +37,27 @@
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPUART driver version 2.2.1. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 1))
/*! @brief LPUART driver version 2.2.3. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 3))
/*@}*/
/*! @brief Error codes for the LPUART driver. */
enum _lpuart_status
{
kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */
kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */
kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */
kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */
kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */
kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */
kStatus_LPUART_FlagCannotClearManually =
MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */
kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */
kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */
kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */
kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */
kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */
kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */
kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */
kStatus_LPUART_FlagCannotClearManually = MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */
kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */
kStatus_LPUART_RxRingBufferOverrun =
MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */
kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */
@ -67,7 +65,7 @@ enum _lpuart_status
kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */
kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */
kStatus_LPUART_BaudrateNotSupport =
MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */
MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */
};
/*! @brief LPUART parity mode. */
@ -81,9 +79,9 @@ typedef enum _lpuart_parity_mode
/*! @brief LPUART data bits count. */
typedef enum _lpuart_data_bits
{
kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */
kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */
kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */
#endif
} lpuart_data_bits_t;
@ -168,13 +166,13 @@ enum _lpuart_flags
#endif
};
/*! @brief LPUART configure structure. */
/*! @brief LPUART configuration structure. */
typedef struct _lpuart_config
{
uint32_t baudRate_Bps; /*!< LPUART baud rate */
lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
uint32_t baudRate_Bps; /*!< LPUART baud rate */
lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */
bool isMsb; /*!< Data bits order, LSB (default), MSB */
bool isMsb; /*!< Data bits order, LSB (default), MSB */
#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
#endif
@ -233,35 +231,58 @@ struct _lpuart_handle
extern "C" {
#endif /* _cplusplus */
#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
/*!
* @name Software Reset
* @{
*/
/*!
* @brief Resets the LPUART using software.
*
* This function resets all internal logic and registers except the Global Register.
* Remains set until cleared by software.
*
* @param base LPUART peripheral base address.
*/
static inline void LPUART_SoftwareReset(LPUART_Type *base)
{
base->GLOBAL |= LPUART_GLOBAL_RST_MASK;
base->GLOBAL &= ~LPUART_GLOBAL_RST_MASK;
}
/* @} */
#endif /*FSL_FEATURE_LPUART_HAS_GLOBAL*/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
*
* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
* The example below shows how to use this API to configure the LPUART.
* @code
* lpuart_config_t lpuartConfig;
* lpuartConfig.baudRate_Bps = 115200U;
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
* lpuartConfig.dataBitsCount = kLPUART_EightDataBits;
* lpuartConfig.isMsb = false;
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
* lpuartConfig.txFifoWatermark = 0;
* lpuartConfig.rxFifoWatermark = 1;
* LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
* @endcode
*
* @param base LPUART peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @param srcClock_Hz LPUART clock source frequency in HZ.
* @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success LPUART initialize succeed
*/
* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
*
* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
* The example below shows how to use this API to configure the LPUART.
* @code
* lpuart_config_t lpuartConfig;
* lpuartConfig.baudRate_Bps = 115200U;
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
* lpuartConfig.dataBitsCount = kLPUART_EightDataBits;
* lpuartConfig.isMsb = false;
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
* lpuartConfig.txFifoWatermark = 0;
* lpuartConfig.rxFifoWatermark = 1;
* LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
* @endcode
*
* @param base LPUART peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @param srcClock_Hz LPUART clock source frequency in HZ.
* @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success LPUART initialize succeed
*/
status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz);
/*!
@ -536,10 +557,10 @@ static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data)
}
/*!
* @brief Reads the RX register.
* @brief Reads the receiver register.
*
* This function reads data from the receiver register directly. The upper layer must
* ensure that the RX register is full or that the RX FIFO has data before calling this function.
* ensure that the receiver register is full or that the RX FIFO has data before calling this function.
*
* @param base LPUART peripheral base address.
* @return Data read from data register.
@ -548,8 +569,9 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
{
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
uint32_t ctrl = base->CTRL;
bool isSevenDataBits = ((ctrl & LPUART_CTRL_M7_MASK) ||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
bool isSevenDataBits =
((ctrl & LPUART_CTRL_M7_MASK) ||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
if (isSevenDataBits)
{
@ -565,10 +587,10 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
}
/*!
* @brief Writes to transmitter register using a blocking method.
* @brief Writes to the transmitter register using a blocking method.
*
* This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have
* room and then writes data to the transmitter buffer.
* room, and writes data to the transmitter buffer.
*
* @note This function does not check whether all data has been sent out to the bus.
* Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is
@ -581,10 +603,10 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
/*!
* @brief Reads the RX data register using a blocking method.
* @brief Reads the receiver data register using a blocking method.
*
* This function polls the RX register, waits for the RX register full or RX FIFO
* has data then reads data from the TX register.
* This function polls the receiver register, waits for the receiver register full or receiver FIFO
* has data, and reads data from the TX register.
*
* @param base LPUART peripheral base address.
* @param data Start address of the buffer to store the received data.
@ -670,7 +692,7 @@ void LPUART_TransferStartRingBuffer(LPUART_Type *base,
size_t ringBufferSize);
/*!
* @brief Abort the background transfer and uninstall the ring buffer.
* @brief Aborts the background transfer and uninstalls the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
@ -683,7 +705,7 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle);
* @brief Aborts the interrupt-driven data transmit.
*
* This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
* how many bytes are still not sent out.
* how many bytes are not sent out.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
@ -691,10 +713,10 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle);
void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to LPUART TX register.
* @brief Gets the number of bytes that have been written to the LPUART transmitter register.
*
* This function gets the number of bytes that have been written to LPUART TX
* register by interrupt method.
* register by an interrupt method.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
@ -748,7 +770,7 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been received.
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -219,6 +219,9 @@ status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart
EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base),
sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral);
/* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
handle->nbytes = sizeof(uint8_t);
/* Submit transfer. */
EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->txEdmaHandle);
@ -257,6 +260,9 @@ status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpu
EDMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data,
sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory);
/* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
handle->nbytes = sizeof(uint8_t);
/* Submit transfer. */
EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->rxEdmaHandle);
@ -309,7 +315,9 @@ status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handl
return kStatus_NoTransferInProgress;
}
*count = handle->rxDataSizeAll - EDMA_GetRemainingBytes(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
*count = handle->rxDataSizeAll -
(uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
return kStatus_Success;
}
@ -325,7 +333,9 @@ status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t
return kStatus_NoTransferInProgress;
}
*count = handle->txDataSizeAll - EDMA_GetRemainingBytes(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
*count = handle->txDataSizeAll -
(uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
return kStatus_Success;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -39,7 +39,6 @@
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
@ -66,6 +65,8 @@ struct _lpuart_edma_handle
edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */
edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
@ -93,11 +94,11 @@ extern "C" {
* @param rxEdmaHandle User requested DMA handle for RX DMA transfer.
*/
void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle);
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle);
/*!
* @brief Sends data using eDMA.
@ -150,9 +151,9 @@ void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handl
void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to LPUART TX register.
* @brief Gets the number of bytes written to the LPUART TX register.
*
* This function gets the number of bytes that have been written to LPUART TX
* This function gets the number of bytes written to the LPUART TX
* register by DMA.
*
* @param base LPUART peripheral base address.
@ -165,9 +166,9 @@ void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *ha
status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count);
/*!
* @brief Get the number of bytes that have been received.
* @brief Gets the number of received bytes.
*
* This function gets the number of bytes that have been received.
* This function gets the number of received bytes.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -109,9 +109,23 @@ static lpuart_handle_t *s_lpuartHandle[FSL_FEATURE_SOC_LPUART_COUNT];
/* Array of LPUART peripheral base address. */
static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS;
/* Array of LPUART IRQ number. */
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS;
static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS;
#else
static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS;
#endif
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of LPUART clock name. */
static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS;
#if defined(LPUART_PERIPH_CLOCKS)
/* Array of LPUART functional clock name. */
static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS;
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* LPUART ISR for transactional APIs. */
static lpuart_isr_t s_lpuartIsr;
@ -123,7 +137,7 @@ uint32_t LPUART_GetInstance(LPUART_Type *base)
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < FSL_FEATURE_SOC_LPUART_COUNT; instance++)
for (instance = 0; instance < ARRAY_SIZE(s_lpuartBases); instance++)
{
if (s_lpuartBases[instance] == base)
{
@ -131,13 +145,15 @@ uint32_t LPUART_GetInstance(LPUART_Type *base)
}
}
assert(instance < FSL_FEATURE_SOC_LPUART_COUNT);
assert(instance < ARRAY_SIZE(s_lpuartBases));
return instance;
}
static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle)
{
assert(handle);
size_t size;
if (handle->rxRingBufferTail > handle->rxRingBufferHead)
@ -154,6 +170,8 @@ static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_han
static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle)
{
assert(handle);
bool full;
if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U))
@ -169,6 +187,8 @@ static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t
static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
{
assert(data);
size_t i;
/* The Non Blocking write data API assume user have ensured there is enough space in
@ -181,33 +201,48 @@ static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size
static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length)
{
assert(data);
size_t i;
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
uint32_t ctrl = base->CTRL;
bool isSevenDataBits =
((ctrl & LPUART_CTRL_M7_MASK) ||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
#endif
/* The Non Blocking read data API assume user have ensured there is enough space in
peripheral to write. */
for (i = 0; i < length; i++)
{
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
if (isSevenDataBits)
{
data[i] = (base->DATA & 0x7F);
}
else
{
data[i] = base->DATA;
}
#else
data[i] = base->DATA;
#endif
}
}
void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz)
status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz)
{
assert(config);
assert(config->baudRate_Bps);
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark);
assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark);
#endif
uint32_t temp;
uint16_t sbr, sbrTemp;
uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff;
/* Enable lpuart clock */
CLOCK_EnableClock(s_lpuartClock[LPUART_GetInstance(base)]);
/* Disable LPUART TX RX before setting. */
base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
/* 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
@ -248,34 +283,75 @@ void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcC
/* Check to see if actual baud rate is within 3% of desired baud rate
* based on the best calculate OSR value */
if (baudDiff < ((config->baudRate_Bps / 100) * 3))
if (baudDiff > ((config->baudRate_Bps / 100) * 3))
{
temp = base->BAUD;
/* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
* If so, then "BOTHEDGE" sampling must be turned on */
if ((osr > 3) && (osr < 8))
{
temp |= LPUART_BAUD_BOTHEDGE_MASK;
}
/* program the osr value (bit value is one less than actual value) */
temp &= ~LPUART_BAUD_OSR_MASK;
temp |= LPUART_BAUD_OSR(osr - 1);
/* write the sbr value to the BAUD registers */
temp &= ~LPUART_BAUD_SBR_MASK;
base->BAUD = temp | LPUART_BAUD_SBR(sbr);
/* Unacceptable baud rate difference of more than 3%*/
return kStatus_LPUART_BaudrateNotSupport;
}
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = LPUART_GetInstance(base);
/* Enable lpuart clock */
CLOCK_EnableClock(s_lpuartClock[instance]);
#if defined(LPUART_PERIPH_CLOCKS)
CLOCK_EnableClock(s_lpuartPeriphClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
/*Reset all internal logic and registers, except the Global Register */
LPUART_SoftwareReset(base);
#else
/* Disable LPUART TX RX before setting. */
base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
#endif
temp = base->BAUD;
/* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
* If so, then "BOTHEDGE" sampling must be turned on */
if ((osr > 3) && (osr < 8))
{
temp |= LPUART_BAUD_BOTHEDGE_MASK;
}
/* program the osr value (bit value is one less than actual value) */
temp &= ~LPUART_BAUD_OSR_MASK;
temp |= LPUART_BAUD_OSR(osr - 1);
/* write the sbr value to the BAUD registers */
temp &= ~LPUART_BAUD_SBR_MASK;
base->BAUD = temp | LPUART_BAUD_SBR(sbr);
/* Set bit count and parity mode. */
base->BAUD &= ~LPUART_BAUD_M10_MASK;
temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK);
if (kLPUART_ParityDisabled != config->parityMode)
temp |= (uint8_t)config->parityMode;
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
if (kLPUART_SevenDataBits == config->dataBitsCount)
{
temp |= (LPUART_CTRL_M_MASK | (uint8_t)config->parityMode);
if (kLPUART_ParityDisabled != config->parityMode)
{
temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */
}
else
{
temp |= LPUART_CTRL_M7_MASK;
}
}
else
#endif
{
if (kLPUART_ParityDisabled != config->parityMode)
{
temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */
}
}
base->CTRL = temp;
@ -298,17 +374,27 @@ void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcC
#endif
/* Clear all status flags */
temp = (LPUART_STAT_LBKDIF_MASK | LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
temp |= LPUART_STAT_IDLE_MASK;
temp |= LPUART_STAT_LBKDIF_MASK;
#endif
#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
#endif
/* Set data bits order. */
if (config->isMsb)
{
temp |= LPUART_STAT_MSBF_MASK;
}
else
{
temp &= ~LPUART_STAT_MSBF_MASK;
}
base->STAT |= temp;
/* Enable TX/RX base on configure structure. */
@ -324,6 +410,8 @@ void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcC
}
base->CTRL = temp;
return kStatus_Success;
}
void LPUART_Deinit(LPUART_Type *base)
{
@ -341,11 +429,11 @@ void LPUART_Deinit(LPUART_Type *base)
}
/* Clear all status flags */
temp = (LPUART_STAT_LBKDIF_MASK | LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
temp |= LPUART_STAT_IDLE_MASK;
temp |= LPUART_STAT_LBKDIF_MASK;
#endif
#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
@ -357,15 +445,27 @@ void LPUART_Deinit(LPUART_Type *base)
/* Disable the module. */
base->CTRL = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = LPUART_GetInstance(base);
/* Disable lpuart clock */
CLOCK_DisableClock(s_lpuartClock[LPUART_GetInstance(base)]);
CLOCK_DisableClock(s_lpuartClock[instance]);
#if defined(LPUART_PERIPH_CLOCKS)
CLOCK_DisableClock(s_lpuartPeriphClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void LPUART_GetDefaultConfig(lpuart_config_t *config)
{
assert(config);
config->baudRate_Bps = 115200U;
config->parityMode = kLPUART_ParityDisabled;
config->dataBitsCount = kLPUART_EightDataBits;
config->isMsb = false;
#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
config->stopBitCount = kLPUART_OneStopBit;
#endif
@ -377,18 +477,14 @@ void LPUART_GetDefaultConfig(lpuart_config_t *config)
config->enableRx = false;
}
void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
{
assert(baudRate_Bps);
uint32_t temp, oldCtrl;
uint16_t sbr, sbrTemp;
uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff;
/* Store CTRL before disable Tx and Rx */
oldCtrl = base->CTRL;
/* Disable LPUART TX RX before setting. */
base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
/* 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
@ -431,6 +527,12 @@ void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcCl
* based on the best calculate OSR value */
if (baudDiff < ((baudRate_Bps / 100) * 3))
{
/* Store CTRL before disable Tx and Rx */
oldCtrl = base->CTRL;
/* Disable LPUART TX RX before setting. */
base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
temp = base->BAUD;
/* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
@ -447,17 +549,25 @@ void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcCl
/* write the sbr value to the BAUD registers */
temp &= ~LPUART_BAUD_SBR_MASK;
base->BAUD = temp | LPUART_BAUD_SBR(sbr);
}
/* Restore CTRL. */
base->CTRL = oldCtrl;
/* Restore CTRL. */
base->CTRL = oldCtrl;
return kStatus_Success;
}
else
{
/* Unacceptable baud rate difference of more than 3%*/
return kStatus_LPUART_BaudrateNotSupport;
}
}
void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask)
{
base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK));
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
base->FIFO |= ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) |
((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
#endif
mask &= 0xFFFFFF00U;
base->CTRL |= mask;
@ -467,7 +577,8 @@ void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask)
{
base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK));
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
base->FIFO &= ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) &
~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
#endif
mask &= 0xFFFFFF00U;
base->CTRL &= ~mask;
@ -503,24 +614,24 @@ status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask)
status_t status;
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
temp = (uint32_t)base->FIFO;
temp &= (uint32_t)(~(kLPUART_TxFifoOverflowFlag | kLPUART_RxFifoUnderflowFlag));
temp |= mask & (kLPUART_TxFifoOverflowFlag | kLPUART_RxFifoUnderflowFlag);
temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK));
temp |= (mask << 16) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK);
base->FIFO = temp;
#endif
temp = (uint32_t)base->STAT;
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
temp &= (uint32_t)(~(kLPUART_LinBreakFlag));
temp |= mask & kLPUART_LinBreakFlag;
temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK));
temp |= mask & LPUART_STAT_LBKDIF_MASK;
#endif
temp &= (uint32_t)(~(kLPUART_RxActiveEdgeFlag | kLPUART_IdleLineFlag | kLPUART_RxOverrunFlag |
kLPUART_NoiseErrorFlag | kLPUART_FramingErrorFlag | kLPUART_ParityErrorFlag));
temp |= mask & (kLPUART_RxActiveEdgeFlag | kLPUART_IdleLineFlag | kLPUART_RxOverrunFlag | kLPUART_NoiseErrorFlag |
kLPUART_FramingErrorFlag | kLPUART_ParityErrorFlag);
temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK));
temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
temp &= (uint32_t)(~(kLPUART_DataMatch2Flag | kLPUART_DataMatch2Flag));
temp |= mask & (kLPUART_DataMatch2Flag | kLPUART_DataMatch2Flag);
temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK));
temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK);
#endif
base->STAT |= temp;
base->STAT = temp;
/* If some flags still pending. */
if (mask & LPUART_GetStatusFlags(base))
{
@ -540,6 +651,8 @@ status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask)
void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
{
assert(data);
/* This API can only ensure that the data is written into the data buffer but can't
ensure all data in the data buffer are sent into the transmit shift buffer. */
while (length--)
@ -553,7 +666,15 @@ void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length)
{
assert(data);
uint32_t statusFlag;
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
uint32_t ctrl = base->CTRL;
bool isSevenDataBits =
((ctrl & LPUART_CTRL_M7_MASK) ||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
#endif
while (length--)
{
@ -589,7 +710,18 @@ status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length)
return kStatus_LPUART_ParityError;
}
}
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
if (isSevenDataBits)
{
*(data++) = (base->DATA & 0x7F);
}
else
{
*(data++) = base->DATA;
}
#else
*(data++) = base->DATA;
#endif
}
return kStatus_Success;
@ -603,6 +735,12 @@ void LPUART_TransferCreateHandle(LPUART_Type *base,
assert(handle);
uint32_t instance;
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
uint32_t ctrl = base->CTRL;
bool isSevenDataBits =
((ctrl & LPUART_CTRL_M7_MASK) ||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
#endif
/* Zero the handle. */
memset(handle, 0, sizeof(lpuart_handle_t));
@ -615,6 +753,11 @@ void LPUART_TransferCreateHandle(LPUART_Type *base,
handle->callback = callback;
handle->userData = userData;
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
/* Initial seven data bits flag */
handle->isSevenDataBits = isSevenDataBits;
#endif
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
/* Note:
Take care of the RX FIFO, RX interrupt request only assert when received bytes
@ -624,7 +767,7 @@ void LPUART_TransferCreateHandle(LPUART_Type *base,
5 bytes are received. the last byte will be saved in FIFO but not trigger
RX interrupt because the water mark is 2.
*/
base->WATER &= (~LPUART_WATER_RXWATER_SHIFT);
base->WATER &= (~LPUART_WATER_RXWATER_MASK);
#endif
/* Get instance from peripheral base address. */
@ -635,8 +778,13 @@ void LPUART_TransferCreateHandle(LPUART_Type *base,
s_lpuartIsr = LPUART_TransferHandleIRQ;
/* Enable interrupt in NVIC. */
/* Enable interrupt in NVIC. */
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
EnableIRQ(s_lpuartRxIRQ[instance]);
EnableIRQ(s_lpuartTxIRQ[instance]);
#else
EnableIRQ(s_lpuartIRQ[instance]);
#endif
}
void LPUART_TransferStartRingBuffer(LPUART_Type *base,
@ -645,18 +793,16 @@ void LPUART_TransferStartRingBuffer(LPUART_Type *base,
size_t ringBufferSize)
{
assert(handle);
assert(ringBuffer);
/* Setup the ring buffer address */
if (ringBuffer)
{
handle->rxRingBuffer = ringBuffer;
handle->rxRingBufferSize = ringBufferSize;
handle->rxRingBufferHead = 0U;
handle->rxRingBufferTail = 0U;
handle->rxRingBuffer = ringBuffer;
handle->rxRingBufferSize = ringBufferSize;
handle->rxRingBufferHead = 0U;
handle->rxRingBufferTail = 0U;
/* Enable the interrupt to accept the data when user need the ring buffer. */
LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
}
/* Enable the interrupt to accept the data when user need the ring buffer. */
LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
}
void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle)
@ -676,13 +822,12 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle)
status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer)
{
status_t status;
assert(handle);
assert(xfer);
assert(xfer->data);
assert(xfer->dataSize);
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
status_t status;
/* Return error if current TX busy. */
if (kLPUART_TxBusy == handle->txState)
@ -707,6 +852,8 @@ status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *hand
void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle)
{
assert(handle);
LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable);
handle->txDataSize = 0;
@ -715,16 +862,14 @@ void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle)
status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
{
assert(handle);
assert(count);
if (kLPUART_TxIdle == handle->txState)
{
return kStatus_NoTransferInProgress;
}
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->txDataSizeAll - handle->txDataSize;
return kStatus_Success;
@ -735,6 +880,11 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
lpuart_transfer_t *xfer,
size_t *receivedBytes)
{
assert(handle);
assert(xfer);
assert(xfer->data);
assert(xfer->dataSize);
uint32_t i;
status_t status;
/* How many bytes to copy from ring buffer to user memory. */
@ -743,13 +893,6 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
size_t bytesToReceive;
/* How many bytes currently have received. */
size_t bytesCurrentReceived;
uint32_t regPrimask = 0U;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* How to get data:
1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
@ -773,8 +916,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
/* If RX ring buffer is used. */
if (handle->rxRingBuffer)
{
/* Disable IRQ, protect ring buffer. */
regPrimask = DisableGlobalIRQ();
/* Disable LPUART RX IRQ, protect ring buffer. */
LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
/* How many bytes in RX ring buffer currently. */
bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle);
@ -811,8 +954,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
handle->rxDataSizeAll = bytesToReceive;
handle->rxState = kLPUART_RxBusy;
}
/* Enable IRQ if previously enabled. */
EnableGlobalIRQ(regPrimask);
/* Enable LPUART RX IRQ if previously enabled. */
LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
/* Call user callback since all data are received. */
if (0 == bytesToReceive)
@ -849,6 +992,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle)
{
assert(handle);
/* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
if (!handle->rxRingBuffer)
{
@ -862,16 +1007,14 @@ void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle)
status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
{
assert(handle);
assert(count);
if (kLPUART_RxIdle == handle->rxState)
{
return kStatus_NoTransferInProgress;
}
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->rxDataSizeAll - handle->rxDataSize;
return kStatus_Success;
@ -879,19 +1022,17 @@ status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *hand
void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle)
{
assert(handle);
uint8_t count;
uint8_t tempCount;
volatile uint8_t dummy;
assert(handle);
/* If RX overrun. */
if (LPUART_STAT_OR_MASK & base->STAT)
{
/* Read base->DATA, otherwise the RX does not work. */
dummy = base->DATA;
/* Avoid optimization */
dummy++;
/* Clear overrun flag, otherwise the RX does not work. */
base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK);
/* Trigger callback. */
if (handle->callback)
{
@ -964,8 +1105,19 @@ void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle)
}
}
/* Read data. */
/* Read data. */
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
if (handle->isSevenDataBits)
{
handle->rxRingBuffer[handle->rxRingBufferHead] = (base->DATA & 0x7F);
}
else
{
handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA;
}
#else
handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA;
#endif
/* Increase handle->rxRingBufferHead. */
if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
@ -1033,71 +1185,113 @@ void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle)
void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle)
{
/* TODO: To be implemented. */
/* To be implemented by User. */
}
#if defined(LPUART0)
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
void LPUART0_TX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
}
void LPUART0_RX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
}
#else
void LPUART0_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
}
void LPUART0_RX_TX_DriverIRQHandler(void)
{
LPUART0_DriverIRQHandler();
}
#endif
#endif
#if defined(LPUART1)
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
void LPUART1_TX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
}
void LPUART1_RX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
}
#else
void LPUART1_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
}
void LPUART1_RX_TX_DriverIRQHandler(void)
{
LPUART1_DriverIRQHandler();
}
#endif
#endif
#if defined(LPUART2)
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
void LPUART2_TX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
}
void LPUART2_RX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
}
#else
void LPUART2_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
}
void LPUART2_RX_TX_DriverIRQHandler(void)
{
LPUART2_DriverIRQHandler();
}
#endif
#endif
#if defined(LPUART3)
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
void LPUART3_TX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
}
void LPUART3_RX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
}
#else
void LPUART3_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
}
void LPUART3_RX_TX_DriverIRQHandler(void)
{
LPUART3_DriverIRQHandler();
}
#endif
#endif
#if defined(LPUART4)
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
void LPUART4_TX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
}
void LPUART4_RX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
}
#else
void LPUART4_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
}
void LPUART4_RX_TX_DriverIRQHandler(void)
{
LPUART4_DriverIRQHandler();
}
#endif
#endif
#if defined(LPUART5)
#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
void LPUART5_TX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
}
void LPUART5_RX_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
}
#else
void LPUART5_DriverIRQHandler(void)
{
s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
}
void LPUART5_RX_TX_DriverIRQHandler(void)
{
LPUART5_DriverIRQHandler();
}
#endif
#endif

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -37,36 +37,35 @@
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPUART driver version 2.1.0. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*! @brief LPUART driver version 2.2.3. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 3))
/*@}*/
/*! @brief Error codes for the LPUART driver. */
enum _lpuart_status
{
kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */
kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */
kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */
kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */
kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */
kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */
kStatus_LPUART_FlagCannotClearManually =
MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */
kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */
kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */
kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */
kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */
kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */
kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */
kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */
kStatus_LPUART_FlagCannotClearManually = MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */
kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */
kStatus_LPUART_RxRingBufferOverrun =
MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */
kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */
kStatus_LPUART_NoiseError = MAKE_STATUS(kStatusGroup_LPUART, 10), /*!< LPUART noise error. */
kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */
kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */
kStatus_LPUART_BaudrateNotSupport =
MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */
};
/*! @brief LPUART parity mode. */
@ -77,6 +76,15 @@ typedef enum _lpuart_parity_mode
kLPUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */
} lpuart_parity_mode_t;
/*! @brief LPUART data bits count. */
typedef enum _lpuart_data_bits
{
kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */
#endif
} lpuart_data_bits_t;
/*! @brief LPUART stop bit count. */
typedef enum _lpuart_stop_bit_count
{
@ -158,11 +166,13 @@ enum _lpuart_flags
#endif
};
/*! @brief LPUART configure structure. */
/*! @brief LPUART configuration structure. */
typedef struct _lpuart_config
{
uint32_t baudRate_Bps; /*!< LPUART baud rate */
lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
uint32_t baudRate_Bps; /*!< LPUART baud rate */
lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */
bool isMsb; /*!< Data bits order, LSB (default), MSB */
#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
#endif
@ -206,7 +216,11 @@ struct _lpuart_handle
void *userData; /*!< LPUART callback function parameter.*/
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
volatile uint8_t rxState; /*!< RX transfer state. */
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
bool isSevenDataBits; /*!< Seven data bits flag. */
#endif
};
/*******************************************************************************
@ -217,32 +231,59 @@ struct _lpuart_handle
extern "C" {
#endif /* _cplusplus */
#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
/*!
* @name Software Reset
* @{
*/
/*!
* @brief Resets the LPUART using software.
*
* This function resets all internal logic and registers except the Global Register.
* Remains set until cleared by software.
*
* @param base LPUART peripheral base address.
*/
static inline void LPUART_SoftwareReset(LPUART_Type *base)
{
base->GLOBAL |= LPUART_GLOBAL_RST_MASK;
base->GLOBAL &= ~LPUART_GLOBAL_RST_MASK;
}
/* @} */
#endif /*FSL_FEATURE_LPUART_HAS_GLOBAL*/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
*
* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
* The example below shows how to use this API to configure the LPUART.
* @code
* lpuart_config_t lpuartConfig;
* lpuartConfig.baudRate_Bps = 115200U;
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
* lpuartConfig.txFifoWatermark = 0;
* lpuartConfig.rxFifoWatermark = 1;
* LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
* @endcode
*
* @param base LPUART peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @param srcClock_Hz LPUART clock source frequency in HZ.
*/
void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz);
* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock.
*
* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function
* to configure the configuration structure and get the default configuration.
* The example below shows how to use this API to configure the LPUART.
* @code
* lpuart_config_t lpuartConfig;
* lpuartConfig.baudRate_Bps = 115200U;
* lpuartConfig.parityMode = kLPUART_ParityDisabled;
* lpuartConfig.dataBitsCount = kLPUART_EightDataBits;
* lpuartConfig.isMsb = false;
* lpuartConfig.stopBitCount = kLPUART_OneStopBit;
* lpuartConfig.txFifoWatermark = 0;
* lpuartConfig.rxFifoWatermark = 1;
* LPUART_Init(LPUART1, &lpuartConfig, 20000000U);
* @endcode
*
* @param base LPUART peripheral base address.
* @param config Pointer to a user-defined configuration structure.
* @param srcClock_Hz LPUART clock source frequency in HZ.
* @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source.
* @retval kStatus_Success LPUART initialize succeed
*/
status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz);
/*!
* @brief Deinitializes a LPUART instance.
@ -260,6 +301,8 @@ void LPUART_Deinit(LPUART_Type *base);
* values are:
* lpuartConfig->baudRate_Bps = 115200U;
* lpuartConfig->parityMode = kLPUART_ParityDisabled;
* lpuartConfig->dataBitsCount = kLPUART_EightDataBits;
* lpuartConfig->isMsb = false;
* lpuartConfig->stopBitCount = kLPUART_OneStopBit;
* lpuartConfig->txFifoWatermark = 0;
* lpuartConfig->rxFifoWatermark = 1;
@ -282,8 +325,10 @@ void LPUART_GetDefaultConfig(lpuart_config_t *config);
* @param base LPUART peripheral base address.
* @param baudRate_Bps LPUART baudrate to be set.
* @param srcClock_Hz LPUART clock source frequency in HZ.
* @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source.
* @retval kStatus_Success Set baudrate succeeded.
*/
void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
/* @} */
@ -512,24 +557,40 @@ static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data)
}
/*!
* @brief Reads the RX register.
* @brief Reads the receiver register.
*
* This function reads data from the TX register directly. The upper layer must
* ensure that the RX register is full or that the TX FIFO has data before calling this function.
* This function reads data from the receiver register directly. The upper layer must
* ensure that the receiver register is full or that the RX FIFO has data before calling this function.
*
* @param base LPUART peripheral base address.
* @return Data read from data register.
*/
static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
{
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
uint32_t ctrl = base->CTRL;
bool isSevenDataBits =
((ctrl & LPUART_CTRL_M7_MASK) ||
((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
if (isSevenDataBits)
{
return (base->DATA & 0x7F);
}
else
{
return base->DATA;
}
#else
return base->DATA;
#endif
}
/*!
* @brief Writes to transmitter register using a blocking method.
* @brief Writes to the transmitter register using a blocking method.
*
* This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have
* room and then writes data to the transmitter buffer.
* room, and writes data to the transmitter buffer.
*
* @note This function does not check whether all data has been sent out to the bus.
* Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is
@ -542,10 +603,10 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
/*!
* @brief Reads the RX data register using a blocking method.
* @brief Reads the receiver data register using a blocking method.
*
* This function polls the RX register, waits for the RX register full or RX FIFO
* has data then reads data from the TX register.
* This function polls the receiver register, waits for the receiver register full or receiver FIFO
* has data, and reads data from the TX register.
*
* @param base LPUART peripheral base address.
* @param data Start address of the buffer to store the received data.
@ -601,7 +662,7 @@ void LPUART_TransferCreateHandle(LPUART_Type *base,
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param xfer LPUART transfer structure, refer to #lpuart_transfer_t.
* @param xfer LPUART transfer structure, see #lpuart_transfer_t.
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register.
* @retval kStatus_InvalidArgument Invalid argument.
@ -631,7 +692,7 @@ void LPUART_TransferStartRingBuffer(LPUART_Type *base,
size_t ringBufferSize);
/*!
* @brief Abort the background transfer and uninstall the ring buffer.
* @brief Aborts the background transfer and uninstalls the ring buffer.
*
* This function aborts the background transfer and uninstalls the ring buffer.
*
@ -644,7 +705,7 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle);
* @brief Aborts the interrupt-driven data transmit.
*
* This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out
* how many bytes are still not sent out.
* how many bytes are not sent out.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
@ -652,10 +713,10 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle);
void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to LPUART TX register.
* @brief Gets the number of bytes that have been written to the LPUART transmitter register.
*
* This function gets the number of bytes that have been written to LPUART TX
* register by interrupt method.
* register by an interrupt method.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
@ -686,7 +747,7 @@ status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle,
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.
* @param xfer LPUART transfer structure, refer to #uart_transfer_t.
* @param xfer LPUART transfer structure, see #uart_transfer_t.
* @param receivedBytes Bytes received from the ring buffer directly.
* @retval kStatus_Success Successfully queue the transfer into the transmit queue.
* @retval kStatus_LPUART_RxBusy Previous receive request is not finished.
@ -709,7 +770,7 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle);
/*!
* @brief Get the number of bytes that have been received.
* @brief Gets the number of bytes that have been received.
*
* This function gets the number of bytes that have been received.
*

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -98,6 +98,8 @@ extern uint32_t LPUART_GetInstance(LPUART_Type *base);
static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
assert(param);
lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param;
/* Avoid the warning for unused variables. */
@ -118,6 +120,8 @@ static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool tra
static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
assert(param);
lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param;
/* Avoid warning for unused parameters. */
@ -138,11 +142,11 @@ static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool
}
void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle)
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle)
{
assert(handle);
@ -189,19 +193,18 @@ void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
EDMA_SetCallback(handle->rxEdmaHandle, LPUART_ReceiveEDMACallback, &s_edmaPrivateHandle[instance]);
}
}
status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer)
{
assert(handle);
assert(handle->txEdmaHandle);
assert(xfer);
assert(xfer->data);
assert(xfer->dataSize);
edma_transfer_config_t xferConfig;
status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous TX not finished. */
if (kLPUART_TxBusy == handle->txState)
{
@ -216,6 +219,9 @@ status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart
EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base),
sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral);
/* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
handle->nbytes = sizeof(uint8_t);
/* Submit transfer. */
EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->txEdmaHandle);
@ -231,17 +237,15 @@ status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart
status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer)
{
assert(handle);
assert(handle->rxEdmaHandle);
assert(xfer);
assert(xfer->data);
assert(xfer->dataSize);
edma_transfer_config_t xferConfig;
status_t status;
/* Return error if xfer invalid. */
if ((0U == xfer->dataSize) || (NULL == xfer->data))
{
return kStatus_InvalidArgument;
}
/* If previous RX not finished. */
if (kLPUART_RxBusy == handle->rxState)
{
@ -256,6 +260,9 @@ status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpu
EDMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data,
sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory);
/* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
handle->nbytes = sizeof(uint8_t);
/* Submit transfer. */
EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->rxEdmaHandle);
@ -271,6 +278,7 @@ status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpu
void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
{
assert(handle);
assert(handle->txEdmaHandle);
/* Disable LPUART TX EDMA. */
@ -284,6 +292,7 @@ void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handl
void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
{
assert(handle);
assert(handle->rxEdmaHandle);
/* Disable LPUART RX EDMA. */
@ -297,38 +306,36 @@ void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *ha
status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count)
{
assert(handle);
assert(handle->rxEdmaHandle);
assert(count);
if (kLPUART_RxIdle == handle->rxState)
{
return kStatus_NoTransferInProgress;
}
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->rxDataSizeAll - EDMA_GetRemainingBytes(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
*count = handle->rxDataSizeAll -
(uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel);
return kStatus_Success;
}
status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count)
{
assert(handle);
assert(handle->txEdmaHandle);
assert(count);
if (kLPUART_TxIdle == handle->txState)
{
return kStatus_NoTransferInProgress;
}
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->txDataSizeAll - EDMA_GetRemainingBytes(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
*count = handle->txDataSizeAll -
(uint32_t)handle->nbytes *
EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel);
return kStatus_Success;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
@ -39,8 +39,6 @@
* @{
*/
/*! @file*/
/*******************************************************************************
* Definitions
******************************************************************************/
@ -67,6 +65,8 @@ struct _lpuart_edma_handle
edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */
edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
volatile uint8_t txState; /*!< TX transfer state. */
volatile uint8_t rxState; /*!< RX transfer state */
};
@ -94,11 +94,11 @@ extern "C" {
* @param rxEdmaHandle User requested DMA handle for RX DMA transfer.
*/
void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle);
lpuart_edma_handle_t *handle,
lpuart_edma_transfer_callback_t callback,
void *userData,
edma_handle_t *txEdmaHandle,
edma_handle_t *rxEdmaHandle);
/*!
* @brief Sends data using eDMA.
@ -123,7 +123,7 @@ status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart
*
* @param base LPUART peripheral base address.
* @param handle Pointer to lpuart_edma_handle_t structure.
* @param xfer LPUART eDMA transfer structure, refer to #lpuart_transfer_t.
* @param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t.
* @retval kStatus_Success if succeed, others fail.
* @retval kStatus_LPUART_RxBusy Previous transfer ongoing.
* @retval kStatus_InvalidArgument Invalid argument.
@ -151,9 +151,9 @@ void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handl
void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle);
/*!
* @brief Get the number of bytes that have been written to LPUART TX register.
* @brief Gets the number of bytes written to the LPUART TX register.
*
* This function gets the number of bytes that have been written to LPUART TX
* This function gets the number of bytes written to the LPUART TX
* register by DMA.
*
* @param base LPUART peripheral base address.
@ -166,9 +166,9 @@ void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *ha
status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count);
/*!
* @brief Get the number of bytes that have been received.
* @brief Gets the number of received bytes.
*
* This function gets the number of bytes that have been received.
* This function gets the number of received bytes.
*
* @param base LPUART peripheral base address.
* @param handle LPUART handle pointer.