⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 AT91RM9200的完整启动代码:包括loader, boot及U-boot三部分均已编译通过!欢迎下载使用!
💻 C
字号:
/* * (INCA) ASC UART support */#include <config.h>#ifdef CONFIG_PURPLE#define	serial_init	asc_serial_init#define	serial_putc	asc_serial_putc#define	serial_puts	asc_serial_puts#define	serial_getc	asc_serial_getc#define	serial_tstc	asc_serial_tstc#define	serial_setbrg	asc_serial_setbrg#endif#include <common.h>#include <asm/inca-ip.h>#include "serial.h"#ifdef CONFIG_PURPLE#undef ASC_FIFO_PRESENT#define TOUT_LOOP	100000/* Set base address for second FPI interrupt control register bank */#define SFPI_INTCON_BASEADDR	0xBF0F0000 /* Register offset from base address */#define FBS_ISR		0x00000000	/* Interrupt status register */#define FBS_IMR		0x00000008	/* Interrupt mask register */#define FBS_IDIS	0x00000010	/* Interrupt disable register *//* Interrupt status register bits */#define FBS_ISR_AT	0x00000040	/* ASC transmit interrupt */#define FBS_ISR_AR 	0x00000020	/* ASC receive interrupt */#define FBS_ISR_AE	0x00000010	/* ASC error interrupt */#define FBS_ISR_AB	0x00000008	/* ASC transmit buffer interrupt */#define FBS_ISR_AS      0x00000004 	/* ASC start of autobaud detection interrupt */#define FBS_ISR_AF	0x00000002	/* ASC end of autobaud detection interrupt */#else#define ASC_FIFO_PRESENT#endif#define SET_BIT(reg, mask)                  reg |= (mask)#define CLEAR_BIT(reg, mask)                reg &= (~mask)#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask)#define SET_BITS(reg, mask)                 SET_BIT(reg, mask)#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);}extern uint incaip_get_fpiclk(void);static int serial_setopt (void);/* pointer to ASC register base address */static volatile incaAsc_t *pAsc = (incaAsc_t *)INCA_IP_ASC;/******************************************************************************** serial_init - initialize a INCAASC channel** This routine initializes the number of data bits, parity* and set the selected baud rate. Interrupts are disabled.* Set the modem control signals if the option is selected.** RETURNS: N/A*/int serial_init (void){#ifdef CONFIG_INCA_IP    /* we have to set PMU.EN13 bit to enable an ASC device*/    INCAASC_PMU_ENABLE(13);#endif        /* and we have to set CLC register*/    CLEAR_BIT(pAsc->asc_clc, ASCCLC_DISS);    SET_BITFIELD(pAsc->asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001);        /* initialy we are in async mode */    pAsc->asc_con = ASCCON_M_8ASYNC;    /* select input port */    pAsc->asc_pisel = (CONSOLE_TTY & 0x1);#ifdef ASC_FIFO_PRESENT    /* TXFIFO's filling level */    SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK,                    ASCTXFCON_TXFITLOFF, INCAASC_TXFIFO_FL);    /* enable TXFIFO */    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN);    /* RXFIFO's filling level */    SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,                     ASCRXFCON_RXFITLOFF, INCAASC_RXFIFO_FL);    /* enable RXFIFO */    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN);#endif    /* enable error signals */    SET_BIT(pAsc->asc_con, ASCCON_FEN);    SET_BIT(pAsc->asc_con, ASCCON_OEN);#ifdef CONFIG_INCA_IP    /* acknowledge ASC interrupts */    ASC_INTERRUPTS_CLEAR(INCAASC_IRQ_LINE_ALL);    /* disable ASC interrupts */    ASC_INTERRUPTS_DISABLE(INCAASC_IRQ_LINE_ALL);#endif#ifdef ASC_FIFO_PRESENT    /* set FIFOs into the transparent mode */    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXTMEN);    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXTMEN);#endif    /* set baud rate */    serial_setbrg();    /* set the options */    serial_setopt();        return 0;}void serial_setbrg (void){    ulong      uiReloadValue, fdv;    ulong      f_ASC;#ifdef CONFIG_INCA_IP    f_ASC = incaip_get_fpiclk();#else    f_ASC = ASC_CLOCK_RATE;#endif#ifndef INCAASC_USE_FDV    fdv = 2;    uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;#else     fdv = INCAASC_FDV_HIGH_BAUDRATE;    uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;#endif /* INCAASC_USE_FDV */        if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )    {#ifndef INCAASC_USE_FDV        fdv = 3;        uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;#else         fdv = INCAASC_FDV_LOW_BAUDRATE;        uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;#endif /* INCAASC_USE_FDV */                if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )        {            return;    /* can't impossibly generate that baud rate */        }    }    /* Disable Baud Rate Generator; BG should only be written when R=0 */    CLEAR_BIT(pAsc->asc_con, ASCCON_R);#ifndef INCAASC_USE_FDV    /*     * Disable Fractional Divider (FDE)     * Divide clock by reload-value + constant (BRS)     */    /* FDE = 0 */    CLEAR_BIT(pAsc->asc_con, ASCCON_FDE);    if ( fdv == 2 )        CLEAR_BIT(pAsc->asc_con, ASCCON_BRS);   /* BRS = 0 */    else        SET_BIT(pAsc->asc_con, ASCCON_BRS); /* BRS = 1 */#else /* INCAASC_USE_FDV */    /* Enable Fractional Divider */    SET_BIT(pAsc->asc_con, ASCCON_FDE); /* FDE = 1 */    /* Set fractional divider value */    pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK;#endif /* INCAASC_USE_FDV */    /* Set reload value in BG */    pAsc->asc_bg = uiReloadValue;    /* Enable Baud Rate Generator */    SET_BIT(pAsc->asc_con, ASCCON_R);           /* R = 1 */}/********************************************************************************* serial_setopt - set the serial options** Set the channel operating mode to that specified. Following options* are supported: CREAD, CSIZE, PARENB, and PARODD.** Note, this routine disables the transmitter.  The calling routine* may have to re-enable it.** RETURNS:* Returns 0 to indicate success, otherwise -1 is returned*/static int serial_setopt (void){    ulong  con;    switch ( ASC_OPTIONS & ASCOPT_CSIZE )    {    /* 7-bit-data */    case ASCOPT_CS7:        con = ASCCON_M_7ASYNCPAR;   /* 7-bit-data and parity bit */        break;    /* 8-bit-data */    case ASCOPT_CS8:        if ( ASC_OPTIONS & ASCOPT_PARENB )            con = ASCCON_M_8ASYNCPAR;   /* 8-bit-data and parity bit */        else            con = ASCCON_M_8ASYNC;      /* 8-bit-data no parity */        break;        /*      *  only 7 and 8-bit frames are supported     *  if we don't use IOCTL extensions      */    default:        return -1;    }    if ( ASC_OPTIONS & ASCOPT_STOPB )        SET_BIT(con, ASCCON_STP);       /* 2 stop bits */    else        CLEAR_BIT(con, ASCCON_STP);     /* 1 stop bit */    if ( ASC_OPTIONS & ASCOPT_PARENB )        SET_BIT(con, ASCCON_PEN);           /* enable parity checking */        else        CLEAR_BIT(con, ASCCON_PEN);         /* disable parity checking */        if ( ASC_OPTIONS & ASCOPT_PARODD )        SET_BIT(con, ASCCON_ODD);       /* odd parity */    else        CLEAR_BIT(con, ASCCON_ODD);     /* even parity */    if ( ASC_OPTIONS & ASCOPT_CREAD )        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_SETREN); /* Receiver enable */    pAsc->asc_con |= con;    return 0;}void serial_putc (const char c){#ifdef ASC_FIFO_PRESENT    uint txFl = 0;#else    uint timeout = 0;#endif    if (c == '\n') serial_putc ('\r');#ifdef ASC_FIFO_PRESENT    /* check do we have a free space in the TX FIFO */    /* get current filling level */    do    {	txFl = ( pAsc->asc_fstat & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF;    }    while ( txFl == INCAASC_TXFIFO_FULL );#else    while(!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &			   FBS_ISR_AB))    {	    if (timeout++ > TOUT_LOOP)	    {		    break;	    }    }#endif    pAsc->asc_tbuf = c; /* write char to Transmit Buffer Register */#ifndef ASC_FIFO_PRESENT    *(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) = FBS_ISR_AB |                                                                 FBS_ISR_AT;#endif        /* check for errors */    if ( pAsc->asc_con & ASCCON_OE )    {        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);        return;    }}void serial_puts (const char *s){    while (*s)    {	serial_putc (*s++);    }}int serial_getc (void){    ulong symbol_mask;    char c;    while (!serial_tstc());    symbol_mask =	((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff);        c = (char)(pAsc->asc_rbuf & symbol_mask);#ifndef ASC_FIFO_PRESENT    *(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) = FBS_ISR_AR;#endif    return c;}int serial_tstc (void){    int res = 1;#ifdef ASC_FIFO_PRESENT    if ( (pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 )    {        res = 0;    }#else    if (!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &			    					FBS_ISR_AR))        {        res = 0;    }#endif    else if ( pAsc->asc_con & ASCCON_FE )    {        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRFE);        res = 0;    }    else if ( pAsc->asc_con & ASCCON_PE )    {        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRPE);        res = 0;    }    else if ( pAsc->asc_con & ASCCON_OE )    {        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);        res = 0;    }    return res;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -