ser_mcf5272_uart.c

来自「eCos操作系统源码」· C语言 代码 · 共 947 行 · 第 1/3 页

C
947
字号
    chan - pointer to the serial private data. RETURN:    the character read from the UART. */static unsigned char MCF5272_uart_getc(serial_channel *chan){    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *)chan->dev_priv;    /* Wait until character has been received */	while (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_RXRDY))    {        diag_printf("ready poll");    }    /* Read the character from the FIFO queue. */	    return MCF5272_UART_READ(port->base->urf);}/******************************************************************************* MCF5272_uart_set_config() - Set up the device characteristics; baud rate, etc. INPUT:    chan - pointer to the serial private data.    key  - configuration key (command).    xbuf - pointer to the configuration buffer    len  - the length of the configuration buffer RETURN:    NOERR - If the configuration is successful    EINVAL -  If the argument is invalid*/Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,                            const void *xbuf, cyg_uint32 *len){    cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;    switch (key) {    case CYG_IO_SET_CONFIG_SERIAL_INFO:      {          /* Set serial configuration. */              if ( *len < sizeof(cyg_serial_info_t) ) {              return EINVAL;          }          *len = sizeof(cyg_serial_info_t);          if (!MCF5272_uart_config_port(chan, config))              return EINVAL;      }      break;    case CYG_IO_GET_CONFIG_SERIAL_INFO:        // Retrieve UART configuration        *config = port->config;        break;    default:        return EINVAL;    }    return ENOERR;}/*******************************************************************************  MCF5272_uart_start_xmit() - Enable the transmitter on the device.  INPUT:    chan - pointer to the serial private data.*/static void MCF5272_uart_start_xmit(serial_channel *chan){    CYG_INTERRUPT_STATE int_state;    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;    /* Enable the UART transmit. */    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXEN);    /* Enable transmit interrupt */    HAL_DISABLE_INTERRUPTS(int_state);    port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);    HAL_RESTORE_INTERRUPTS(int_state);}/****************************************************************************************************** MCF5272_uart_stop_xmit() - Disable the transmitter on the device INPUT:    chan - pointer to the serial private data.*/static void MCF5272_uart_stop_xmit(serial_channel * chan){	   CYG_INTERRUPT_STATE int_state;   MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;   /* Disable transmit interrupt */   HAL_DISABLE_INTERRUPTS(int_state);   port->imr_mirror &= ~MCF5272_UART_UIMR_TXRDY;   MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);   HAL_RESTORE_INTERRUPTS(int_state);   /* Disable the UART transmit.      !!!!!!!!!!!!!      !!!WARNING!!!      !!!!!!!!!!!!!      If the transmit the disabe      the diag_printf routines will poll forever to transmit the      a character. Hence, don't ever disable the transmit if      we want it to work with diag_printf.   */   //MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXDE);}/****************************************************************************************************** MCF5272_uart_ISR() - UART I/O interrupt interrupt service routine (ISR). INPUT:    vector - the interrupt vector number    data   - user parameter. RETURN:     returns CYG_ISR_CALL_DSR to call the DSR. */static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data){    serial_channel *chan = (serial_channel *) data;    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;    /* Write the value in the interrupt status register back       to the mask register to disable the interrupt temporarily.     */    MCF5272_UART_WRITE(port->base->uisr_uimr, 0);    return CYG_ISR_CALL_DSR;  // Cause DSR to run}/****************************************************************************************************** MCF5272_uart_DSR() - Defered Service Routine (DSR) - This routine processes the interrupt                      from the device. INPUT:    vector - The interrupt vector number    count  - The nunber of DSR requests.    data   - Device specific information*/static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    MCF5272_uart_info_t *port = (MCF5272_uart_info_t *)chan->dev_priv;    volatile u8_t isr;    /* Retrieve the interrupt status bits. We use these status bits to figure out       what process shouled we perform: read from the UART or inform of a completion       of a data transmission.    */    /* Retrieve the interrupt status register so     * the DSR can look it up.     */    while((isr = (MCF5272_UART_READ(port->base->uisr_uimr) & port->imr_mirror)))    {       switch (port->autobaud_state)       {       default:       case AB_IDLE:           if (isr & MCF5272_UART_UISR_DB)           {               /* Detected the begin of a break, set the state to AB_BEGIN_BREAK               */               port->autobaud_state = AB_BEGIN_BREAK;               /* Reset the Delta Break bit in the UISR */               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT);           }           break;       case AB_BEGIN_BREAK:           if (isr & MCF5272_UART_UISR_DB)           {               /* Detected the end of a break, set the state to AB_BEGIN, and                  setup autobaud detection.               */               port->autobaud_state = AB_BEGIN;               /* Reset the Delta Break bit in the UISR and Enable autobaud */               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT |                                  MCF5272_UART_UCR_ENAB);               /* Enable autobaud completion interrupt */               port->imr_mirror |= MCF5272_UART_UIMR_ABC;               /* Disable the delta break interrupt so we can't receive                  anymore break interrupt.               */               port->imr_mirror &= ~MCF5272_UART_UIMR_DB;           }           break;       case AB_BEGIN:           if (isr & MCF5272_UART_UISR_ABC)           {               int count;               // Retrieve the baudrate that we're using now.               u16_t divider = (port->base->uabu << 8) + port->base->uabl;               // Search in the list to find a match.               for (count = sizeof(dividers_table)/sizeof(unsigned long) - 1;                    count >= 0;                    count--)               {                   if (divider < dividers_table[count]) break;               }               // Set the baud.               port->config.baud = count;               /* Autobaud completion */               port->autobaud_state = AB_IDLE;               /* Disable autobaud */               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_NONE);               /* Ignore autobaud completion interrupt. */               port->imr_mirror &= ~MCF5272_UART_UIMR_ABC;               /* Reenable begin break change and receive interrupt. */               port->imr_mirror |= MCF5272_UART_UIMR_DB;           }           break;       }        /* Receive character interrupt */        if ((isr & MCF5272_UART_UISR_RXRDY))            /* Ignore all receive interrupt when we're autobauding. */        {            // Read all the characters in the fifo.            while ((MCF5272_UART_READ(port->base->uisr_uimr) & MCF5272_UART_UISR_RXRDY))            {                char c;                /* Read the character from the UART. */                c = MCF5272_UART_READ(port->base->urb_utb);                /* Pass the read character to the upper layer. */                (chan->callbacks->rcv_char)(chan, c);            }        }        /* Transmit  complete interrupt */        if ((isr & MCF5272_UART_UISR_TXRDY))        {            /*   Transmit holding register is empty                         */           (chan->callbacks->xmt_char)(chan);        }    }    /*   Unmask all the DUART interrupts  that were masked  in the ISR,  so */    /* that we can receive the next interrupt.                              */    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);}#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0unsigned long MCF5272_uart_get_channel_0_baud_rate(){    /* return the baud rate for the first serial port */    return baud_rates_table[MCF5272_uart_channel_info_0.config.baud];}#endif#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1unsigned long MCF5272_uart_get_channel_1_baud_rate(){    /* return the baud rate for the second serial port */    return baud_rates_table[MCF5272_uart_channel_info_1.config.baud];}#endif

⌨️ 快捷键说明

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