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

Subversion Repositories openrisc_me

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/rtos/ecos-2.0/packages/devs/serial/mcf52xx/mcf5272
    from Rev 27 to Rev 174
    Reverse comparison

Rev 27 → Rev 174

/v2_0/cdl/ser_mcf5272_uart.cdl
0,0 → 1,142
# ====================================================================
#
# ser_MCF5272_uart.cdl
#
# eCos serial driver for MCF5272 UART
#
# ====================================================================
#####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####
# ====================================================================
 
cdl_package CYGPKG_IO_SERIAL_MCF5272_UART {
display "Serial driver for MCF5272 UART"
 
parent CYGPKG_IO_SERIAL_DEVICES
active_if CYGPKG_IO_SERIAL
requires CYGPKG_ERROR
include_dir cyg/io
description "
This option enables the serial device drivers for the
GMPU boards."
 
compile -library=libextras.a ser_mcf5272_uart.c
 
#define_proc {
# puts $::cdl_system_header "/***** serial driver proc output start *****/"
# puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_MCF52xx_ser_MFC5272_uart.h>"
# puts $::cdl_system_header "/***** serial driver proc output end *****/"
#}
 
 
cdl_component CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0 {
display "MCF5272 UART serial port 0 driver"
flavor bool
default_value 1
 
implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
implements CYGINT_IO_SERIAL_LINE_STATUS_HW
 
description "This option includes the serial device driver for the MCF5272 UART port 0."
 
cdl_option CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME {
display "Device name for the MCF5272 UART serial port 0 driver"
flavor data
default_value {"\"/dev/ser0\""}
description "
This option specifies the name of serial device for the
MCF5272 UART port 0."
}
 
cdl_option CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD {
display "Baud rate for the MCF5272 UART serial port 0 driver"
flavor data
legal_values {1200 2400 4800 9600 14400 19200 38400 115200}
default_value 9600
description "
This option specifies the default baud rate (speed) for the
MCF5272 UART port 0."
}
 
cdl_option CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE {
display "Buffer size for the MCF5272 UART serial port 0 driver"
flavor data
legal_values 0 to 8192
default_value 128
description "
This option specifies the size of the internal buffers used
for the MCF5272 UART port 0."
}
}
 
cdl_component CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1 {
display "MCF5272 UART serial port 1 driver"
flavor bool
default_value 0
 
implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
implements CYGINT_IO_SERIAL_LINE_STATUS_HW
 
description "This option includes the serial device driver for the MCF5272 UART port 1."
 
cdl_option CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME {
display "Device name for the MCF5272 UART serial port 1 driver"
flavor data
default_value {"\"/dev/ser1\""}
description "
This option specifies the name of serial device for the
MCF5272 UART port 1."
}
 
cdl_option CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BAUD {
display "Baud rate for the MCF5272 UART serial port 1 driver"
flavor data
legal_values {1200 2400 4800 9600 14400 19200 38400 115200}
default_value 9600
description "
This option specifies the default baud rate (speed) for the
MCF5272 UART port 1."
}
 
cdl_option CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE {
display "Buffer size for the MCF5272 UART serial port 1 driver"
flavor data
legal_values 0 to 8192
default_value 128
description "
This option specifies the size of the internal buffers used
for the MCF5272 UART port 1."
}
}
}
 
/v2_0/include/ser_mcf5272_uart.h
0,0 → 1,130
#ifndef _SER_MCF5272_H_
#define _SER_MCF5272_H_
//==========================================================================
//####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 <pkgconf/io_serial_mcf5272_uart.h>
 
/* Bit level definitions and macros */
#define MCF5272_UART_UMR1_RXRTS (0x80)
#define MCF5272_UART_UMR1_RXIRQ (0x40)
#define MCF5272_UART_UMR1_ERR (0x20)
#define MCF5272_UART_UMR1_PM_MULTI_ADDR (0x1C)
#define MCF5272_UART_UMR1_PM_MULTI_DATA (0x18)
#define MCF5272_UART_UMR1_PM_NONE (0x10)
#define MCF5272_UART_UMR1_PM_FORCE_HI (0x0C)
#define MCF5272_UART_UMR1_PM_FORCE_LO (0x08)
#define MCF5272_UART_UMR1_PM_ODD (0x04)
#define MCF5272_UART_UMR1_PM_EVEN (0x00)
#define MCF5272_UART_UMR1_BC_5 (0x00)
#define MCF5272_UART_UMR1_BC_6 (0x01)
#define MCF5272_UART_UMR1_BC_7 (0x02)
#define MCF5272_UART_UMR1_BC_8 (0x03)
 
