OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [serial/] [mcf52xx/] [mcf5272/] [v2_0/] [src/] [ser_mcf5272_uart.c] - Diff between revs 27 and 174

Only display areas with differences | Details | Blame | View Log

Rev 27 Rev 174
//==========================================================================
//==========================================================================
//
//
//      devs/serial/MCF52xx/MCF5282
//      devs/serial/MCF52xx/MCF5282
//
//
//      MCF5272 UART Serial I/O Interface Module (interrupt driven)
//      MCF5272 UART Serial I/O Interface Module (interrupt driven)
//
//
//==========================================================================
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
//
// eCos is free software; you can redistribute it and/or modify it under
// 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
// 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.
// 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
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// You should have received a copy of the GNU General Public License along
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
//
// As a special exception, if other files instantiate templates or use macros
// 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
// 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
// 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
// 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
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
// 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 exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
// this file might be covered by the GNU General Public License.
//
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//==========================================================================
 
 
#include <cyg/io/io.h>
#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/devtab.h>
#include <cyg/io/serial.h>
#include <cyg/io/serial.h>
#include <cyg/infra/diag.h>
#include <cyg/infra/diag.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/hal_memmap.h>
#include <cyg/hal/hal_memmap.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/drv_api.h>
#include <cyg/hal/drv_api.h>
#include <pkgconf/hal.h>
#include <pkgconf/hal.h>
#include <pkgconf/system.h>
#include <pkgconf/system.h>
#include <pkgconf/io_serial.h>
#include <pkgconf/io_serial.h>
#include <pkgconf/io.h>
#include <pkgconf/io.h>
#include <pkgconf/io_serial_mcf5272_uart.h>
#include <pkgconf/io_serial_mcf5272_uart.h>
#include <cyg/io/ser_mcf5272_uart.h>
#include <cyg/io/ser_mcf5272_uart.h>
 
 
 
 
/* The UART priority level */
/* The UART priority level */
#define MCF5272_UART_PRIORITY_LEVEL 2
#define MCF5272_UART_PRIORITY_LEVEL 2
 
 
 
 
/* Autobaud states */
/* Autobaud states */
typedef enum autobaud_states_t
typedef enum autobaud_states_t
{
{
    AB_IDLE = 0,  /* Normal state. Autobaud process hasn't been initiated yet. */
    AB_IDLE = 0,  /* Normal state. Autobaud process hasn't been initiated yet. */
    AB_BEGIN_BREAK, /* Detected a start of the break */
    AB_BEGIN_BREAK, /* Detected a start of the break */
    AB_BEGIN,       /* Detected the end of the break and has set up the autobaud.*/
    AB_BEGIN,       /* Detected the end of the break and has set up the autobaud.*/
 
 
}autobaud_states_t;
}autobaud_states_t;
 
 
#define FIELD_OFFSET(type,field) (cyg_uint32)(&(((type*)0)->field))
#define FIELD_OFFSET(type,field) (cyg_uint32)(&(((type*)0)->field))
 
 
typedef struct MCF5272_uart_info_t
typedef struct MCF5272_uart_info_t
{
{
 
 
    volatile mcf5272_sim_uart_t*    base;                       // Base address of the UART registers
    volatile mcf5272_sim_uart_t*    base;                       // Base address of the UART registers
    uint32                          uart_vector;                // UART interrupt vector number
    uint32                          uart_vector;                // UART interrupt vector number
 
 
    cyg_interrupt                   serial_interrupt;           // Interrupt context
    cyg_interrupt                   serial_interrupt;           // Interrupt context
    cyg_handle_t                    serial_interrupt_handle;    // Interrupt handle
    cyg_handle_t                    serial_interrupt_handle;    // Interrupt handle
 
 
    volatile uint8                  imr_mirror;                 // Interrupt mask register mirror
    volatile uint8                  imr_mirror;                 // Interrupt mask register mirror
 
 
    cyg_serial_info_t               config;                     // The channel configuration
    cyg_serial_info_t               config;                     // The channel configuration
 
 
    autobaud_states_t               autobaud_state;             // The autobaud state
    autobaud_states_t               autobaud_state;             // The autobaud state
 
 
 
 
} MCF5272_uart_info_t;
} MCF5272_uart_info_t;
 
 
/* Function prtoftyps for the MCF5272 UART ISR and DSR. */
/* Function prtoftyps for the MCF5272 UART ISR and DSR. */
static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data);
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);
static void       MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
 
 
 
 
/* Function prototypes for the serial functions. */
/* Function prototypes for the serial functions. */
static bool MCF5272_uart_init(struct cyg_devtab_entry * tab);
static bool MCF5272_uart_init(struct cyg_devtab_entry * tab);
static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
                  struct cyg_devtab_entry *sub_tab,
                  struct cyg_devtab_entry *sub_tab,
                  const char *name);
                  const char *name);
static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c);
static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c);
static unsigned char MCF5272_uart_getc(serial_channel *chan);
static unsigned char MCF5272_uart_getc(serial_channel *chan);
Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
                            const void *xbuf, cyg_uint32 *len);
                            const void *xbuf, cyg_uint32 *len);
static void MCF5272_uart_start_xmit(serial_channel *chan);
static void MCF5272_uart_start_xmit(serial_channel *chan);
static void MCF5272_uart_stop_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. */
/* Declare the serial functions that are called by the common serial driver layer. */
static SERIAL_FUNS
static SERIAL_FUNS
(
(
    MCF5272_uart_funs,
    MCF5272_uart_funs,
    MCF5272_uart_putc,
    MCF5272_uart_putc,
    MCF5272_uart_getc,
    MCF5272_uart_getc,
    MCF5272_uart_set_config,
    MCF5272_uart_set_config,
    MCF5272_uart_start_xmit,
    MCF5272_uart_start_xmit,
    MCF5272_uart_stop_xmit
    MCF5272_uart_stop_xmit
);
);
 
 
 
 
/* Definition for channel 0 UART configuration. */
/* Definition for channel 0 UART configuration. */
/************************************************/
/************************************************/
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
 
 
/* Data structure contains
/* Data structure contains
   channel informtion.
   channel informtion.
 */
 */
