Fuart在uboot下使用方法

  1. 将cmd_fuart.c放到uboot/common下,在Makefile里增加:obj-y += cmd_fuart.o

  2. 之后make即可在boot菜单下使用fuart命令测试。

    cmd_fuart.c代码如下:

    #include < common.h >  
    #include "linux/string.h"  
    #include "asm/arch/mach/ms_types.h"  
    #include "asm/arch/mach/platform.h"  
    #include "../arch/arm/cpu/armv7/infinity3/ms_serial.h"  
    //#include < stdlib.h >
    
    #define FUART_BASE 0x1F220400  //UART0_BASE 0x1F221000  
    #define FUART_REG8(_x_)  ((U8 volatile *)(FUART_BASE))[((_x_) * 4) - ((_x_) & 1)]  
    #define FUART_CHIPTOP_BASE 0x1F203C00  
    #define FUART_CHIPTOP_REG16(_x_) ((U16 volatile *)(FUART_CHIPTOP_BASE))[((_x_) * 2) ]  
    #define FUART_BAUDRATE_DEFAULT  115200  
    #define FUART_CLK CONFIG_UART_CLOCK  
    #define FUART_REGCLK_BASE 0x1F207000  
    #define FUART_REGCLK_REG16(_x_) ((U16 volatile *)(FUART_REGCLK_BASE))[((_x_) * 2) ]
    
    static void ms_fuart_setbrg (void)  
    {  
    //    // set baud_rate  
    //
    
        U16 DLR = ((FUART_CLK+8*FUART_BAUDRATE_DEFAULT)/ (16 * FUART_BAUDRATE_DEFAULT));
    
        //i.   Set "reg_mcr_loopback";  
        FUART_REG8(UART_MCR) |= 0x10;
    
        //  Clear FIFO Buffer  
        FUART_REG8(UART_FCR) |= 0x07;
    
        //ii.   Poll "reg_usr_busy" till 0;  
        while(FUART_REG8(UART_USR) & 0x01)  
        {  
            FUART_REG8(UART_IIR)=(FUART_REG8(UART_IIR)|(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));  
        }  
    //  
        FUART_REG8(UART_LCR) |= UART_LCR_DLAB;  
        FUART_REG8(UART_DLL) = (DLR & 0xFF);  
        FUART_REG8(UART_DLM) = ((DLR >> 8) & 0xFF);  
        FUART_REG8(UART_LCR) &= ~(UART_LCR_DLAB);  
    //  
        FUART_REG8(UART_MCR) &= ~0x10;  
    }
    
    static void ms_fuart_clk_enable(void)  
    {
    
        //printf("0x34 = 0x%04x\n",FUART_REGCLK_REG16(0x34));  
        FUART_REGCLK_REG16(0x34) &= (~0x01);  
    }  
    static void ms_faurt_select_pad(void)  
    {  
        if( FUART_BASE == 0x1F220400 ) //fuart  
        {  
            FUART_CHIPTOP_REG16(0x03) &= ~(0x3 << 4);  
            FUART_CHIPTOP_REG16(0x03) |= (0x2 << 4);   //pad_mode
    
            FUART_CHIPTOP_REG16(0x53) &= ~(0xf00);  
            FUART_CHIPTOP_REG16(0x53) |= 0x100;
    
            FUART_CHIPTOP_REG16(0x57) &= ~(0x1 << 1);  
            //printf("03=0x%04x ,53=0x%04x, 57=0x%04x",FUART_CHIPTOP_REG16(0x03),FUART_CHIPTOP_REG16(0x53),FUART_CHIPTOP_REG16(0x57));  
        }  
        else if( FUART_BASE == 0x1F221000 ){ //uart0  
            //FUART_CHIPTOP_REG8(0x06) &= (~0x30);  
            //FUART_CHIPTOP_REG8(0x06) |= 0x0;  
        }  
    }  
    static int ms_fuart_init(void)  
    {  
        ms_fuart_clk_enable();  //must first  
        //i.   Set "reg_mcr_loopback";  
        FUART_REG8(UART_MCR) |= 0x10;
    
        //ii.   Poll "reg_usr_busy" till 0;  
        while(FUART_REG8(UART_USR) & 0x01)  
        {  
            FUART_REG8(UART_IIR)=(FUART_REG8(UART_IIR)|(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));  
        }  
        printf("2");  
        FUART_REG8(UART_IER) = 0x00;
    
        // Reset receiver and transmiter  
        FUART_REG8(UART_FCR) = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_1;
    
        // Set 8 bit char, 1 stop bit, no parity  
        FUART_REG8(UART_LCR) = UART_LCR_WLEN8 & ~(UART_LCR_STOP2 | UART_LCR_PARITY);
    
        //i.   Set "reg_mcr_loopback back;  
        FUART_REG8(UART_MCR) &= ~0x10;
    
        ms_fuart_setbrg();  
        ms_faurt_select_pad();
    
        return (0);  
    }
    
    static void ms_fuart_serial_putc(const char c)  
    {  
        while (!(FUART_REG8(UART_LSR) & UART_LSR_THRE));
    
        FUART_REG8(UART_TX) = c;
    
    }
    
    static void ms_fuart_putc (const char c)  
    {  
        if (c == '\n')  
            ms_fuart_serial_putc('\r');
    
        ms_fuart_serial_putc(c);  
    }
    
    static char ms_fuart_getc (void)  
    {  
        char c;  
    //  
        while(!(FUART_REG8(UART_LSR) & UART_LSR_DR));
    
        c=(char) ( FUART_REG8(UART_TX) & 0xff);
    
        return c;  
    }
    
    /*
    static int ms_fuart_tstc (void)  
    {  
        return  ((FUART_REG8(UART_LSR) & UART_LSR_DR));  
    }  
    */
    
    static void ms_fuart_help(void)  
    {  
        printf("do_fuart tx strins\n");  
        printf("do_fuart rx number\n");  
    }
    
    static int do_fuart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  
    {  
        int i=0,len = 0;
    
        printf("doing fuart service for you:\n");  
        if(argc!=3){ms_fuart_help();return 0;}
    
        ms_fuart_init();  
        if(0 == strcmp(argv[1],"tx"))  
        {  
            len = strlen(argv[2]);  
            for(i=0;i<len;i++){
    
                ms_fuart_putc(*(argv[2]+i));  
            }  
            return 0;  
        }  
        else if(0 == strcmp(argv[1],"rx"))  
        {  
            //len = atoi(argv[2]);  
            len=10;  
            for(i=0;i<len;i++){  
                printf(" %c",ms_fuart_getc());  
            }  
            printf("\n");  
            return 0;  
        }  
        else {  
            ms_fuart_help();  
        }  
        return 0;  
    }  
    U_BOOT_CMD(  
        fuart, CONFIG_SYS_MAXARGS , 1 ,do_fuart,  
        "use fuart_tx & fuart_rx as transmission",  
        "20180713"  
    );