#define MCF5272_UART_UMR2_CM_NORMAL (0x00)
#define MCF5272_UART_UMR2_CM_ECHO (0x40)
#define MCF5272_UART_UMR2_CM_LOCAL_LOOP (0x80)
#define MCF5272_UART_UMR2_CM_REMOTE_LOOP (0xC0)
#define MCF5272_UART_UMR2_TXRTS (0x20)
#define MCF5272_UART_UMR2_TXCTS (0x10)
#define MCF5272_UART_UMR2_STOP_BITS_1 (0x07)
#define MCF5272_UART_UMR2_STOP_BITS_15 (0x08)
#define MCF5272_UART_UMR2_STOP_BITS_2 (0x0F)
#define MCF5272_UART_UMR2_STOP_BITS(a) ((a)&0x0f) /* Stop Bit Length */
 
//#define MCF5272_UART_USR_RB (0x80)
//#define MCF5272_UART_USR_FE (0x40)
//#define MCF5272_UART_USR_PE (0x20)
//#define MCF5272_UART_USR_OE (0x10)
//#define MCF5272_UART_USR_TXEMP (0x08)
//#define MCF5272_UART_USR_TXRDY (0x04)
#define MCF5272_UART_USR_FFULL (0x02)
#define MCF5272_UART_USR_RXRDY (0x01)
 
#define MCF5272_UART_UCSR_RCS(a) (((a)&0x0f)<<4) /* Rx Clk Select */
#define MCF5272_UART_UCSR_TCS(a) ((a)&0x0f) /* Tx Clk Select */
 
 
#define MCF5272_UART_UCR_NONE (0x00)
#define MCF5272_UART_UCR_ENAB (0x80)
#define MCF5272_UART_UCR_STOP_BREAK (0x70)
#define MCF5272_UART_UCR_START_BREAK (0x60)
#define MCF5272_UART_UCR_RESET_BKCHGINT (0x50)
#define MCF5272_UART_UCR_RESET_ERROR (0x40)
#define MCF5272_UART_UCR_RESET_TX (0x30)
#define MCF5272_UART_UCR_RESET_RX (0x20)
#define MCF5272_UART_UCR_RESET_MR (0x10)
#define MCF5272_UART_UCR_TX_DISABLED (0x08)
#define MCF5272_UART_UCR_TX_ENABLED (0x04)
#define MCF5272_UART_UCR_RX_DISABLED (0x02)
#define MCF5272_UART_UCR_RX_ENABLED (0x01)
 
#define MCF5272_UART_UCCR_COS (0x10)
#define MCF5272_UART_UCCR_CTS (0x01)
 
#define MCF5272_UART_UACR_BRG (0x80)
#define MCF5272_UART_UACR_CTMS_TIMER (0x60)
#define MCF5272_UART_UACR_IEC (0x01)
 
#define MCF5272_UART_UISR_COS (0x80)
#define MCF5272_UART_UISR_ABC (0x40)
#define MCF5272_UART_UISR_DB (0x04)
#define MCF5272_UART_UISR_RXRDY (0x02)
#define MCF5272_UART_UISR_TXRDY (0x01)
 
#define MCF5272_UART_UIMR_COS (0x80)
#define MCF5272_UART_UIMR_ABC (0x40)
#define MCF5272_UART_UIMR_DB (0x04)
#define MCF5272_UART_UIMR_FFULL (0x02)
#define MCF5272_UART_UIMR_TXRDY (0x01)
 
typedef unsigned char uint8; /* 8 bits */
typedef unsigned short int uint16; /* 16 bits */
typedef unsigned long int uint32; /* 32 bits */
 
typedef signed char int8; /* 8 bits */
typedef signed short int int16; /* 16 bits */
typedef signed long int int32; /* 32 bits */
 
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
unsigned long MCF5272_uart_get_channel_0_baud_rate(void);
#endif /* CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0 */
 
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
unsigned long MCF5272_uart_get_channel_1_baud_rate(void);
#endif /* CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1 */
 
#endif /* _SER_MCF5272_H_ */
 
/v2_0/src/ser_mcf5272_uart.c
0,0 → 1,946
//==========================================================================
//
// 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
);
#endif
 
DEVTAB_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)
);
 
#else
static 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
);
#endif
DEVTAB_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
UART driver.
 
INPUT:
Pointer to the the device table.
 
