📄 mcfuart.c
字号:
/* * Generic UART Serial driver for Motorola Coldfire processors * * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russian Fed. * Author: Victor V. Vengerov <vvv@oktet.ru> * * COPYRIGHT (c) 1989-2000. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * * http://www.rtems.com/license/LICENSE. * * $Id: mcfuart.c,v 1.1.4.2 2003/09/04 18:45:44 joel Exp $ * */#include <rtems.h>#include <termios.h>#include <rtems/libio.h>#include "mcf5206/mcfuart.h"/* * int_driven_uart -- mapping between interrupt vector number and * UART descriptor structures */static struct { mcfuart *uart; int vec;} int_driven_uart[2];/* Forward function declarations */static rtems_isrmcfuart_interrupt_handler(rtems_vector_number vec); /* * mcfuart_init -- * This function verifies the input parameters and perform initialization * of the Motorola Coldfire on-chip UART descriptor structure. * * PARAMETERS: * uart - pointer to the UART channel descriptor structure * tty - pointer to termios structure * int_driven - interrupt-driven (1) or polled (0) I/O mode * chn - channel number (0/1) * rx_buf - pointer to receive buffer * rx_buf_len - receive buffer length * * RETURNS: * RTEMS_SUCCESSFUL if all parameters are valid, or error code */rtems_status_codemcfuart_init(mcfuart *uart, void *tty, rtems_unsigned8 intvec, rtems_unsigned32 chn){ if (uart == NULL) return RTEMS_INVALID_ADDRESS; if ((chn <= 0) || (chn > MCF5206E_UART_CHANNELS)) return RTEMS_INVALID_NUMBER; uart->chn = chn; uart->intvec = intvec; uart->tty = tty; return RTEMS_SUCCESSFUL;}/* mcfuart_set_baudrate -- * Program the UART timer to specified baudrate * * PARAMETERS: * uart - pointer to UART descriptor structure * baud - termios baud rate (B50, B9600, etc...) * * RETURNS: * none */static voidmcfuart_set_baudrate(mcfuart *uart, speed_t baud){ rtems_unsigned32 div; rtems_unsigned32 rate; switch (baud) { case B50: rate = 50; break; case B75: rate = 75; break; case B110: rate = 110; break; case B134: rate = 134; break; case B150: rate = 150; break; case B200: rate = 200; break; case B300: rate = 300; break; case B600: rate = 600; break; case B1200: rate = 1200; break; case B2400: rate = 2400; break; case B4800: rate = 4800; break; case B9600: rate = 9600; break; case B19200: rate = 19200; break; case B38400: rate = 38400; break; case B57600: rate = 57600; break;#ifdef B115200 case B115200: rate = 115200; break;#endif#ifdef B230400 case B230400: rate = 230400; break;#endif default: rate = 9600; break; } div = SYSTEM_CLOCK_FREQUENCY / (rate * 32); *MCF5206E_UBG1(MBAR,uart->chn) = (rtems_unsigned8)((div >> 8) & 0xff); *MCF5206E_UBG2(MBAR,uart->chn) = (rtems_unsigned8)(div & 0xff);}/* * mcfuart_reset -- * This function perform the hardware initialization of Motorola * Coldfire processor on-chip UART controller using parameters * filled by the mcfuart_init function. * * PARAMETERS: * uart - pointer to UART channel descriptor structure * * RETURNS: * RTEMS_SUCCESSFUL if channel is initialized successfully, error * code in other case * * ALGORITHM: * This function in general follows to algorith described in MCF5206e * User's Manual, 12.5 UART Module Initialization Sequence */rtems_status_codemcfuart_reset(mcfuart *uart){ register rtems_unsigned32 chn; rtems_status_code rc; if (uart == NULL) return RTEMS_INVALID_ADDRESS; chn = uart->chn; /* Reset the receiver and transmitter */ *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_RX; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_TX; /* * Program the vector number for a UART module interrupt, or * disable UART interrupts if polled I/O. Enable the desired * interrupt sources. */ if (uart->intvec != 0) { int_driven_uart[chn - 1].uart = uart; int_driven_uart[chn - 1].vec = uart->intvec; rc = rtems_interrupt_catch(mcfuart_interrupt_handler, uart->intvec, &uart->old_handler); if (rc != RTEMS_SUCCESSFUL) return rc; *MCF5206E_UIVR(MBAR,chn) = uart->intvec; *MCF5206E_UIMR(MBAR,chn) = MCF5206E_UIMR_FFULL; *MCF5206E_UACR(MBAR,chn) = MCF5206E_UACR_IEC; *MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(uart->chn == 1 ? MCF5206E_INTR_UART_1 : MCF5206E_INTR_UART_2); } else { *MCF5206E_UIMR(MBAR,chn) = 0; } /* Select the receiver and transmitter clock. */ mcfuart_set_baudrate(uart, B19200); /* dBUG defaults (unfortunately, it is differ to termios default */ *MCF5206E_UCSR(MBAR,chn) = MCF5206E_UCSR_RCS_TIMER | MCF5206E_UCSR_TCS_TIMER; /* Mode Registers 1,2 - set termios defaults (8N1) */ *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_MR; *MCF5206E_UMR(MBAR,chn) = /* MCF5206E_UMR1_RXRTS | */ MCF5206E_UMR1_PM_NO_PARITY | MCF5206E_UMR1_BC_8; *MCF5206E_UMR(MBAR,chn) = MCF5206E_UMR2_CM_NORMAL |/* MCF5206E_UMR2_TXCTS | */ MCF5206E_UMR2_SB_1; /* Enable Receiver and Transmitter */ *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_ERR; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_TC_ENABLE; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_RC_ENABLE; return RTEMS_SUCCESSFUL;}/* * mcfuart_disable -- * This function disable the operations on Motorola Coldfire UART * controller * * PARAMETERS: * uart - pointer to UART channel descriptor structure * * RETURNS: * RTEMS_SUCCESSFUL if UART closed successfuly, or error code in * other case */rtems_status_codemcfuart_disable(mcfuart *uart){ rtems_status_code rc; *MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_TC_DISABLE | MCF5206E_UCR_RC_DISABLE; if (uart->intvec != 0) { *MCF5206E_IMR(MBAR) |= MCF5206E_INTR_BIT(uart->chn == 1 ? MCF5206E_INTR_UART_1 : MCF5206E_INTR_UART_2); rc = rtems_interrupt_catch(uart->old_handler, uart->intvec, NULL); int_driven_uart[uart->chn - 1].uart = NULL; int_driven_uart[uart->chn - 1].vec = 0; if (rc != RTEMS_SUCCESSFUL) return rc; } return RTEMS_SUCCESSFUL;}/* * mcfuart_set_attributes -- * This function parse the termios attributes structure and perform * the appropriate settings in hardware. * * PARAMETERS: * uart - pointer to the UART descriptor structure * t - pointer to termios parameters * * RETURNS: * RTEMS_SUCCESSFUL */intmcfuart_set_attributes(mcfuart *uart, const struct termios *t){ int level; speed_t baud; rtems_unsigned8 umr1, umr2; baud = cfgetospeed(t); umr1 = 0; umr2 = MCF5206E_UMR2_CM_NORMAL; /* Set flow control */ if ((t->c_cflag & CRTSCTS) != 0) { umr1 |= MCF5206E_UMR1_RXRTS; umr2 |= MCF5206E_UMR2_TXCTS; } /* Set character size */ switch (t->c_cflag & CSIZE) { case CS5: umr1 |= MCF5206E_UMR1_BC_5; break; case CS6: umr1 |= MCF5206E_UMR1_BC_6; break; case CS7: umr1 |= MCF5206E_UMR1_BC_7; break; case CS8: umr1 |= MCF5206E_UMR1_BC_8; break; } /* Set number of stop bits */ if ((t->c_cflag & CSTOPB) != 0) { if ((t->c_cflag & CSIZE) == CS5) { umr2 |= MCF5206E_UMR2_SB5_2; } else { umr2 |= MCF5206E_UMR2_SB_2; } } else { if ((t->c_cflag & CSIZE) == CS5)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -