mn10300_serial.c
来自「开放源码实时操作系统源码.」· C语言 代码 · 共 1,037 行 · 第 1/3 页
C
1,037 行
//==========================================================================
//
// mn10300_serial.c
//
// Serial device driver for mn10300 on-chip serial devices
//
//==========================================================================
//####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####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 1999-02-25
// Purpose: MN10300 serial device driver
// Description: MN10300 serial device driver
//
//####DESCRIPTIONEND####
//
//==========================================================================
#include <pkgconf/hal.h>
#include <pkgconf/io_serial.h>
#include <cyg/hal/hal_io.h>
#include <cyg/io/io.h>
#include <cyg/io/devtab.h>
#include <cyg/io/serial.h>
#include <cyg/hal/hal_intr.h>
#ifdef CYGPKG_IO_SERIAL_MN10300
#define CYG_HAL_MN10300_SERIAL_RX_FIFO
//-------------------------------------------------------------------------
extern void diag_printf(const char *fmt, ...);
//-------------------------------------------------------------------------
// Forward definitions
static bool mn10300_serial_init(struct cyg_devtab_entry *tab);
static bool mn10300_serial_putc(serial_channel *chan, unsigned char c);
static Cyg_ErrNo mn10300_serial_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name);
static unsigned char mn10300_serial_getc(serial_channel *chan);
static Cyg_ErrNo mn10300_serial_set_config(serial_channel *chan, cyg_uint32 key,
const void *xbuf, cyg_uint32 *len);
static void mn10300_serial_start_xmit(serial_channel *chan);
static void mn10300_serial_stop_xmit(serial_channel *chan);
#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
static cyg_uint32 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
static cyg_uint32 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
static void mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
static void mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
#endif
//-------------------------------------------------------------------------
#define BUFSIZE 128
//-------------------------------------------------------------------------
// MN10300 serial line control register values:
// Offsets to serial control registers from base
#define SERIAL_CTR 0x0
#define SERIAL_ICR 0x4
#define SERIAL_TXB 0x8
#define SERIAL_RXB 0x9
#define SERIAL_STR 0xc
#define SERIAL_TIM 0xd
// Status register bits
#define SR_RBF 0x10
#define SR_TBF 0x20
#define SR_RXF 0x40
#define SR_TXF 0x80
// Control register bits
#define LCR_SB1 0x00
#define LCR_SB1_5 0x00
#define LCR_SB2 0x04
#define LCR_PN 0x00 // Parity mode - none
#define LCR_PS 0x40 // Forced "space" parity
#define LCR_PM 0x50 // Forced "mark" parity
#define LCR_PE 0x60 // Parity mode - even
#define LCR_PO 0x70 // Parity mode - odd
#define LCR_WL5 0x00 // not supported - use 7bit
#define LCR_WL6 0x00 // not supported - use 7bit
#define LCR_WL7 0x00 // 7 bit chars
#define LCR_WL8 0x80 // 8 bit chars
#define LCR_RXE 0x4000 // receive enable
#define LCR_TXE 0x8000 // transmit enable
#if defined(CYGPKG_HAL_MN10300_AM31)
#define LCR_TWE 0x0100 // interrupt enable (only on serial2/AM31)
#else
#define LCR_TWE 0x0000 // Bit does not exist in other variants
#endif
//-------------------------------------------------------------------------
// MN10300 timer registers:
#undef TIMER_BR
#undef TIMER_MD
#define TIMER_MD 0x00
#define TIMER_BR 0x10
//-------------------------------------------------------------------------
// Serial and timer base registers:
#if defined(CYGPKG_HAL_MN10300_AM31)
#define SERIAL0_BASE 0x34000800
#define SERIAL1_BASE 0x34000810
#define SERIAL2_BASE 0x34000820
#define TIMER0_BASE 0x34001000
#define TIMER1_BASE 0x34001001
#define TIMER2_BASE 0x34001002
#define SERIAL0_TIMER_SELECT 0x0004 // timer 0
#define SERIAL1_TIMER_SELECT 0x0004 // timer 1
#define SERIAL2_TIMER_SELECT 0x0001 // timer 2
#ifdef CYGPKG_HAL_MN10300_AM31_STDEVAL1
// The use of PORT3 to provide CTS/CTR is specific to
// the STDEVAL1 board only.
#define PORT3_MD 0x36008025
#endif
#define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) \
CYG_MACRO_START \
if( mn10300_chan->is_serial2 ) \
cr |= LCR_TWE; \
else \
cr |= LCR_TXE; \
CYG_MACRO_END
#define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) \
CYG_MACRO_START \
if( mn10300_chan->is_serial2 ) \
cr &= ~LCR_TWE; \
else \
cr &= ~LCR_TXE; \
CYG_MACRO_END
#elif defined(CYGPKG_HAL_MN10300_AM33)
#define SERIAL0_BASE 0xd4002000
#define SERIAL1_BASE 0xd4002010
#define SERIAL2_BASE 0xd4002020
#define TIMER0_BASE 0xd4003002
#define TIMER1_BASE 0xd4003001
#define TIMER2_BASE 0xd4003003
#define SERIAL0_TIMER_SELECT 0x0005 // timer 2
#define SERIAL1_TIMER_SELECT 0x0004 // timer 1
#define SERIAL2_TIMER_SELECT 0x0003 // timer 3
#define HW_TIMER0 0xd4003000
#define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan)
#define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan)
#else
#error Unsupported MN10300 variant
#endif
//-------------------------------------------------------------------------
// Tables to map input values to hardware settings
static unsigned char select_word_length[] = {
LCR_WL5, // 5 bits / word (char)
LCR_WL6,
LCR_WL7,
LCR_WL8
};
static unsigned char select_stop_bits[] = {
0,
LCR_SB1, // 1 stop bit
LCR_SB1_5, // 1.5 stop bit
LCR_SB2 // 2 stop bits
};
static unsigned char select_parity[] = {
LCR_PN, // No parity
LCR_PE, // Even parity
LCR_PO, // Odd parity
LCR_PM, // Mark parity
LCR_PS, // Space parity
};
#if defined(CYGPKG_HAL_MN10300_AM31)
static unsigned short select_baud_01[] = {
0, // Unused
0, // 50
0, // 75
0, // 110
0, // 134.5
0, // 150
0, // 200
0, // 300
0, // 600
0, // 1200
0, // 1800
0, // 2400
0, // 3600
0, // 4800
0, // 7200
195, // 9600
130, // 14400
98, // 19200
48, // 38400
32, // 57600
16, // 115200
8, // 230400
};
// Serial 2 has its own timer register in addition to using timer 2 to
// supply the baud rate generator. Both of these must be proframmed to
// get the right baud rate. The following values come from Matsushita
// with some modifications from Cygmon.
static struct
{
cyg_uint8 serial2_val;
cyg_uint8 timer2_val;
} select_baud_2[] = {
{ 0, 0 }, // Unused
{ 0, 0 }, // 50
{ 0, 0 }, // 75
{ 0, 0 }, // 110
{ 0, 0 }, // 134.5
{ 0, 0 }, // 150
{ 0, 0 }, // 200
{ 0, 0 }, // 300
{ 126, 196 }, // 600
{ 125, 98 }, // 1200
{ 0, 0 }, // 1800
{ 124, 49 }, // 2400
{ 0, 0 }, // 3600
{ 124, 24 }, // 4800
{ 0, 0 }, // 7200
{ 70, 21 }, // 9600
{ 0, 0 }, // 14400
{ 70, 10 }, // 19200
{ 22, 16 }, // 38400
{ 88, 2 }, // 57600
{ 64, 1 }, // 115200
{ 62, 0 }, // 230400
};
#elif defined(CYGPKG_HAL_MN10300_AM33)
// The AM33 runs at a different clock rate and therefore has a
// different set of dividers for the baud rate.
static unsigned short select_baud_01[] = {
0, // Unused
0, // 50
0, // 75
0, // 110
0, // 134.5
0, // 150
0, // 200
0, // 300
0, // 600
3168, // 1200
0, // 1800
1584, // 2400
0, // 3600
792, // 4800
0, // 7200
396, // 9600
0, // 14400
198, // 19200
99, // 38400
0, // 57600
33, // 115200
16, // 230400
};
// Serial 2 has its own timer register in addition to using timer 2 to
// supply the baud rate generator. Both of these must be proframmed to
// get the right baud rate. The following values come from Matsushita
// with some modifications from Cygmon.
// The values in the following table differ significantly from those
// given in the Matsushita documentation. These have been determined
// by (somewhat exhaustive) experiment, the values in the documentation
// do not appear to work at all.
static struct
{
cyg_uint8 serial2_val;
cyg_uint8 timer2_val;
} select_baud_2[] = {
{ 0, 0 }, // Unused
{ 0, 0 }, // 50
{ 0, 0 }, // 75
{ 0, 0 }, // 110
{ 0, 0 }, // 134.5
{ 0, 0 }, // 150
{ 0, 0 }, // 200
{ 0, 0 }, // 300
{ 0, 0 }, // 600
{ 0, 0 }, // 1200
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?