summaryrefslogtreecommitdiff
path: root/platform/drivers/src/uart_imx.c
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2016-01-12 14:06:54 -0800
committerStefan Agner <stefan.agner@toradex.com>2016-01-12 14:06:54 -0800
commita57cc2c988482010061b9e68344fdf1969889763 (patch)
tree5c050337492ce27c09b47421b123980b5a79f8d9 /platform/drivers/src/uart_imx.c
initial commit, FreeRTOS_BSP_1.0.0_iMX7D
Diffstat (limited to 'platform/drivers/src/uart_imx.c')
-rw-r--r--platform/drivers/src/uart_imx.c601
1 files changed, 601 insertions, 0 deletions
diff --git a/platform/drivers/src/uart_imx.c b/platform/drivers/src/uart_imx.c
new file mode 100644
index 0000000..3c5149d
--- /dev/null
+++ b/platform/drivers/src/uart_imx.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * 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
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "uart_imx.h"
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Initialization and Configuration functions
+ ******************************************************************************/
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_Init
+ * Description : This function initializes the module according to uart
+ * initialize structure.
+ *
+ *END**************************************************************************/
+void UART_Init(UART_Type* base, uart_init_config_t* initConfig)
+{
+ assert(initConfig);
+
+ /* Disable UART Module. */
+ UART_UCR1_REG(base) &= ~UART_UCR1_UARTEN_MASK;
+
+ /* Reset UART register to its default value. */
+ UART_Deinit(base);
+
+ /* Set UART data word length, stop bit count, parity mode and communication
+ * direction according to uart init struct, disable RTS hardware flow
+ * control. */
+ UART_UCR2_REG(base) |= (initConfig->wordLength |
+ initConfig->stopBitNum |
+ initConfig->parity |
+ initConfig->direction |
+ UART_UCR2_IRTS_MASK);
+
+ /* For imx family device, UARTs are used in MUXED mode,
+ * so that this bit should always be set.*/
+ UART_UCR3_REG(base) |= UART_UCR3_RXDMUXSEL_MASK;
+
+ /* Set BaudRate according to uart initialize struct. */
+ /* Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)) */
+ UART_SetBaudRate(base, initConfig->clockRate, initConfig->baudRate);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_Deinit
+ * Description : This function reset Uart module register content to its
+ * default value.
+ *
+ *END**************************************************************************/
+void UART_Deinit(UART_Type* base)
+{
+ /* Disable UART Module */
+ UART_UCR1_REG(base) &= ~UART_UCR1_UARTEN_MASK;
+
+ /* Reset UART Module Register content to default value */
+ UART_UCR1_REG(base) = 0x00000000;
+ UART_UCR2_REG(base) = 0x00000001;
+ UART_UCR3_REG(base) = 0x00000700;
+ UART_UCR4_REG(base) = 0x00008000;
+ UART_UFCR_REG(base) = 0x00000801;
+ UART_UESC_REG(base) = 0x0000002B;
+ UART_UTIM_REG(base) = 0x00000000;
+ UART_ONEMS_REG(base) = 0x00000000;
+ UART_UTS_REG(base) = 0x00000060;
+ UART_UMCR_REG(base) = 0x00000000;
+
+ /* Reset the transmit and receive state machines, all FIFOs and register
+ * USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD and UTS[6-3]. */
+ UART_UCR2_REG(base) &= ~UART_UCR2_SRST_MASK;
+ while (!(UART_UCR2_REG(base) & UART_UCR2_SRST_MASK));
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetBaudRate
+ * Description :
+ *
+ *END**************************************************************************/
+void UART_SetBaudRate(UART_Type* base, uint32_t clockRate, uint32_t baudRate)
+{
+ uint32_t numerator;
+ uint32_t denominator;
+ uint32_t divisor;
+ uint32_t refFreqDiv;
+ uint32_t divider = 1;
+
+ /* get the approximately maximum divisor */
+ numerator = clockRate;
+ denominator = baudRate << 4;
+ divisor = 1;
+
+ while (denominator != 0)
+ {
+ divisor = denominator;
+ denominator = numerator % denominator;
+ numerator = divisor;
+ }
+
+ numerator = clockRate / divisor;
+ denominator = (baudRate << 4) / divisor;
+
+ /* numerator ranges from 1 ~ 7 * 64k */
+ /* denominator ranges from 1 ~ 64k */
+ if ((numerator > (UART_UBIR_INC_MASK * 7)) ||
+ (denominator > UART_UBIR_INC_MASK))
+ {
+ uint32_t m = (numerator - 1) / (UART_UBIR_INC_MASK * 7) + 1;
+ uint32_t n = (denominator - 1) / UART_UBIR_INC_MASK + 1;
+ uint32_t max = m > n ? m : n;
+ numerator /= max;
+ denominator /= max;
+ if (0 == numerator)
+ numerator = 1;
+ if (0 == denominator)
+ denominator = 1;
+ }
+ divider = (numerator - 1) / UART_UBIR_INC_MASK + 1;
+
+ switch (divider)
+ {
+ case 1:
+ refFreqDiv = 0x05;
+ break;
+ case 2:
+ refFreqDiv = 0x04;
+ break;
+ case 3:
+ refFreqDiv = 0x03;
+ break;
+ case 4:
+ refFreqDiv = 0x02;
+ break;
+ case 5:
+ refFreqDiv = 0x01;
+ break;
+ case 6:
+ refFreqDiv = 0x00;
+ break;
+ case 7:
+ refFreqDiv = 0x06;
+ break;
+ default:
+ refFreqDiv = 0x05;
+ }
+
+ UART_UFCR_REG(base) &= ~UART_UFCR_RFDIV_MASK;
+ UART_UFCR_REG(base) |= UART_UFCR_RFDIV(refFreqDiv);
+ UART_UBIR_REG(base) = UART_UBIR_INC(denominator - 1);
+ UART_UBMR_REG(base) = UART_UBMR_MOD(numerator / divider - 1);
+ UART_ONEMS_REG(base) = UART_ONEMS_ONEMS(clockRate/(1000 * refFreqDiv));
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetInvertCmd
+ * Description : This function is used to set the polarity of UART signal.
+ * The polarity of Tx and Rx can be set separately.
+ *
+ *END**************************************************************************/
+void UART_SetInvertCmd(UART_Type* base, uint32_t direction, bool invert)
+{
+ assert((direction & uartDirectionTx) || (direction & uartDirectionRx));
+
+ if (invert)
+ {
+ if (direction & UART_UCR2_RXEN_MASK)
+ UART_UCR4_REG(base) |= UART_UCR4_INVR_MASK;
+ if (direction & UART_UCR2_TXEN_MASK)
+ UART_UCR3_REG(base) |= UART_UCR3_INVT_MASK;
+ }
+ else
+ {
+ if (direction & UART_UCR2_RXEN_MASK)
+ UART_UCR4_REG(base) &= ~UART_UCR4_INVR_MASK;
+ if (direction & UART_UCR2_TXEN_MASK)
+ UART_UCR3_REG(base) &= ~UART_UCR3_INVT_MASK;
+ }
+}
+
+/*******************************************************************************
+ * Low Power Mode functions
+ ******************************************************************************/
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetDozeMode
+ * Description : This function is used to set UART enable condition in the
+ * DOZE state.
+ *
+ *END**************************************************************************/
+void UART_SetDozeMode(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UCR1_REG(base) &= UART_UCR1_DOZE_MASK;
+ else
+ UART_UCR1_REG(base) |= ~UART_UCR1_DOZE_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetLowPowerMode
+ * Description : This function is used to set UART enable condition of the
+ * UART low power feature.
+ *
+ *END**************************************************************************/
+void UART_SetLowPowerMode(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UCR4_REG(base) &= ~UART_UCR4_LPBYP_MASK;
+ else
+ UART_UCR4_REG(base) |= UART_UCR4_LPBYP_MASK;
+}
+
+/*******************************************************************************
+ * Interrupt and Flag control functions
+ ******************************************************************************/
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetIntCmd
+ * Description : This function is used to set the enable condition of
+ * specific UART interrupt source. The available interrupt
+ * source can be select from uart_int_source enumeration.
+ *
+ *END**************************************************************************/
+void UART_SetIntCmd(UART_Type* base, uint32_t intSource, bool enable)
+{
+ volatile uint32_t* uart_reg = 0;
+ uint32_t uart_mask = 0;
+
+ uart_reg = (uint32_t *)((uint32_t)base + (intSource >> 16));
+ uart_mask = (1 << (intSource & 0x0000FFFF));
+
+ if (enable)
+ *uart_reg |= uart_mask;
+ else
+ *uart_reg &= ~uart_mask;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_GetStatusFlag
+ * Description : This function is used to get the current status of specific
+ * UART status flag. The available status flag can be select
+ * from uart_status_flag & uart_interrupt_flag enumeration.
+ *
+ *END**************************************************************************/
+bool UART_GetStatusFlag(UART_Type* base, uint32_t flag)
+{
+ volatile uint32_t* uart_reg = 0;
+
+ uart_reg = (uint32_t *)((uint32_t)base + (flag >> 16));
+ return (bool)((*uart_reg >> (flag & 0x0000FFFF)) & 0x1);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_ClearStatusFlag
+ * Description : This function is used to get the current status
+ * of specific UART status flag. The available status
+ * flag can be select from uart_status_flag &
+ * uart_interrupt_flag enumeration.
+ *
+ *END**************************************************************************/
+void UART_ClearStatusFlag(UART_Type* base, uint32_t flag)
+{
+ volatile uint32_t* uart_reg = 0;
+ uint32_t uart_mask = 0;
+
+ uart_reg = (uint32_t *)((uint32_t)base + (flag >> 16));
+ uart_mask = (1 << (flag & 0x0000FFFF));
+
+ /* write 1 to clear. */
+ *uart_reg |= uart_mask;
+}
+
+/*******************************************************************************
+ * DMA control functions
+ ******************************************************************************/
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetDmaCmd
+ * Description : This function is used to set the enable condition of
+ * specific UART DMA source. The available DMA
+ * source can be select from uart_dma_source enumeration.
+ *
+ *END**************************************************************************/
+void UART_SetDmaCmd(UART_Type* base, uint32_t dmaSource, bool enable)
+{
+ volatile uint32_t* uart_reg = 0;
+ uint32_t uart_mask = 0;
+
+ uart_reg = (uint32_t *)((uint32_t)base + (dmaSource >> 16));
+ uart_mask = (1 << (dmaSource & 0x0000FFFF));
+ if (enable)
+ *uart_reg |= uart_mask;
+ else
+ *uart_reg &= ~uart_mask;
+}
+
+/*******************************************************************************
+ * Hardware Flow control and Modem Signal functions
+ ******************************************************************************/
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetRtsFlowCtrlCmd
+ * Description : This function is used to set the enable condition of RTS
+ * Hardware flow control.
+ *
+ *END**************************************************************************/
+void UART_SetRtsFlowCtrlCmd(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UCR2_REG(base) &= ~UART_UCR2_IRTS_MASK;
+ else
+ UART_UCR2_REG(base) |= UART_UCR2_IRTS_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetCtsFlowCtrlCmd
+ * Description : This function is used to set the enable condition of CTS
+ * auto control. if CTS control is enabled, the CTS_B pin will
+ * be controlled by the receiver, otherwise the CTS_B pin will
+ * controlled by UART_CTSPinCtrl function.
+ *
+ *END**************************************************************************/
+void UART_SetCtsFlowCtrlCmd(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UCR2_REG(base) |= UART_UCR2_CTSC_MASK;
+ else
+ UART_UCR2_REG(base) &= ~UART_UCR2_CTSC_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetCtsPinLevel
+ * Description : This function is used to control the CTS_B pin state when
+ * auto CTS control is disabled.
+ * The CTS_B pin is low(active)
+ * The CTS_B pin is high(inactive)
+ *
+ *END**************************************************************************/
+void UART_SetCtsPinLevel(UART_Type* base, bool active)
+{
+ if (active)
+ UART_UCR2_REG(base) |= UART_UCR2_CTS_MASK;
+ else
+ UART_UCR2_REG(base) &= ~UART_UCR2_CTS_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetModemMode
+ * Description : This function is used to set the role(DTE/DCE) of UART module
+ * in RS-232 communication.
+ *
+ *END**************************************************************************/
+void UART_SetModemMode(UART_Type* base, uint32_t mode)
+{
+ assert((uartModemModeDce & uartModemModeDce) || (uartModemModeDce & uartModemModeDte));
+ if (uartModemModeDce == mode)
+ UART_UFCR_REG(base) &= ~UART_UFCR_DCEDTE_MASK;
+ else
+ UART_UFCR_REG(base) |= UART_UFCR_DCEDTE_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetDtrPinLevel
+ * Description : This function is used to set the pin state of
+ * DSR pin(for DCE mode) or DTR pin(for DTE mode) for the
+ * modem interface.
+ *
+ *END**************************************************************************/
+void UART_SetDtrPinLevel(UART_Type* base, bool active)
+{
+ if (active)
+ UART_UCR3_REG(base) |= UART_UCR3_DSR_MASK;
+ else
+ UART_UCR3_REG(base) &= ~UART_UCR3_DSR_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetDcdPinLevel
+ * Description : This function is used to set the pin state of
+ * DCD pin. THIS FUNCTION IS FOR DCE MODE ONLY.
+ *
+ *END**************************************************************************/
+void UART_SetDcdPinLevel(UART_Type* base, bool active)
+{
+ if (active)
+ UART_UCR3_REG(base) |= UART_UCR3_DCD_MASK;
+ else
+ UART_UCR3_REG(base) &= ~UART_UCR3_DCD_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetRiPinLevel
+ * Description : This function is used to set the pin state of
+ * RI pin. THIS FUNCTION IS FOR DCE MODE ONLY.
+ *
+ *END**************************************************************************/
+void UART_SetRiPinLevel(UART_Type* base, bool active)
+{
+ if (active)
+ UART_UCR3_REG(base) |= UART_UCR3_RI_MASK;
+ else
+ UART_UCR3_REG(base) &= ~UART_UCR3_RI_MASK;
+}
+
+/*******************************************************************************
+ * Multi-processor and RS-485 functions
+ ******************************************************************************/
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UAER_Putchar9
+ * Description : This function is used to send 9 Bits length data in
+ * RS-485 Multidrop mode.
+ *
+ *END**************************************************************************/
+void UAER_Putchar9(UART_Type* base, uint16_t data)
+{
+ assert(data <= 0x1FF);
+
+ if (data & 0x0100)
+ UART_UMCR_REG(base) |= UART_UMCR_TXB8_MASK;
+ else
+ UART_UMCR_REG(base) &= ~UART_UMCR_TXB8_MASK;
+ UART_UTXD_REG(base) = (data & UART_UTXD_TX_DATA_MASK);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UAER_Getchar9
+ * Description : This functions is used to receive 9 Bits length data in
+ * RS-485 Multidrop mode.
+ *
+ *END**************************************************************************/
+uint16_t UAER_Getchar9(UART_Type* base)
+{
+ uint16_t rxData = 0;
+
+ if (UART_URXD_REG(base) & UART_URXD_PRERR_MASK)
+ rxData |= 0x0100;
+ rxData |= (UART_URXD_REG(base) & UART_URXD_RX_DATA_MASK);
+ return rxData;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetMultidropMode
+ * Description : This function is used to set the enable condition of
+ * 9-Bits data or Multidrop mode.
+ *
+ *END**************************************************************************/
+void UART_SetMultidropMode(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UMCR_REG(base) |= UART_UMCR_MDEN_MASK;
+ else
+ UART_UMCR_REG(base) &= ~UART_UMCR_MDEN_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetSlaveAddressDetectCmd
+ * Description : This function is used to set the enable condition of
+ * Automatic Address Detect Mode.
+ *
+ *END**************************************************************************/
+void UART_SetSlaveAddressDetectCmd(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UMCR_REG(base) |= UART_UMCR_SLAM_MASK;
+ else
+ UART_UMCR_REG(base) &= ~UART_UMCR_SLAM_MASK;
+}
+
+/*******************************************************************************
+ * IrDA control functions
+ ******************************************************************************/
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetIrDACmd
+ * Description : This function is used to set the enable condition of
+ * IrDA Mode.
+ *
+ *END**************************************************************************/
+void UART_SetIrDACmd(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UCR1_REG(base) |= UART_UCR1_IREN_MASK;
+ else
+ UART_UCR1_REG(base) &= ~UART_UCR1_IREN_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetIrDAVoteClock
+ * Description : This function is used to set the clock for the IR pulsed
+ * vote logic. The available clock can be select from
+ * uart_irda_vote_clock enumeration.
+ *
+ *END**************************************************************************/
+void UART_SetIrDAVoteClock(UART_Type* base, uint32_t voteClock)
+{
+ assert((voteClock == uartIrdaVoteClockSampling) || \
+ (voteClock == uartIrdaVoteClockReference));
+
+ if (uartIrdaVoteClockSampling == voteClock)
+ UART_UCR4_REG(base) |= UART_UCR4_IRSC_MASK;
+ else
+ UART_UCR4_REG(base) &= ~UART_UCR4_IRSC_MASK;
+}
+
+/*******************************************************************************
+ * Misc. functions
+ ******************************************************************************/
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetAutoBaudRateCmd
+ * Description : This function is used to set the enable condition of
+ * Automatic Baud Rate Detection feature.
+ *
+ *END**************************************************************************/
+void UART_SetAutoBaudRateCmd(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UCR1_REG(base) |= UART_UCR1_ADBR_MASK;
+ else
+ UART_UCR1_REG(base) &= ~UART_UCR1_ADBR_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SendBreakChar
+ * Description : This function is used to send BREAK character.It is
+ * important that SNDBRK is asserted high for a sufficient
+ * period of time to generate a valid BREAK.
+ *
+ *END**************************************************************************/
+void UART_SendBreakChar(UART_Type* base, bool active)
+{
+ if (active)
+ UART_UCR1_REG(base) |= UART_UCR1_SNDBRK_MASK;
+ else
+ UART_UCR1_REG(base) &= ~UART_UCR1_SNDBRK_MASK;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : UART_SetEscapeDecectCmd
+ * Description : This function is used to set the enable condition of
+ * Escape Sequence Detection feature.
+ *
+ *END**************************************************************************/
+void UART_SetEscapeDecectCmd(UART_Type* base, bool enable)
+{
+ if (enable)
+ UART_UCR2_REG(base) |= UART_UCR2_ESCEN_MASK;
+ else
+ UART_UCR2_REG(base) &= ~UART_UCR2_ESCEN_MASK;
+}
+
+/*******************************************************************************
+ * EOF
+ ******************************************************************************/