ser_mcf5272_uart.c

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

C
947
字号
//==========================================================================////      devs/serial/MCF52xx/MCF5282////      MCF5272 UART Serial I/O Interface Module (interrupt driven)////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================#include <cyg/io/io.h>#include <cyg/io/devtab.h>#include <cyg/io/serial.h>#include <cyg/infra/diag.h>#include <cyg/hal/hal_intr.h>#include <cyg/hal/hal_memmap.h>#include <cyg/infra/cyg_type.h>#include <cyg/hal/hal_arch.h>#include <cyg/hal/drv_api.h>#include <pkgconf/hal.h>#include <pkgconf/system.h>#include <pkgconf/io_serial.h>#include <pkgconf/io.h>#include <pkgconf/io_serial_mcf5272_uart.h>#include <cyg/io/ser_mcf5272_uart.h>/* The UART priority level */#define MCF5272_UART_PRIORITY_LEVEL 2/* Autobaud states */typedef enum autobaud_states_t{    AB_IDLE = 0,  /* Normal state. Autobaud process hasn't been initiated yet. */    AB_BEGIN_BREAK, /* Detected a start of the break */    AB_BEGIN,       /* Detected the end of the break and has set up the autobaud.*/}autobaud_states_t;#define FIELD_OFFSET(type,field) (cyg_uint32)(&(((type*)0)->field))typedef struct MCF5272_uart_info_t{    volatile mcf5272_sim_uart_t*    base;                       // Base address of the UART registers    uint32                          uart_vector;                // UART interrupt vector number    cyg_interrupt                   serial_interrupt;           // Interrupt context    cyg_handle_t                    serial_interrupt_handle;    // Interrupt handle    volatile uint8                  imr_mirror;                 // Interrupt mask register mirror    cyg_serial_info_t               config;                     // The channel configuration    autobaud_states_t               autobaud_state;             // The autobaud state} MCF5272_uart_info_t;/* Function prtoftyps for the MCF5272 UART ISR and DSR. */static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data);static void       MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);/* Function prototypes for the serial functions. */static bool MCF5272_uart_init(struct cyg_devtab_entry * tab);static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,                  struct cyg_devtab_entry *sub_tab,                  const char *name);static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c);static unsigned char MCF5272_uart_getc(serial_channel *chan);Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,                            const void *xbuf, cyg_uint32 *len);static void MCF5272_uart_start_xmit(serial_channel *chan);static void MCF5272_uart_stop_xmit(serial_channel * chan);/* Declare the serial functions that are called by the common serial driver layer. */static SERIAL_FUNS(    MCF5272_uart_funs,    MCF5272_uart_putc,    MCF5272_uart_getc,    MCF5272_uart_set_config,    MCF5272_uart_start_xmit,    MCF5272_uart_stop_xmit);/* Definition for channel 0 UART configuration. *//************************************************/#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0/* Data structure contains   channel informtion. */static MCF5272_uart_info_t MCF5272_uart_channel_info_0;/* If the channel buffer size is zero, do not include interrupt UART processing */#if CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE > 0/*      Allocated receive and transmit buffer.   The size of the buffer  is *//* configured by the configtool.                                            */static unsigned char MCF5272_uart_out_buf0[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE];static unsigned char MCF5272_uart_in_buf0[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE];/*      Channel function table.   We register  the UART  functions here  so *//* that uppper serial drivers can call the serial driver's routines.        */static SERIAL_CHANNEL_USING_INTERRUPTS(    MCF5272_uart_channel_0,    MCF5272_uart_funs,    MCF5272_uart_channel_info_0,    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),    CYG_SERIAL_STOP_DEFAULT,    CYG_SERIAL_PARITY_DEFAULT,    CYG_SERIAL_WORD_LENGTH_DEFAULT,    CYG_SERIAL_FLAGS_DEFAULT,    MCF5272_uart_out_buf0, sizeof(MCF5272_uart_out_buf0),    MCF5272_uart_in_buf0, sizeof(MCF5272_uart_in_buf0));#else/* Don't use interrupt processing for the UART. */static SERIAL_CHANNEL(    MCF5272_uart_channel_0,    MCF5272_uart_funs,    MCF5272_uart_channel_info_0,    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),    CYG_SERIAL_STOP_DEFAULT,    CYG_SERIAL_PARITY_DEFAULT,    CYG_SERIAL_WORD_LENGTH_DEFAULT,    CYG_SERIAL_FLAGS_DEFAULT);#endifDEVTAB_ENTRY(    MCF5272_uart_io0,    CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME,    0,                       // Does not depend on a lower level interface    &cyg_io_serial_devio,    // The table of I/O functions.    MCF5272_uart_init,       // UART initialization function.    MCF5272_uart_lookup,     // The UART lookup function. This function typically sets                             // up the device for actual use, turing on interrupts, configuring the port, etc.    &MCF5272_uart_channel_0);#endif //  CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0/* Definition for channel 1 UART configuration. *//************************************************/#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1/* Data structure contains   channel informtion. */static MCF5272_uart_info_t MCF5272_uart_channel_info_1;/* If the channel buffer size is zero, do not include interrupt UART processing */#if CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE > 0/*      Allocated receive and transmit buffer.   The size of the buffer  is *//* configured by the configtool.                                            */static unsigned char MCF5272_uart_out_buf1[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE];static unsigned char MCF5272_uart_in_buf1[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE];/*      Channel function table.   We register  the UART  functions here  so *//* that uppper serial drivers can call the serial driver's routines.        */static SERIAL_CHANNEL_USING_INTERRUPTS(    MCF5272_uart_channel_1,    MCF5272_uart_funs,    MCF5272_uart_channel_info_1,    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BAUD),    CYG_SERIAL_STOP_DEFAULT,    CYG_SERIAL_PARITY_DEFAULT,    CYG_SERIAL_WORD_LENGTH_DEFAULT,    CYG_SERIAL_FLAGS_DEFAULT,    MCF5272_uart_out_buf1, sizeof(MCF5272_uart_out_buf1),    MCF5272_uart_in_buf1, sizeof(MCF5272_uart_in_buf1));#elsestatic SERIAL_CHANNEL(MCF5272_uart_channel_1,                      MCF5272_uart_funs,                      MCF5272_uart_channel_info_1,                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),                      CYG_SERIAL_STOP_DEFAULT,                      CYG_SERIAL_PARITY_DEFAULT,                      CYG_SERIAL_WORD_LENGTH_DEFAULT,                      CYG_SERIAL_FLAGS_DEFAULT    );#endifDEVTAB_ENTRY(    MCF5272_uart_io1,    CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME,    0,                     // Does not depend on a lower level interface    &cyg_io_serial_devio,  // The table of I/O functions.    MCF5272_uart_init,     // UART initialization function.    MCF5272_uart_lookup,   // The UART lookup function. This function typically sets                           // up the device for actual use, turing on interrupts, configuring the port, etc.    &MCF5272_uart_channel_1);#endif //  CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1/* Definition of macros that access the UART's SIM registers *//* Read from a register */#define MCF5272_UART_WRITE(_addr_,_value_) \   *((volatile CYG_BYTE*)&(_addr_)) = (CYG_BYTE)(_value_)/* Write to a register */#define MCF5272_UART_READ(_addr_) \   *(volatile CYG_BYTE*)&(_addr_)/* Function Prototypes *//* =================== *//* Internal function to actually configure the hardware to desired baud rate, etc. */static bool MCF5272_uart_config_port(serial_channel*, cyg_serial_info_t*);static void MCF5272_uart_start_xmit(serial_channel*);/* Baudrate conversion table. */static unsigned long baud_rates_table[]={    0,    50,     // CYGNUM_SERIAL_BAUD_50 = 1    75,     // CYGNUM_SERIAL_BAUD_75    110,    // CYGNUM_SERIAL_BAUD_110    134,    // CYGNUM_SERIAL_BAUD_134_5    150,    // CYGNUM_SERIAL_BAUD_150    200,    // CYGNUM_SERIAL_BAUD_200    300,    // CYGNUM_SERIAL_BAUD_300    600,    // CYGNUM_SERIAL_BAUD_600    1200,   // CYGNUM_SERIAL_BAUD_1200    1800,   // CYGNUM_SERIAL_BAUD_1800    2400,   // CYGNUM_SERIAL_BAUD_2400    3600,   // CYGNUM_SERIAL_BAUD_3600    4800,   // CYGNUM_SERIAL_BAUD_4800    7200,   // CYGNUM_SERIAL_BAUD_7200    9600,   // CYGNUM_SERIAL_BAUD_9600    14400,  // CYGNUM_SERIAL_BAUD_14400    19200,  // CYGNUM_SERIAL_BAUD_19200    38400,  // CYGNUM_SERIAL_BAUD_38400    57600,  // CYGNUM_SERIAL_BAUD_57600    115200, // CYGNUM_SERIAL_BAUD_115200    230400  // CYGNUM_SERIAL_BAUD_230400};/*      The table contains  divers  to  divide  the  clock  to  configre  a *//* approppriate for the UART.                                               */static unsigned long dividers_table[]={    0,    46080,   // 50    30720,   // 75    20945,   // 110    17130,   // 134_5    15360,   // 150    11520,   // 200    7680,    // 300    3840,    // 600    1920,    // 1200    1280,    // 1800    960,     // 2400    640,     // 3600    480,     // 4800    320,     // 7200    240,     // 9600    160,     // 14400    120,     // 19200    60,      // 38400    40,      // 57600    20,      // 115200    10       // 230400};/******************************************************************************* MCF5272_uart_init() - This routine is called during bootstrap to set up the

⌨️ 快捷键说明

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