static MCF5272_uart_info_t MCF5272_uart_channel_info_0;
static MCF5272_uart_info_t MCF5272_uart_channel_info_0;
 
 
/* If the channel buffer size is zero, do not include interrupt UART processing */
/* If the channel buffer size is zero, do not include interrupt UART processing */
#if CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE > 0
#if CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE > 0
 
 
/*      Allocated receive and transmit buffer.   The size of the buffer  is */
/*      Allocated receive and transmit buffer.   The size of the buffer  is */
/* configured by the configtool.                                            */
/* configured by the configtool.                                            */
 
 
static unsigned char MCF5272_uart_out_buf0[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE];
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];
static unsigned char MCF5272_uart_in_buf0[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE];
 
 
/*      Channel function table.   We register  the UART  functions here  so */
/*      Channel function table.   We register  the UART  functions here  so */
/* that uppper serial drivers can call the serial driver's routines.        */
/* that uppper serial drivers can call the serial driver's routines.        */
 
 
static SERIAL_CHANNEL_USING_INTERRUPTS(
static SERIAL_CHANNEL_USING_INTERRUPTS(
    MCF5272_uart_channel_0,
    MCF5272_uart_channel_0,
    MCF5272_uart_funs,
    MCF5272_uart_funs,
    MCF5272_uart_channel_info_0,
    MCF5272_uart_channel_info_0,
    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
    CYG_SERIAL_STOP_DEFAULT,
    CYG_SERIAL_STOP_DEFAULT,
    CYG_SERIAL_PARITY_DEFAULT,
    CYG_SERIAL_PARITY_DEFAULT,
    CYG_SERIAL_WORD_LENGTH_DEFAULT,
    CYG_SERIAL_WORD_LENGTH_DEFAULT,
    CYG_SERIAL_FLAGS_DEFAULT,
    CYG_SERIAL_FLAGS_DEFAULT,
    MCF5272_uart_out_buf0, sizeof(MCF5272_uart_out_buf0),
    MCF5272_uart_out_buf0, sizeof(MCF5272_uart_out_buf0),
    MCF5272_uart_in_buf0, sizeof(MCF5272_uart_in_buf0)
    MCF5272_uart_in_buf0, sizeof(MCF5272_uart_in_buf0)
);
);
#else
#else
/* Don't use interrupt processing for the UART. */
/* Don't use interrupt processing for the UART. */
static SERIAL_CHANNEL(
static SERIAL_CHANNEL(
    MCF5272_uart_channel_0,
    MCF5272_uart_channel_0,
    MCF5272_uart_funs,
    MCF5272_uart_funs,
    MCF5272_uart_channel_info_0,
    MCF5272_uart_channel_info_0,
    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
    CYG_SERIAL_STOP_DEFAULT,
    CYG_SERIAL_STOP_DEFAULT,
    CYG_SERIAL_PARITY_DEFAULT,
    CYG_SERIAL_PARITY_DEFAULT,
    CYG_SERIAL_WORD_LENGTH_DEFAULT,
    CYG_SERIAL_WORD_LENGTH_DEFAULT,
    CYG_SERIAL_FLAGS_DEFAULT
    CYG_SERIAL_FLAGS_DEFAULT
);
);
#endif
#endif
 
 
DEVTAB_ENTRY(
DEVTAB_ENTRY(
    MCF5272_uart_io0,
    MCF5272_uart_io0,
    CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME,
    CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME,
    0,                       // Does not depend on a lower level interface
    0,                       // Does not depend on a lower level interface
    &cyg_io_serial_devio,    // The table of I/O functions.
    &cyg_io_serial_devio,    // The table of I/O functions.
    MCF5272_uart_init,       // UART initialization function.
    MCF5272_uart_init,       // UART initialization function.
    MCF5272_uart_lookup,     // The UART lookup function. This function typically sets
    MCF5272_uart_lookup,     // The UART lookup function. This function typically sets
                             // up the device for actual use, turing on interrupts, configuring the port, etc.
                             // up the device for actual use, turing on interrupts, configuring the port, etc.
    &MCF5272_uart_channel_0
    &MCF5272_uart_channel_0
);
);
#endif //  CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0
#endif //  CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0
 
 
/* Definition for channel 1 UART configuration. */
/* Definition for channel 1 UART configuration. */
/************************************************/
/************************************************/
 
 
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
 
 
 
 
/* Data structure contains
/* Data structure contains
   channel informtion.
   channel informtion.
 */
 */
static MCF5272_uart_info_t MCF5272_uart_channel_info_1;
static MCF5272_uart_info_t MCF5272_uart_channel_info_1;
 
 
/* If the channel buffer size is zero, do not include interrupt UART processing */
/* If the channel buffer size is zero, do not include interrupt UART processing */
#if CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE > 0
#if CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE > 0
 
 
/*      Allocated receive and transmit buffer.   The size of the buffer  is */
/*      Allocated receive and transmit buffer.   The size of the buffer  is */
/* configured by the configtool.                                            */
/* configured by the configtool.                                            */
 
 
static unsigned char MCF5272_uart_out_buf1[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE];
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];
static unsigned char MCF5272_uart_in_buf1[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE];
 
 
/*      Channel function table.   We register  the UART  functions here  so */
/*      Channel function table.   We register  the UART  functions here  so */
/* that uppper serial drivers can call the serial driver's routines.        */
/* that uppper serial drivers can call the serial driver's routines.        */
 
 
static SERIAL_CHANNEL_USING_INTERRUPTS(
static SERIAL_CHANNEL_USING_INTERRUPTS(
    MCF5272_uart_channel_1,
    MCF5272_uart_channel_1,
    MCF5272_uart_funs,
    MCF5272_uart_funs,
    MCF5272_uart_channel_info_1,
    MCF5272_uart_channel_info_1,
    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BAUD),
    CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BAUD),
    CYG_SERIAL_STOP_DEFAULT,
    CYG_SERIAL_STOP_DEFAULT,
    CYG_SERIAL_PARITY_DEFAULT,
    CYG_SERIAL_PARITY_DEFAULT,
    CYG_SERIAL_WORD_LENGTH_DEFAULT,
    CYG_SERIAL_WORD_LENGTH_DEFAULT,
    CYG_SERIAL_FLAGS_DEFAULT,
    CYG_SERIAL_FLAGS_DEFAULT,
    MCF5272_uart_out_buf1, sizeof(MCF5272_uart_out_buf1),
    MCF5272_uart_out_buf1, sizeof(MCF5272_uart_out_buf1),
    MCF5272_uart_in_buf1, sizeof(MCF5272_uart_in_buf1)
    MCF5272_uart_in_buf1, sizeof(MCF5272_uart_in_buf1)
);
);
 
 
#else
#else
static SERIAL_CHANNEL(MCF5272_uart_channel_1,
static SERIAL_CHANNEL(MCF5272_uart_channel_1,
                      MCF5272_uart_funs,
                      MCF5272_uart_funs,
                      MCF5272_uart_channel_info_1,
                      MCF5272_uart_channel_info_1,
                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
                      CYG_SERIAL_STOP_DEFAULT,
                      CYG_SERIAL_STOP_DEFAULT,
                      CYG_SERIAL_PARITY_DEFAULT,
                      CYG_SERIAL_PARITY_DEFAULT,
                      CYG_SERIAL_WORD_LENGTH_DEFAULT,
                      CYG_SERIAL_WORD_LENGTH_DEFAULT,
                      CYG_SERIAL_FLAGS_DEFAULT
                      CYG_SERIAL_FLAGS_DEFAULT
    );
    );
