📄 mxc_nb_uart.c
字号:
/* * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//*! * @file mxc_nb_uart.c * * @brief UART code required for SPL of NANDboot to send and receive data to * terminal for user interaction. * * @ingroup NANDboot */#include "mxc_nb_uart.h"#ifdef MXC91231#include "../ipl/mxc_setup_mxc91231.h"#endif#ifdef MXC91331#include "../ipl/mxc_setup_mxc91331.h"#endif#ifdef MXC91131#include "../ipl/mxc_setup_mxc91131.h"#endif#ifdef MX31#include "../ipl/mxc_setup_mx31.h"#endif#ifdef MX21#include "../ipl/mxc_setup_mx21.h"#endif/*! * This function configures MXC UART and its I/O pins. In order to use UART, * IOMUX configuration is required. This function configures IOMUX pins used by * UART to send and receive the data. UART is configured in polling mode. The * transmitter FIFO is set to 2 characters and receiver to 1 characters. * * Refer to gpio.h in the respective MXC arch include directory for generating * the value of the IOMUX initialization constants for UART referred in this * function. */void mxcnb_uart_init(void){ volatile unsigned int *pMuxCtl, *pMuxComCtl; volatile unsigned short *pPBCCtl; volatile unsigned char dummy; volatile int i = 0; SETUP_IOMUX(); *DEBUG_ADDR0 = 0xAA00AA00;#if !(defined(MX31)||defined(MX21)) /* PBC setup */ pPBCCtl = (volatile unsigned short *)(PBC_BASE + 0x4); /*Enable UART transceivers also reset the Ethernet/external UART */ pPBCCtl = (volatile unsigned short *)(PBC_BASE + 0x4); *pPBCCtl = 0x005F; for (i = 0; i < 1000000; i++) { } pPBCCtl = (volatile unsigned short *)(PBC_BASE + 0x6); *pPBCCtl = 0x3; /*clear reset the Ethernet */ for (i = 0; i < 100000; i++) { }#endif /* config UART */#ifdef MX21 _reg_UCR2 = 0x61E6; _reg_UCR1= 0x0; _reg_UCR3 = 0x4; _reg_UCR4 = 0x8000; // configure appropriate pins for UART_1_RX, UART_1_TX, UART2_RX and UART2_TX _reg_UCR1 = 0x0005; // UARTEN = 1,enable the clock //UUCR2 = CTSC,TXEN,RXEN=1,reset, ignore IRTS bit, WS = 1 , //8 bit tx and rx,1 stop bit, disable parity _reg_UCR2 = 0x6026; _reg_UCR3 = 0x0004; _reg_UCR4 = 0x8000; // Set up reference freq divide for UART module // MX2 only support 16MHz output // PerCLK1(31.99998691MHz)/UFCR[RFDIV] (2)= 15.99999673MHz _reg_UFCR = 0x0A01; //clear loopback bit _reg_UTS = 0x0000; _reg_UBIR = 837; _reg_UBMR = 9999; // configure UBMR#else _reg_UCR1 = 1; /* Enable UART */ _reg_UCR2 = 0x4027; /* CTS high, Ignore RTS, Word=8, RX/TX Enb */#ifdef MX31 _reg_UCR3 = 0x704;#endif _reg_UFCR = UART_FIFO_CTRL; /* * The calculation: * (UMBR+1)/(UMIR+1) = RefFreq/(16*Baud) * Where: * RefFreq = PerClock / UART_RFDIV */ _reg_UBIR = MXC_UART_UBIR; _reg_UBMR = MXC_UART_UBMR;#endif/* end of MX21*/}/*! * This functions checks the Receive Data Ready bit in the UART Status * Register USR2. Bit is set when data is received. * * @return This function returns the RDR bit from the USR2 register * of UART * */U8 mxcnb_uart_dataready(void){ mxcnb_wd_reset(); return _reg_USR2 & RDR_MASK; /* check RDR bit */}/*! * This function gets data from UART. It is used to read character by * character of the options and data received by the UART * * @result It returns the character received by the UART * */ U8 mxcnb_uart_getdata(void){ /* wait until RDR bit set */ while (!mxcnb_uart_dataready()) { /* Do nothing */ mxcnb_wd_reset(); } return (U8)_reg_URXD;}/*! * This function sends data to UART. It waits for the transmit buffer to be * empty by checking TXFE bit in UART status register . If buffer is empty it * writes the character data into it. If carriage return character is found it * will append line-feed character. * * @param data character data to send to UART * */void mxcnb_uart_putdata(U8 data){ /* wait until TXFE bit set */ while (!(_reg_USR2 & TXFE_MASK)) { /* Do nothing */ } /* write the data to the TX register */ _reg_UTXD = (U16)data; /* if carriage return, append line-feed */ if (data == '\n') { /* wait until TXFE bit set */ while (!(_reg_USR2 & TXFE_MASK)) { /* Do nothing */ } _reg_UTXD = '\r'; }}/*! * This function sends hex data to UART. It takes 32 bit integer data, * converts it into ascii characters and sends it to UART. * * @param hex_data hex data to send to UART * */void mxcnb_uart_puthex(U32 hex_data){ U32 data; int i; for (i = 7; i >= 0; i--) { /* * Shift nibble at i+1 position to last position and * AND it with 0xF */ data = (hex_data >> 4*i)& 0xF; if (data > 9) { data += 'A' - 0xa; /* hex a to f to ascii 'A' to 'F' */ } else { data += '0'; /* hex 0 to 9 to ascii '0' to '9' */ } mxcnb_uart_putdata(data); /* send to UART */ }}/*! * This function sends a line of characters to UART. It calls * \b mxcnb_uart_putdata() function to send each character of the line till it * encounters the null character as the end of line. * * @param line pointer to string to be send to UART * */void mxcnb_uart_putstring(U8 *line){ while (*line) { mxcnb_uart_putdata(*(line++)); }}/*! * This function gets a string data from UART. It reads character by character * using \b mxcnb_uart_getdata() function. It takes char pointer as a parameter * where the characters of the string are copied * * @param str pointer to string data received by UART * * @return This function returns the size of the string read from UART. * */int mxcnb_uart_getstring(U8* str){ U8 ch; int i = 0; /* counter for size */ /* * loop until carriage return is pressed or MAX_STRLEN has reached */ do { /* wait for key press */ while (!mxcnb_uart_dataready()) { /* Do nothing */ } /* read the character received by UART */ ch = mxcnb_uart_getdata(); /* check if not carriage return */ if (ch != '\r') { /* check if back space */ if (ch == '\b') { if (i > 0) { /* erase the character */ mxcnb_uart_putdata('\b'); mxcnb_uart_putdata(' '); mxcnb_uart_putdata('\b'); str--; *str = 0; i--; } } else { mxcnb_uart_putdata(ch); *(str++) = ch; i++; } } } while ((ch != '\r') && (i < MAX_STRLEN - 1)); /* if and character is typed */ if (i > 0) { *(str++) = 0; /* mark end of string */ } return i; /* Size of string */}/*! * This function reads hex data from UART and stores at the char pointer * passed as a parameter. * * @param str pointer which points to ascii hex data * * @return This function returns -1 if incorrect hex data is entered or the * correct hex value entered. * */int mxcnb_uart_gethex(U8 * str){ int size, i = 0; U32 addr = 0; U8 tmp; /* get the ascii hex string from UART */ size = mxcnb_uart_getstring(str) - 1; /* hex value cannot be greater than 4 bytes or 8 nibbles */ if (size <= 7 ) { do { tmp = 0; if (str[size - i] >= '0' && str[size - i] <= '9') { tmp = str[size - i] - '0'; } else { if (str[size - i] >= (int)'a' && str[size - i] <= (int)'f') { tmp = (str[size - i] - 'a') + 0xa; } else { if (str[size - i] >= (int)'A' && str[size - i] <= (int)'F') { tmp = (str[size - i] - 'A') + 0xa; } else { /* error if not ascii hex */ return -1; } } } addr |= (tmp << (4 * i)); i++; } while ((size - i) >= 0); } else { return -1; /* error if more than 8 ascii hex */ } return addr;}#if UNIT_TEST/*! * This function is used for unit test of UART functions. It will be included * in the code only if UNIT_TEST is enabled. */void mxcnb_uart_unit_test(void){ /* U8* str = "Enter data: "; */ U8* test_str = (U8*)DEBUG_ADDR3; U32 hex; *(DEBUG_ADDR0 + 1) = 0xAA11AA11; /* to test 'mxcnb_uart_putdata' function */ mxcnb_uart_putdata('h'); mxcnb_uart_putdata('e'); mxcnb_uart_putdata('l'); mxcnb_uart_putdata('l'); mxcnb_uart_putdata('o'); mxcnb_uart_putdata('!'); mxcnb_uart_putdata('\n'); /* to test 'mxcnb_uart_putstring' function */ mxcnb_uart_putstring("\nEnter test data: "); /* to test 'mxcnb_uart_getdata' and 'mxcnb_uart_getstring'*/ mxcnb_uart_getstring(test_str); *(DEBUG_ADDR0 + 2) = 0xAA22AA22; /* reprint the string entered */ mxcnb_uart_putstring("\nYou entered: "); mxcnb_uart_putstring(test_str); /* to test 'mxcb_uart_gethex' and mxcb_uart_puthex' */ mxcnb_uart_putstring("\nEnter 4 bytes hex value: 0x"); hex = mxcnb_uart_gethex(test_str); /* reprint the hex value entered */ if (hex != -1) { mxcnb_uart_putstring("\n0x"); mxcnb_uart_puthex(hex); } else { mxcnb_uart_putstring("\nIncorrect hex value"); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -