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 + -
显示快捷键?