#endif
#endif
DEVTAB_ENTRY(
DEVTAB_ENTRY(
    MCF5272_uart_io1,
    MCF5272_uart_io1,
    CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME,
    CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME,
    0,                     // Does not depend on a lower level interface
    0,                     // Does not depend on a lower level interface
    &cyg_io_serial_devio,  // The table of I/O functions.
    &cyg_io_serial_devio,  // The table of I/O functions.
    MCF5272_uart_init,     // UART initialization function.
    MCF5272_uart_init,     // UART initialization function.
    MCF5272_uart_lookup,   // The UART lookup function. This function typically sets
    MCF5272_uart_lookup,   // The UART lookup function. This function typically sets
                           // up the device for actual use, turing on interrupts, configuring the port, etc.
                           // up the device for actual use, turing on interrupts, configuring the port, etc.
    &MCF5272_uart_channel_1
    &MCF5272_uart_channel_1
);
);
#endif //  CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1
#endif //  CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1
 
 
 
 
 
 
/* Definition of macros that access the UART's SIM registers */
/* Definition of macros that access the UART's SIM registers */
/* Read from a register */
/* Read from a register */
 
 
#define MCF5272_UART_WRITE(_addr_,_value_) \
#define MCF5272_UART_WRITE(_addr_,_value_) \
   *((volatile CYG_BYTE*)&(_addr_)) = (CYG_BYTE)(_value_)
   *((volatile CYG_BYTE*)&(_addr_)) = (CYG_BYTE)(_value_)
/* Write to a register */
/* Write to a register */
#define MCF5272_UART_READ(_addr_) \
#define MCF5272_UART_READ(_addr_) \
   *(volatile CYG_BYTE*)&(_addr_)
   *(volatile CYG_BYTE*)&(_addr_)
 
 
 
 
