Fuart在uboot下使用方法
-
将cmd_fuart.c放到uboot/common下,在Makefile里增加:obj-y += cmd_fuart.o
-
之后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" );