RETURN:
Returns true if the initialization is successful. Otherwise, it retuns false
*/
static bool MCF5272_uart_init(struct cyg_devtab_entry * tab)
{
serial_channel *chan = (serial_channel *)tab->priv;
MCF5272_uart_info_t *MCF5272_uart_chan = (MCF5272_uart_info_t *)chan->dev_priv;
 
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
 
/* Instantiation of the UART channel 0 data strucutre. This data */
/* structure contains channel information. */
 
if (strcmp(tab->name, CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME) == 0)
{
 
/* Initiliaze the UART information data to all zeros. */
 
memset(MCF5272_uart_chan, sizeof(MCF5272_uart_info_t), 0);
 
/* Set the base address of the UART registers to differentiate */
/* itself from the different regusters for the other UART port. */
 
MCF5272_uart_chan->base = (mcf5272_sim_uart_t*)&MCF5272_SIM->uart[0];
 
/* Set the UART interrupt vector number. */
 
MCF5272_uart_chan->uart_vector = CYGNUM_HAL_VECTOR_UART1;
 
/* Set the autobaud state to idle. */
 
MCF5272_uart_chan->autobaud_state = AB_IDLE;
 
/* Initilize the UART 0 output pins */
 
MCF5272_SIM->gpio.pbcnt = MCF5272_GPIO_PBCNT_URT0_EN |
((MCF5272_SIM->gpio.pbcnt) & ~MCF5272_GPIO_PBCNT_URT0_MSK);
}
#endif
 
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
 
/* Instantiation of the UART channel 1 data strucutre. This data structure contains
channel information.
*/
if (strcmp(tab->name, CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME) == 0)
{
 
/* Initiliaze the UART information data to all zeros. */
 
memset(MCF5272_uart_chan, sizeof(MCF5272_uart_info_t), 0);
 
/* Set the base address of the UART registers to differentiate */
/* itself from the different regusters for the other UART port. */
 
MCF5272_uart_chan->base = (mcf5272_sim_uart_t*)&MCF5272_SIM->uart[1];
 
/* Set the UART interrupt vector number. */
 
MCF5272_uart_chan->uart_vector = CYGNUM_HAL_VECTOR_UART2;
 
/* Set the autobaud state to idle. */
 
MCF5272_uart_chan->autobaud_state = AB_IDLE;
 
/* Initilize the UART 1 output pins */
 
MCF5272_SIM->gpio.pdcnt = MCF5272_GPIO_PDCNT_URT1_EN |
((MCF5272_SIM->gpio.pdcnt) & ~MCF5272_GPIO_PDCNT_URT1_MSK);
 
}
#endif
 
 
if (chan->out_cbuf.len > 0) {
 
/* If the the buffer is greater than zero, then the driver will */
/* use interrupt driven I/O. Hence, the driver creates an */
/* interrupt context for the UART device. */
 
cyg_drv_interrupt_create(MCF5272_uart_chan->uart_vector,
MCF5272_UART_PRIORITY_LEVEL, // Priority - Level 2
(cyg_addrword_t)chan, // Data item passed to interrupt handler
MCF5272_uart_ISR,
MCF5272_uart_DSR,
&MCF5272_uart_chan->serial_interrupt_handle,
&MCF5272_uart_chan->serial_interrupt);
 
cyg_drv_interrupt_attach(MCF5272_uart_chan->serial_interrupt_handle);
 
(chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
}
 
// Configure Serial device.
return(MCF5272_uart_config_port(chan, &chan->config));
}
 
/******************************************************************************************************
MCF5272_uart_config_port() - Configure the UART port.
 
Internal function to actually configure the hardware to desired baud rate, etc.
 
INPUT:
chan - The channel information
new_confg - The port configuration which include the desired baud rate, etc.
 
RETURN:
Returns true if the port configuration is successful. Otherwise, it retuns false
 
*/
static bool MCF5272_uart_config_port(serial_channel *chan,
cyg_serial_info_t *new_config)
{
MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
uint8 mode_reg = 0;
uint32 ubgs;
unsigned int baud_divisor;
 
 
/* Get the divisor from the baudrate table which will use to */
/* configure the port's baud rate. */
 
baud_divisor = baud_rates_table[new_config->baud];
 
/* If the divisor is zeor, we dont' configure the port. */
 
if (baud_divisor == 0) return false;
 
/* Save the configuration value for later use. */
 
port->config = *new_config;
 
/* We first write the reset values into the device and then configure */
/* the device the we way we want to use it. */
/* Reset Transmitter */
 
MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_TX);
 
/* Reset Receiver */
MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_RX);
 
/* Reset Mode Register */
MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_MR);
 
/* Translate the parity configuration to UART mode bits. */
 