/* Function Prototypes */
/* Function Prototypes */
/* =================== */
/* =================== */
/* Internal function to actually configure the hardware to desired baud rate, etc. */
/* 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 bool MCF5272_uart_config_port(serial_channel*, cyg_serial_info_t*);
static void MCF5272_uart_start_xmit(serial_channel*);
static void MCF5272_uart_start_xmit(serial_channel*);
 
 
 
 
/* Baudrate conversion table. */
/* Baudrate conversion table. */
static unsigned long baud_rates_table[]=
static unsigned long baud_rates_table[]=
{
{
    0,
    0,
    50,     // CYGNUM_SERIAL_BAUD_50 = 1
    50,     // CYGNUM_SERIAL_BAUD_50 = 1
    75,     // CYGNUM_SERIAL_BAUD_75
    75,     // CYGNUM_SERIAL_BAUD_75
    110,    // CYGNUM_SERIAL_BAUD_110
    110,    // CYGNUM_SERIAL_BAUD_110
    134,    // CYGNUM_SERIAL_BAUD_134_5
    134,    // CYGNUM_SERIAL_BAUD_134_5
    150,    // CYGNUM_SERIAL_BAUD_150
    150,    // CYGNUM_SERIAL_BAUD_150
    200,    // CYGNUM_SERIAL_BAUD_200
    200,    // CYGNUM_SERIAL_BAUD_200
    300,    // CYGNUM_SERIAL_BAUD_300
    300,    // CYGNUM_SERIAL_BAUD_300
    600,    // CYGNUM_SERIAL_BAUD_600
    600,    // CYGNUM_SERIAL_BAUD_600
    1200,   // CYGNUM_SERIAL_BAUD_1200
    1200,   // CYGNUM_SERIAL_BAUD_1200
    1800,   // CYGNUM_SERIAL_BAUD_1800
    1800,   // CYGNUM_SERIAL_BAUD_1800
    2400,   // CYGNUM_SERIAL_BAUD_2400
    2400,   // CYGNUM_SERIAL_BAUD_2400
    3600,   // CYGNUM_SERIAL_BAUD_3600
    3600,   // CYGNUM_SERIAL_BAUD_3600
    4800,   // CYGNUM_SERIAL_BAUD_4800
    4800,   // CYGNUM_SERIAL_BAUD_4800
    7200,   // CYGNUM_SERIAL_BAUD_7200
    7200,   // CYGNUM_SERIAL_BAUD_7200
    9600,   // CYGNUM_SERIAL_BAUD_9600
    9600,   // CYGNUM_SERIAL_BAUD_9600
    14400,  // CYGNUM_SERIAL_BAUD_14400
    14400,  // CYGNUM_SERIAL_BAUD_14400
    19200,  // CYGNUM_SERIAL_BAUD_19200
    19200,  // CYGNUM_SERIAL_BAUD_19200
    38400,  // CYGNUM_SERIAL_BAUD_38400
    38400,  // CYGNUM_SERIAL_BAUD_38400
    57600,  // CYGNUM_SERIAL_BAUD_57600
    57600,  // CYGNUM_SERIAL_BAUD_57600
    115200, // CYGNUM_SERIAL_BAUD_115200
    115200, // CYGNUM_SERIAL_BAUD_115200
    230400  // CYGNUM_SERIAL_BAUD_230400
    230400  // CYGNUM_SERIAL_BAUD_230400
};
};
 
 
/*      The table contains  divers  to  divide  the  clock  to  configre  a */
/*      The table contains  divers  to  divide  the  clock  to  configre  a */
/* approppriate for the UART.                                               */
/* approppriate for the UART.                                               */
 
 
static unsigned long dividers_table[]=
static unsigned long dividers_table[]=
{
{
    0,
    0,
    46080,   // 50
    46080,   // 50
    30720,   // 75
    30720,   // 75
    20945,   // 110
    20945,   // 110
    17130,   // 134_5
    17130,   // 134_5
    15360,   // 150
    15360,   // 150
    11520,   // 200
    11520,   // 200
    7680,    // 300
    7680,    // 300
    3840,    // 600
    3840,    // 600
    1920,    // 1200
    1920,    // 1200
    1280,    // 1800
    1280,    // 1800
    960,     // 2400
    960,     // 2400
    640,     // 3600
    640,     // 3600
    480,     // 4800
    480,     // 4800
    320,     // 7200
    320,     // 7200
    240,     // 9600
    240,     // 9600
    160,     // 14400
    160,     // 14400
    120,     // 19200
    120,     // 19200
    60,      // 38400
    60,      // 38400
    40,      // 57600
    40,      // 57600
    20,      // 115200
    20,      // 115200
    10       // 230400
    10       // 230400
};
};
 
 
/*******************************************************************************
/*******************************************************************************
 MCF5272_uart_init() - This routine is called during bootstrap to set up the
 MCF5272_uart_init() - This routine is called during bootstrap to set up the
                       UART driver.
                       UART driver.
 
 
 INPUT:
 INPUT:
    Pointer to the the device table.
    Pointer to the the device table.
 
 
 RETURN:
 RETURN:
    Returns true if the initialization is successful. Otherwise, it retuns false
    Returns true if the initialization is successful. Otherwise, it retuns false
*/
*/
static bool MCF5272_uart_init(struct cyg_devtab_entry * tab)
static bool MCF5272_uart_init(struct cyg_devtab_entry * tab)
{
{
    serial_channel *chan = (serial_channel *)tab->priv;
    serial_channel *chan = (serial_channel *)tab->priv;
    MCF5272_uart_info_t *MCF5272_uart_chan = (MCF5272_uart_info_t *)chan->dev_priv;
    MCF5272_uart_info_t *MCF5272_uart_chan = (MCF5272_uart_info_t *)chan->dev_priv;
 
 
    #ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
    #ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
 
 
    /*   Instantiation of the  UART channel  0 data  strucutre.  This  data */
    /*   Instantiation of the  UART channel  0 data  strucutre.  This  data */
    /* structure contains channel information.                              */
    /* structure contains channel information.                              */
 
 
    if (strcmp(tab->name, CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME) == 0)
    if (strcmp(tab->name, CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME) == 0)
    {
    {
 
 
        /*   Initiliaze the UART information data to all zeros.             */
        /*   Initiliaze the UART information data to all zeros.             */
 
 
        memset(MCF5272_uart_chan, sizeof(MCF5272_uart_info_t), 0);
        memset(MCF5272_uart_chan, sizeof(MCF5272_uart_info_t), 0);
 
 
        /*   Set the base  address of the  UART registers to  differentiate */
        /*   Set the base  address of the  UART registers to  differentiate */
        /* itself from the different regusters for the other UART port.     */
        /* itself from the different regusters for the other UART port.     */
 
 
        MCF5272_uart_chan->base = (mcf5272_sim_uart_t*)&MCF5272_SIM->uart[0];
        MCF5272_uart_chan->base = (mcf5272_sim_uart_t*)&MCF5272_SIM->uart[0];
 
 
        /*   Set the UART interrupt vector number.                          */
        /*   Set the UART interrupt vector number.                          */
 
 
        MCF5272_uart_chan->uart_vector = CYGNUM_HAL_VECTOR_UART1;
        MCF5272_uart_chan->uart_vector = CYGNUM_HAL_VECTOR_UART1;
 
 
        /*   Set the autobaud state to idle.                                */
        /*   Set the autobaud state to idle.                                */
 
 
        MCF5272_uart_chan->autobaud_state = AB_IDLE;
        MCF5272_uart_chan->autobaud_state = AB_IDLE;
 
 
        /* Initilize the UART 0 output pins */
        /* Initilize the UART 0 output pins */
 
 
        MCF5272_SIM->gpio.pbcnt =  MCF5272_GPIO_PBCNT_URT0_EN |
        MCF5272_SIM->gpio.pbcnt =  MCF5272_GPIO_PBCNT_URT0_EN |
            ((MCF5272_SIM->gpio.pbcnt) & ~MCF5272_GPIO_PBCNT_URT0_MSK);
            ((MCF5272_SIM->gpio.pbcnt) & ~MCF5272_GPIO_PBCNT_URT0_MSK);
    }
    }
    #endif
    #endif
 
 
    #ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
    #ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
 
 
    /* Instantiation of the UART channel 1 data strucutre. This data structure contains
    /* Instantiation of the UART channel 1 data strucutre. This data structure contains
       channel information.
       channel information.
     */
     */
    if (strcmp(tab->name, CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME) == 0)
    if (strcmp(tab->name, CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME) == 0)
    {
    {
 
 
        /*   Initiliaze the UART information data to all zeros.             */
        /*   Initiliaze the UART information data to all zeros.             */
 
 
        memset(MCF5272_uart_chan, sizeof(MCF5272_uart_info_t), 0);
        memset(MCF5272_uart_chan, sizeof(MCF5272_uart_info_t), 0);
 
 
        /*   Set the base  address of the  UART registers to  differentiate */
        /*   Set the base  address of the  UART registers to  differentiate */
        /* itself from the different regusters for the other UART port.     */
        /* itself from the different regusters for the other UART port.     */
 
 
        MCF5272_uart_chan->base = (mcf5272_sim_uart_t*)&MCF5272_SIM->uart[1];
        MCF5272_uart_chan->base = (mcf5272_sim_uart_t*)&MCF5272_SIM->uart[1];
 
 
         /*   Set the UART interrupt vector number.                          */
         /*   Set the UART interrupt vector number.                          */
 
 
        MCF5272_uart_chan->uart_vector = CYGNUM_HAL_VECTOR_UART2;
        MCF5272_uart_chan->uart_vector = CYGNUM_HAL_VECTOR_UART2;
 
 
        /*   Set the autobaud state to idle.                                */
        /*   Set the autobaud state to idle.                                */
 
 
        MCF5272_uart_chan->autobaud_state = AB_IDLE;
        MCF5272_uart_chan->autobaud_state = AB_IDLE;
 
 
        /* Initilize the UART 1 output pins */
        /* Initilize the UART 1 output pins */
 
 
        MCF5272_SIM->gpio.pdcnt =  MCF5272_GPIO_PDCNT_URT1_EN |
        MCF5272_SIM->gpio.pdcnt =  MCF5272_GPIO_PDCNT_URT1_EN |
            ((MCF5272_SIM->gpio.pdcnt) & ~MCF5272_GPIO_PDCNT_URT1_MSK);
            ((MCF5272_SIM->gpio.pdcnt) & ~MCF5272_GPIO_PDCNT_URT1_MSK);
 
 
    }
    }
    #endif
    #endif
 
 
 
 
    if (chan->out_cbuf.len > 0) {
    if (chan->out_cbuf.len > 0) {
 
 
        /*   If the the buffer is greater  than zero, then the driver  will */
        /*   If the the buffer is greater  than zero, then the driver  will */
        /* use  interrupt  driven  I/O.   Hence,  the  driver  creates   an */
        /* use  interrupt  driven  I/O.   Hence,  the  driver  creates   an */
        /* interrupt context for the UART device.                           */
        /* interrupt context for the UART device.                           */
 
 
        cyg_drv_interrupt_create(MCF5272_uart_chan->uart_vector,
        cyg_drv_interrupt_create(MCF5272_uart_chan->uart_vector,
                                 MCF5272_UART_PRIORITY_LEVEL,           // Priority - Level 2
                                 MCF5272_UART_PRIORITY_LEVEL,           // Priority - Level 2
                                 (cyg_addrword_t)chan,                  //  Data item passed to interrupt handler
                                 (cyg_addrword_t)chan,                  //  Data item passed to interrupt handler
                                 MCF5272_uart_ISR,
                                 MCF5272_uart_ISR,
                                 MCF5272_uart_DSR,
                                 MCF5272_uart_DSR,
                                 &MCF5272_uart_chan->serial_interrupt_handle,
                                 &MCF5272_uart_chan->serial_interrupt_handle,
                                 &MCF5272_uart_chan->serial_interrupt);
                                 &MCF5272_uart_chan->serial_interrupt);
 
 
        cyg_drv_interrupt_attach(MCF5272_uart_chan->serial_interrupt_handle);
        cyg_drv_interrupt_attach(MCF5272_uart_chan->serial_interrupt_handle);
 
 
        (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
        (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    }
    }
 
 
    // Configure Serial device.
    // Configure Serial device.
    return(MCF5272_uart_config_port(chan, &chan->config));
    return(MCF5272_uart_config_port(chan, &chan->config));
}
}
 
 
/******************************************************************************************************
/******************************************************************************************************
 MCF5272_uart_config_port() - Configure the UART port.
 MCF5272_uart_config_port() - Configure the UART port.
 
 
 Internal function to actually configure the hardware to desired baud rate, etc.
 Internal function to actually configure the hardware to desired baud rate, etc.
 
 
 INPUT:
 INPUT:
    chan        - The channel information
    chan        - The channel information
    new_confg   - The port configuration which include the desired baud rate, etc.
    new_confg   - The port configuration which include the desired baud rate, etc.
 
 
 RETURN:
 RETURN:
    Returns true if the port configuration is successful. Otherwise, it retuns false
    Returns true if the port configuration is successful. Otherwise, it retuns false
 
 
 */
 */
static bool MCF5272_uart_config_port(serial_channel *chan,
static bool MCF5272_uart_config_port(serial_channel *chan,
                                     cyg_serial_info_t *new_config)
                                     cyg_serial_info_t *new_config)
{
{
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
    uint8 mode_reg = 0;
    uint8 mode_reg = 0;
    uint32 ubgs;
    uint32 ubgs;
    unsigned int baud_divisor;
    unsigned int baud_divisor;
 
 
 
 
    /*   Get the  divisor  from  the  baudrate  table  which  will  use  to */
    /*   Get the  divisor  from  the  baudrate  table  which  will  use  to */
    /* configure the port's baud rate.                                      */
    /* configure the port's baud rate.                                      */
 
 
    baud_divisor = baud_rates_table[new_config->baud];
    baud_divisor = baud_rates_table[new_config->baud];
 
 
    /*   If the divisor is zeor, we dont' configure the port.               */
    /*   If the divisor is zeor, we dont' configure the port.               */
 
 
    if (baud_divisor == 0) return false;
    if (baud_divisor == 0) return false;
 
 
    /*   Save the configuration value for later use.                        */
    /*   Save the configuration value for later use.                        */
 
 
    port->config = *new_config;
    port->config = *new_config;
 
 
    /*   We first write the reset values into the device and then configure */
    /*   We first write the reset values into the device and then configure */
    /* the device the we way we want to use it.                             */
    /* the device the we way we want to use it.                             */
 
 
        /* Reset Transmitter */
        /* Reset Transmitter */
 
 
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_TX);
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_TX);
 
 
        /* Reset Receiver */
        /* Reset Receiver */
 
 
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_RX);
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_RX);
 
 
        /* Reset Mode Register */
        /* Reset Mode Register */
 
 
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_MR);
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_MR);
 
 
    /* Translate the parity configuration to UART mode bits. */
    /* Translate the parity configuration to UART mode bits. */
 
 
    switch(port->config.parity)
    switch(port->config.parity)
    {
    {
    default:
    default:
    case CYGNUM_SERIAL_PARITY_NONE:
    case CYGNUM_SERIAL_PARITY_NONE:
        mode_reg = 0 | MCF5272_UART_UMR1_PM_NONE;
        mode_reg = 0 | MCF5272_UART_UMR1_PM_NONE;
        break;
        break;
    case CYGNUM_SERIAL_PARITY_EVEN:
    case CYGNUM_SERIAL_PARITY_EVEN:
        mode_reg = 0 | MCF5272_UART_UMR1_PM_EVEN;
        mode_reg = 0 | MCF5272_UART_UMR1_PM_EVEN;
        break;
        break;
    case CYGNUM_SERIAL_PARITY_ODD:
    case CYGNUM_SERIAL_PARITY_ODD:
        mode_reg = 0 | MCF5272_UART_UMR1_PM_ODD;
        mode_reg = 0 | MCF5272_UART_UMR1_PM_ODD;
        break;
        break;
    case CYGNUM_SERIAL_PARITY_MARK:
    case CYGNUM_SERIAL_PARITY_MARK:
        mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_HI;
        mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_HI;
        break;
        break;
    case CYGNUM_SERIAL_PARITY_SPACE:
    case CYGNUM_SERIAL_PARITY_SPACE:
        mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_LO;
        mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_LO;
        break;
        break;
    }
    }
 
 
    /* Translate the number of bits per character configuration to UART mode bits. */
    /* Translate the number of bits per character configuration to UART mode bits. */
 
 
    switch(port->config.word_length)
    switch(port->config.word_length)
    {
    {
 
 
    case CYGNUM_SERIAL_WORD_LENGTH_5:
    case CYGNUM_SERIAL_WORD_LENGTH_5:
        mode_reg |= MCF5272_UART_UMR1_BC_5;
        mode_reg |= MCF5272_UART_UMR1_BC_5;
        break;
        break;
    case CYGNUM_SERIAL_WORD_LENGTH_6:
    case CYGNUM_SERIAL_WORD_LENGTH_6:
        mode_reg |= MCF5272_UART_UMR1_BC_6;
        mode_reg |= MCF5272_UART_UMR1_BC_6;
        break;
        break;
    case CYGNUM_SERIAL_WORD_LENGTH_7:
    case CYGNUM_SERIAL_WORD_LENGTH_7:
        mode_reg |= MCF5272_UART_UMR1_BC_7;
        mode_reg |= MCF5272_UART_UMR1_BC_7;
        break;
        break;
    default:
    default:
    case CYGNUM_SERIAL_WORD_LENGTH_8:
    case CYGNUM_SERIAL_WORD_LENGTH_8:
        mode_reg |= MCF5272_UART_UMR1_BC_8;
        mode_reg |= MCF5272_UART_UMR1_BC_8;
        break;
        break;
    }
    }
 
 
        /* Configure the parity and the bits per character */
        /* Configure the parity and the bits per character */
 
 
    MCF5272_UART_WRITE(port->base->umr, mode_reg);
    MCF5272_UART_WRITE(port->base->umr, mode_reg);
 
 
    /* Translate the stop bit length to UART mode bits. */
    /* Translate the stop bit length to UART mode bits. */
 
 
    switch(port->config.stop)
    switch(port->config.stop)
    {
    {
    default:
    default:
    case CYGNUM_SERIAL_STOP_1:
    case CYGNUM_SERIAL_STOP_1:
        mode_reg = MCF5272_UART_UMR2_STOP_BITS_1;
        mode_reg = MCF5272_UART_UMR2_STOP_BITS_1;
        break;
        break;
    case CYGNUM_SERIAL_STOP_1_5:
    case CYGNUM_SERIAL_STOP_1_5:
        mode_reg = MCF5272_UART_UMR2_STOP_BITS_15;
        mode_reg = MCF5272_UART_UMR2_STOP_BITS_15;
        break;
        break;
    case CYGNUM_SERIAL_STOP_2:
    case CYGNUM_SERIAL_STOP_2:
        mode_reg = MCF5272_UART_UMR2_STOP_BITS_2;
        mode_reg = MCF5272_UART_UMR2_STOP_BITS_2;
        break;
        break;
    }
    }
 
 
        /* No echo or loopback */
        /* No echo or loopback */
 
 
    MCF5272_UART_WRITE(port->base->umr, 0 | MCF5272_UART_UMR2_CM_NORMAL | mode_reg);
    MCF5272_UART_WRITE(port->base->umr, 0 | MCF5272_UART_UMR2_CM_NORMAL | mode_reg);
 
 
        /* Set Rx and Tx baud by timer */
        /* Set Rx and Tx baud by timer */
 
 
    MCF5272_UART_WRITE(port->base->ucr, 0 | MCF5272_UART_UCSR_RCS(0xD) |
    MCF5272_UART_WRITE(port->base->ucr, 0 | MCF5272_UART_UCSR_RCS(0xD) |
                       MCF5272_UART_UCSR_TCS(0xD));
                       MCF5272_UART_UCSR_TCS(0xD));
 
 
        /* Mask all USART interrupts */
        /* Mask all USART interrupts */
 
 
    MCF5272_UART_WRITE(port->base->uisr_uimr, 0);
    MCF5272_UART_WRITE(port->base->uisr_uimr, 0);
 
 
        /* Calculate baud settings */
        /* Calculate baud settings */
 
 
    ubgs = (uint16)((CYGHWR_HAL_SYSTEM_CLOCK_MHZ*1000000)/
    ubgs = (uint16)((CYGHWR_HAL_SYSTEM_CLOCK_MHZ*1000000)/
                    (baud_divisor * 32));
                    (baud_divisor * 32));
 
 
    /*   Program the baud settings to the device.                           */
    /*   Program the baud settings to the device.                           */
 
 
        MCF5272_UART_WRITE(port->base->udu, (uint8)((ubgs & 0xFF00) >> 8));
        MCF5272_UART_WRITE(port->base->udu, (uint8)((ubgs & 0xFF00) >> 8));
        MCF5272_UART_WRITE(port->base->udl, (uint8)(ubgs & 0x00FF));
        MCF5272_UART_WRITE(port->base->udl, (uint8)(ubgs & 0x00FF));
 
 
        /* Enable receiver and transmitter */
        /* Enable receiver and transmitter */
 
 
    MCF5272_UART_WRITE(port->base->ucr, 0 | MCF5272_UART_UCR_TXRXEN);
    MCF5272_UART_WRITE(port->base->ucr, 0 | MCF5272_UART_UCR_TXRXEN);
 
 
    /* Enable both transmit and receive interrupt. */
    /* Enable both transmit and receive interrupt. */
 
 
    port->imr_mirror = MCF5272_UART_UIMR_TXRDY | MCF5272_UART_UIMR_FFULL |
    port->imr_mirror = MCF5272_UART_UIMR_TXRDY | MCF5272_UART_UIMR_FFULL |
                       MCF5272_UART_UIMR_DB;
                       MCF5272_UART_UIMR_DB;
    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
 
 
    return true; /* Returns true to indicate a successful configuration */
    return true; /* Returns true to indicate a successful configuration */
 
 
}
}
 
 
/*******************************************************************************
/*******************************************************************************
 MCF5272_uart_lookup() - This routine is called when the device is "looked" up
 MCF5272_uart_lookup() - This routine is called when the device is "looked" up
                        (i.e. attached)
                        (i.e. attached)
 
 
 INPUT:
 INPUT:
    tab - pointer to a pointer of the device table
    tab - pointer to a pointer of the device table
    sub_tab - Pointer to the sub device table.
    sub_tab - Pointer to the sub device table.
    name - name of the device
    name - name of the device
 
 
 RETURN:
 RETURN:
    always return ENOERR
    always return ENOERR
 
 
*/
*/
static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
                  struct cyg_devtab_entry *sub_tab,
                  struct cyg_devtab_entry *sub_tab,
                  const char *name)
                  const char *name)
{
{
    serial_channel *chan = (serial_channel *)(*tab)->priv;
    serial_channel *chan = (serial_channel *)(*tab)->priv;
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    return ENOERR;
    return ENOERR;
}
}
 
 
/*******************************************************************************
/*******************************************************************************
 MCF5272_uart_putc() - Send a character to the device output buffer.
 MCF5272_uart_putc() - Send a character to the device output buffer.
 
 
 INPUT:
 INPUT:
    chan - pointer to the serial private data.
    chan - pointer to the serial private data.
    c    - the character to output
    c    - the character to output
 
 
 RETURN:
 RETURN:
    'true' if character is sent to device, return 'false' when we've
    'true' if character is sent to device, return 'false' when we've
    ran out of buffer space in the device itself.
    ran out of buffer space in the device itself.
 
 
*/
*/
 
 
static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c)
static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c)
{
{
    CYG_INTERRUPT_STATE int_state;
    CYG_INTERRUPT_STATE int_state;
    MCF5272_uart_info_t *port = (MCF5272_uart_info_t *)chan->dev_priv;
    MCF5272_uart_info_t *port = (MCF5272_uart_info_t *)chan->dev_priv;
 
 
    /* Make sure the transmitter is not full. If it is full, return false. */
    /* Make sure the transmitter is not full. If it is full, return false. */
    if  (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_TXRDY))
    if  (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_TXRDY))
        return false;
        return false;
 
 
    /* Enable transmit interrupt. */
    /* Enable transmit interrupt. */
    HAL_DISABLE_INTERRUPTS(int_state);
    HAL_DISABLE_INTERRUPTS(int_state);
    port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
    port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
    HAL_RESTORE_INTERRUPTS(int_state);
    HAL_RESTORE_INTERRUPTS(int_state);
 
 
    /* Enable the UART transmit. */
    /* Enable the UART transmit. */
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXRXEN);
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXRXEN);
 
 
        /* Send the character */
        /* Send the character */
    MCF5272_UART_WRITE(port->base->urb_utb, c);
    MCF5272_UART_WRITE(port->base->urb_utb, c);
 
 
        return true ;
        return true ;
}
}
 
 
 
 
/******************************************************************************************************
/******************************************************************************************************
 MCF5272_uart_getc() - Fetch a character from the device input bufferand return it to the alling
 MCF5272_uart_getc() - Fetch a character from the device input bufferand return it to the alling
                       routine. Wait until there is a character ready.
                       routine. Wait until there is a character ready.
 
 
 INPUT:
 INPUT:
    chan - pointer to the serial private data.
    chan - pointer to the serial private data.
 
 
 RETURN:
 RETURN:
    the character read from the UART.
    the character read from the UART.
 
 
 */
 */
