diff options
Diffstat (limited to 'platform/drivers/src/uart_imx.c')
-rw-r--r-- | platform/drivers/src/uart_imx.c | 601 |
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 + ******************************************************************************/ |