switch(port->config.parity)
{
default:
case CYGNUM_SERIAL_PARITY_NONE:
mode_reg = 0 | MCF5272_UART_UMR1_PM_NONE;
break;
case CYGNUM_SERIAL_PARITY_EVEN:
mode_reg = 0 | MCF5272_UART_UMR1_PM_EVEN;
break;
case CYGNUM_SERIAL_PARITY_ODD:
mode_reg = 0 | MCF5272_UART_UMR1_PM_ODD;
break;
case CYGNUM_SERIAL_PARITY_MARK:
mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_HI;
break;
case CYGNUM_SERIAL_PARITY_SPACE:
mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_LO;
break;
}
 
/* Translate the number of bits per character configuration to UART mode bits. */
 
switch(port->config.word_length)
{
 
case CYGNUM_SERIAL_WORD_LENGTH_5:
mode_reg |= MCF5272_UART_UMR1_BC_5;
break;
case CYGNUM_SERIAL_WORD_LENGTH_6:
mode_reg |= MCF5272_UART_UMR1_BC_6;
break;
case CYGNUM_SERIAL_WORD_LENGTH_7:
mode_reg |= MCF5272_UART_UMR1_BC_7;
break;
default:
case CYGNUM_SERIAL_WORD_LENGTH_8:
mode_reg |= MCF5272_UART_UMR1_BC_8;
break;
}
 
/* Configure the parity and the bits per character */
MCF5272_UART_WRITE(port->base->umr, mode_reg);
 
/* Translate the stop bit length to UART mode bits. */
 
switch(port->config.stop)
{
default:
case CYGNUM_SERIAL_STOP_1:
mode_reg = MCF5272_UART_UMR2_STOP_BITS_1;
break;
case CYGNUM_SERIAL_STOP_1_5:
mode_reg = MCF5272_UART_UMR2_STOP_BITS_15;
break;
case CYGNUM_SERIAL_STOP_2:
mode_reg = MCF5272_UART_UMR2_STOP_BITS_2;
break;
}
 
/* No echo or loopback */
MCF5272_UART_WRITE(port->base->umr, 0 | MCF5272_UART_UMR2_CM_NORMAL | mode_reg);
 
/* Set Rx and Tx baud by timer */
MCF5272_UART_WRITE(port->base->ucr, 0 | MCF5272_UART_UCSR_RCS(0xD) |
MCF5272_UART_UCSR_TCS(0xD));
 
/* Mask all USART interrupts */
MCF5272_UART_WRITE(port->base->uisr_uimr, 0);
 
/* Calculate baud settings */
ubgs = (uint16)((CYGHWR_HAL_SYSTEM_CLOCK_MHZ*1000000)/
(baud_divisor * 32));
 
/* Program the baud settings to the device. */
 
MCF5272_UART_WRITE(port->base->udu, (uint8)((ubgs & 0xFF00) >> 8));
MCF5272_UART_WRITE(port->base->udl, (uint8)(ubgs & 0x00FF));
 
/* Enable receiver and transmitter */
 
MCF5272_UART_WRITE(port->base->ucr, 0 | MCF5272_UART_UCR_TXRXEN);
 
/* Enable both transmit and receive interrupt. */
 
port->imr_mirror = MCF5272_UART_UIMR_TXRDY | MCF5272_UART_UIMR_FFULL |
MCF5272_UART_UIMR_DB;
MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
 
return true; /* Returns true to indicate a successful configuration */
 
}
 
/*******************************************************************************
MCF5272_uart_lookup() - This routine is called when the device is "looked" up
(i.e. attached)
 
INPUT:
tab - pointer to a pointer of the device table
sub_tab - Pointer to the sub device table.
name - name of the device
 
RETURN:
always return ENOERR
 
*/
static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name)
{
serial_channel *chan = (serial_channel *)(*tab)->priv;
(chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
return ENOERR;
}
 
/*******************************************************************************
MCF5272_uart_putc() - Send a character to the device output buffer.
 
INPUT:
chan - pointer to the serial private data.
c - the character to output
 
RETURN:
'true' if character is sent to device, return 'false' when we've
ran out of buffer space in the device itself.
 
*/
 
static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c)
{
CYG_INTERRUPT_STATE int_state;
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. */
if (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_TXRDY))
return false;
 
/* 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);
 
/* Enable the UART transmit. */
MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXRXEN);
 
/* Send the character */
MCF5272_UART_WRITE(port->base->urb_utb, c);
 
return true ;
}
 
 
/******************************************************************************************************
MCF5272_uart_getc() - Fetch a character from the device input bufferand return it to the alling
routine. Wait until there is a character ready.
 
INPUT:
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_CHANNEL0
unsigned 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_CHANNEL1
unsigned 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
 
 
/v2_0/ChangeLog
0,0 → 1,38
2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
 
* cdl/ser_mcf5272_uart.cdl: Remove irrelevant doc link.
 
//===========================================================================
//####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####
//===========================================================================

powered by: WebSVN 2.1.0

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