static unsigned char MCF5272_uart_getc(serial_channel *chan)
static unsigned char MCF5272_uart_getc(serial_channel *chan)
{
{
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *)chan->dev_priv;
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *)chan->dev_priv;
 
 
    /* Wait until character has been received */
    /* Wait until character has been received */
 
 
        while (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_RXRDY))
        while (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_RXRDY))
    {
    {
        diag_printf("ready poll");
        diag_printf("ready poll");
    }
    }
 
 
    /* Read the character from the FIFO queue. */
    /* Read the character from the FIFO queue. */
 
 
    return MCF5272_UART_READ(port->base->urf);
    return MCF5272_UART_READ(port->base->urf);
 
 
}
}
 
 
 
 
/*******************************************************************************
/*******************************************************************************
 MCF5272_uart_set_config() - Set up the device characteristics; baud rate, etc.
 MCF5272_uart_set_config() - Set up the device characteristics; baud rate, etc.
 
 
 INPUT:
 INPUT:
    chan - pointer to the serial private data.
    chan - pointer to the serial private data.
    key  - configuration key (command).
    key  - configuration key (command).
    xbuf - pointer to the configuration buffer
    xbuf - pointer to the configuration buffer
    len  - the length of the configuration buffer
    len  - the length of the configuration buffer
 
 
 RETURN:
 RETURN:
    NOERR - If the configuration is successful
    NOERR - If the configuration is successful
    EINVAL -  If the argument is invalid
    EINVAL -  If the argument is invalid
 
 
*/
*/
 
 
Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
                            const void *xbuf, cyg_uint32 *len)
                            const void *xbuf, cyg_uint32 *len)
{
{
    cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
    cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
 
 
 
 
    switch (key) {
    switch (key) {
    case CYG_IO_SET_CONFIG_SERIAL_INFO:
    case CYG_IO_SET_CONFIG_SERIAL_INFO:
      {
      {
          /* Set serial configuration. */
          /* Set serial configuration. */
              if ( *len < sizeof(cyg_serial_info_t) ) {
              if ( *len < sizeof(cyg_serial_info_t) ) {
              return EINVAL;
              return EINVAL;
          }
          }
          *len = sizeof(cyg_serial_info_t);
          *len = sizeof(cyg_serial_info_t);
 
 
          if (!MCF5272_uart_config_port(chan, config))
          if (!MCF5272_uart_config_port(chan, config))
              return EINVAL;
              return EINVAL;
      }
      }
      break;
      break;
 
 
    case CYG_IO_GET_CONFIG_SERIAL_INFO:
    case CYG_IO_GET_CONFIG_SERIAL_INFO:
        // Retrieve UART configuration
        // Retrieve UART configuration
        *config = port->config;
        *config = port->config;
        break;
        break;
 
 
    default:
    default:
        return EINVAL;
        return EINVAL;
    }
    }
    return ENOERR;
    return ENOERR;
}
}
 
 
 
 
/*******************************************************************************
/*******************************************************************************
  MCF5272_uart_start_xmit() - Enable the transmitter on the device.
  MCF5272_uart_start_xmit() - Enable the transmitter on the device.
 
 
  INPUT:
  INPUT:
    chan - pointer to the serial private data.
    chan - pointer to the serial private data.
 
 
*/
*/
static void MCF5272_uart_start_xmit(serial_channel *chan)
static void MCF5272_uart_start_xmit(serial_channel *chan)
{
{
    CYG_INTERRUPT_STATE int_state;
    CYG_INTERRUPT_STATE int_state;
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
 
 
    /* Enable the UART transmit. */
    /* Enable the UART transmit. */
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXEN);
    MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXEN);
 
 
    /* Enable transmit interrupt */
    /* Enable transmit interrupt */
    HAL_DISABLE_INTERRUPTS(int_state);
    HAL_DISABLE_INTERRUPTS(int_state);
    port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
    port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
    HAL_RESTORE_INTERRUPTS(int_state);
    HAL_RESTORE_INTERRUPTS(int_state);
 
 
 
 
}
}
 
 
 
 
/******************************************************************************************************
/******************************************************************************************************
 MCF5272_uart_stop_xmit() - Disable the transmitter on the device
 MCF5272_uart_stop_xmit() - Disable the transmitter on the device
 
 
 INPUT:
 INPUT:
    chan - pointer to the serial private data.
    chan - pointer to the serial private data.
 
 
*/
*/
static void MCF5272_uart_stop_xmit(serial_channel * chan)
static void MCF5272_uart_stop_xmit(serial_channel * chan)
{
{
   CYG_INTERRUPT_STATE int_state;
   CYG_INTERRUPT_STATE int_state;
   MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
   MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
 
 
   /* Disable transmit interrupt */
   /* Disable transmit interrupt */
   HAL_DISABLE_INTERRUPTS(int_state);
   HAL_DISABLE_INTERRUPTS(int_state);
   port->imr_mirror &= ~MCF5272_UART_UIMR_TXRDY;
   port->imr_mirror &= ~MCF5272_UART_UIMR_TXRDY;
   MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
   MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
   HAL_RESTORE_INTERRUPTS(int_state);
   HAL_RESTORE_INTERRUPTS(int_state);
 
 
   /* Disable the UART transmit.
   /* Disable the UART transmit.
      !!!!!!!!!!!!!
      !!!!!!!!!!!!!
      !!!WARNING!!!
      !!!WARNING!!!
      !!!!!!!!!!!!!
      !!!!!!!!!!!!!
      If the transmit the disabe
      If the transmit the disabe
      the diag_printf routines will poll forever to transmit the
      the diag_printf routines will poll forever to transmit the
      a character. Hence, don't ever disable the transmit if
      a character. Hence, don't ever disable the transmit if
      we want it to work with diag_printf.
      we want it to work with diag_printf.
   */
   */
   //MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXDE);
   //MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXDE);
 
 
 
 
}
}
 
 
 
 
/******************************************************************************************************
/******************************************************************************************************
 MCF5272_uart_ISR() - UART I/O interrupt interrupt service routine (ISR).
 MCF5272_uart_ISR() - UART I/O interrupt interrupt service routine (ISR).
 
 
 INPUT:
 INPUT:
    vector - the interrupt vector number
    vector - the interrupt vector number
    data   - user parameter.
    data   - user parameter.
 
 
 
 
 RETURN:
 RETURN:
     returns CYG_ISR_CALL_DSR to call the DSR.
     returns CYG_ISR_CALL_DSR to call the DSR.
 
 
 */
 */
static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data)
static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
{
    serial_channel *chan = (serial_channel *) data;
    serial_channel *chan = (serial_channel *) data;
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
    MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
 
 
 
 
    /* Write the value in the interrupt status register back
    /* Write the value in the interrupt status register back
       to the mask register to disable the interrupt temporarily.
       to the mask register to disable the interrupt temporarily.
     */
     */
 
 
    MCF5272_UART_WRITE(port->base->uisr_uimr, 0);
    MCF5272_UART_WRITE(port->base->uisr_uimr, 0);
 
 
    return CYG_ISR_CALL_DSR;  // Cause DSR to run
    return CYG_ISR_CALL_DSR;  // Cause DSR to run
}
}
 
 
 
 
 
 
/******************************************************************************************************
/******************************************************************************************************
 MCF5272_uart_DSR() - Defered Service Routine (DSR) - This routine processes the interrupt
 MCF5272_uart_DSR() - Defered Service Routine (DSR) - This routine processes the interrupt
                      from the device.
                      from the device.
 
 
 INPUT:
 INPUT:
    vector - The interrupt vector number
    vector - The interrupt vector number
    count  - The nunber of DSR requests.
    count  - The nunber of DSR requests.
    data   - Device specific information
    data   - Device specific information
 
 
*/
*/
 
 
static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
{
    serial_channel *chan = (serial_channel *)data;
    serial_channel *chan = (serial_channel *)data;
    MCF5272_uart_info_t *port = (MCF5272_uart_info_t *)chan->dev_priv;
    MCF5272_uart_info_t *port = (MCF5272_uart_info_t *)chan->dev_priv;
    volatile u8_t isr;
    volatile u8_t isr;
 
 
 
 
    /* Retrieve the interrupt status bits. We use these status bits to figure out
    /* 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
       what process shouled we perform: read from the UART or inform of a completion
       of a data transmission.
       of a data transmission.
    */
    */
 
 
    /* Retrieve the interrupt status register so
    /* Retrieve the interrupt status register so
     * the DSR can look it up.
     * the DSR can look it up.
     */
     */
 
 
 
 
    while((isr = (MCF5272_UART_READ(port->base->uisr_uimr) & port->imr_mirror)))
    while((isr = (MCF5272_UART_READ(port->base->uisr_uimr) & port->imr_mirror)))
    {
    {
       switch (port->autobaud_state)
       switch (port->autobaud_state)
       {
       {
       default:
       default:
       case AB_IDLE:
       case AB_IDLE:
           if (isr & MCF5272_UART_UISR_DB)
           if (isr & MCF5272_UART_UISR_DB)
           {
           {
               /* Detected the begin of a break, set the state to AB_BEGIN_BREAK
               /* Detected the begin of a break, set the state to AB_BEGIN_BREAK
               */
               */
               port->autobaud_state = AB_BEGIN_BREAK;
               port->autobaud_state = AB_BEGIN_BREAK;
 
 
               /* Reset the Delta Break bit in the UISR */
               /* Reset the Delta Break bit in the UISR */
               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT);
               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT);
 
 
           }
           }
           break;
           break;
       case AB_BEGIN_BREAK:
       case AB_BEGIN_BREAK:
           if (isr & MCF5272_UART_UISR_DB)
           if (isr & MCF5272_UART_UISR_DB)
           {
           {
               /* Detected the end of a break, set the state to AB_BEGIN, and
               /* Detected the end of a break, set the state to AB_BEGIN, and
                  setup autobaud detection.
                  setup autobaud detection.
               */
               */
               port->autobaud_state = AB_BEGIN;
               port->autobaud_state = AB_BEGIN;
 
 
               /* Reset the Delta Break bit in the UISR and Enable autobaud */
               /* Reset the Delta Break bit in the UISR and Enable autobaud */
               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT |
               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT |
                                  MCF5272_UART_UCR_ENAB);
                                  MCF5272_UART_UCR_ENAB);
 
 
               /* Enable autobaud completion interrupt */
               /* Enable autobaud completion interrupt */
               port->imr_mirror |= MCF5272_UART_UIMR_ABC;
               port->imr_mirror |= MCF5272_UART_UIMR_ABC;
               /* Disable the delta break interrupt so we can't receive
               /* Disable the delta break interrupt so we can't receive
                  anymore break interrupt.
                  anymore break interrupt.
               */
               */
               port->imr_mirror &= ~MCF5272_UART_UIMR_DB;
               port->imr_mirror &= ~MCF5272_UART_UIMR_DB;
 
 
           }
           }
           break;
           break;
 
 
       case AB_BEGIN:
       case AB_BEGIN:
           if (isr & MCF5272_UART_UISR_ABC)
           if (isr & MCF5272_UART_UISR_ABC)
           {
           {
               int count;
               int count;
               // Retrieve the baudrate that we're using now.
               // Retrieve the baudrate that we're using now.
               u16_t divider = (port->base->uabu << 8) + port->base->uabl;
               u16_t divider = (port->base->uabu << 8) + port->base->uabl;
               // Search in the list to find a match.
               // Search in the list to find a match.
               for (count = sizeof(dividers_table)/sizeof(unsigned long) - 1;
               for (count = sizeof(dividers_table)/sizeof(unsigned long) - 1;
                    count >= 0;
                    count >= 0;
                    count--)
                    count--)
               {
               {
                   if (divider < dividers_table[count]) break;
                   if (divider < dividers_table[count]) break;
               }
               }
 
 
               // Set the baud.
               // Set the baud.
               port->config.baud = count;
               port->config.baud = count;
 
 
               /* Autobaud completion */
               /* Autobaud completion */
               port->autobaud_state = AB_IDLE;
               port->autobaud_state = AB_IDLE;
 
 
               /* Disable autobaud */
               /* Disable autobaud */
               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_NONE);
               MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_NONE);
 
 
               /* Ignore autobaud completion interrupt. */
               /* Ignore autobaud completion interrupt. */
               port->imr_mirror &= ~MCF5272_UART_UIMR_ABC;
               port->imr_mirror &= ~MCF5272_UART_UIMR_ABC;
 
 
               /* Reenable begin break change and receive interrupt. */
               /* Reenable begin break change and receive interrupt. */
               port->imr_mirror |= MCF5272_UART_UIMR_DB;
               port->imr_mirror |= MCF5272_UART_UIMR_DB;
 
 
           }
           }
           break;
           break;
 
 
       }
       }
 
 
 
 
        /* Receive character interrupt */
        /* Receive character interrupt */
        if ((isr & MCF5272_UART_UISR_RXRDY))
        if ((isr & MCF5272_UART_UISR_RXRDY))
            /* Ignore all receive interrupt when we're autobauding. */
            /* Ignore all receive interrupt when we're autobauding. */
        {
        {
            // Read all the characters in the fifo.
            // Read all the characters in the fifo.
            while ((MCF5272_UART_READ(port->base->uisr_uimr) & MCF5272_UART_UISR_RXRDY))
            while ((MCF5272_UART_READ(port->base->uisr_uimr) & MCF5272_UART_UISR_RXRDY))
            {
            {
                char c;
                char c;
                /* Read the character from the UART. */
                /* Read the character from the UART. */
                c = MCF5272_UART_READ(port->base->urb_utb);
                c = MCF5272_UART_READ(port->base->urb_utb);
                /* Pass the read character to the upper layer. */
                /* Pass the read character to the upper layer. */
                (chan->callbacks->rcv_char)(chan, c);
                (chan->callbacks->rcv_char)(chan, c);
            }
            }
        }
        }
 
 
        /* Transmit  complete interrupt */
        /* Transmit  complete interrupt */
 
 
        if ((isr & MCF5272_UART_UISR_TXRDY))
        if ((isr & MCF5272_UART_UISR_TXRDY))
        {
        {
 
 
            /*   Transmit holding register is empty                         */
            /*   Transmit holding register is empty                         */
           (chan->callbacks->xmt_char)(chan);
           (chan->callbacks->xmt_char)(chan);
 
 
        }
        }
 
 
    }
    }
 
 
    /*   Unmask all the DUART interrupts  that were masked  in the ISR,  so */
    /*   Unmask all the DUART interrupts  that were masked  in the ISR,  so */
    /* that we can receive the next interrupt.                              */
    /* that we can receive the next interrupt.                              */
 
 
    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
    MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
 
 
}
}
 
 
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
unsigned long MCF5272_uart_get_channel_0_baud_rate()
unsigned long MCF5272_uart_get_channel_0_baud_rate()
{
{
    /* return the baud rate for the first serial port */
    /* return the baud rate for the first serial port */
 
 
    return baud_rates_table[MCF5272_uart_channel_info_0.config.baud];
    return baud_rates_table[MCF5272_uart_channel_info_0.config.baud];
}
}
#endif
#endif
 
 
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
unsigned long MCF5272_uart_get_channel_1_baud_rate()
unsigned long MCF5272_uart_get_channel_1_baud_rate()
{
{
    /* return the baud rate for the second serial port */
    /* return the baud rate for the second serial port */
 
 
    return baud_rates_table[MCF5272_uart_channel_info_1.config.baud];
    return baud_rates_table[MCF5272_uart_channel_info_1.config.baud];
}
}
#endif
#endif
 
 
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.