From 00717a385ba72955a3119353d0b65767ed7fa39b Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 26 Oct 2001 19:32:40 +0000 Subject: 2001-10-26 Victor V. Vengerov * New libcpu support for mcf5206e. * ChangeLog, clock/ckinit.c, clock/.cvsignore, configure.ac, console/mcfuart.c, console/.cvsignore, include/mcf5206e.h, include/mcfmbus.h, include/mcfuart.h, include/.cvsignore, mbus/mcfmbus.c, mbus/.cvsignore, timer/timer.c, timer/timerisr.S, timer/.cvsignore, .cvsignore: New files. --- c/src/lib/libcpu/m68k/mcf5206/.cvsignore | 1 + c/src/lib/libcpu/m68k/mcf5206/ChangeLog | 9 + c/src/lib/libcpu/m68k/mcf5206/clock/.cvsignore | 2 + c/src/lib/libcpu/m68k/mcf5206/clock/ckinit.c | 218 ++++++++ c/src/lib/libcpu/m68k/mcf5206/configure.ac | 37 ++ c/src/lib/libcpu/m68k/mcf5206/console/.cvsignore | 2 + c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c | 570 +++++++++++++++++++++ c/src/lib/libcpu/m68k/mcf5206/include/.cvsignore | 2 + c/src/lib/libcpu/m68k/mcf5206/include/mcf5206e.h | 613 ++++++++++++++++++++++ c/src/lib/libcpu/m68k/mcf5206/include/mcfmbus.h | 131 +++++ c/src/lib/libcpu/m68k/mcf5206/include/mcfuart.h | 113 +++++ c/src/lib/libcpu/m68k/mcf5206/mbus/.cvsignore | 2 + c/src/lib/libcpu/m68k/mcf5206/mbus/mcfmbus.c | 615 +++++++++++++++++++++++ c/src/lib/libcpu/m68k/mcf5206/timer/.cvsignore | 2 + c/src/lib/libcpu/m68k/mcf5206/timer/timer.c | 175 +++++++ c/src/lib/libcpu/m68k/mcf5206/timer/timerisr.S | 49 ++ 16 files changed, 2541 insertions(+) create mode 100644 c/src/lib/libcpu/m68k/mcf5206/.cvsignore create mode 100644 c/src/lib/libcpu/m68k/mcf5206/ChangeLog create mode 100644 c/src/lib/libcpu/m68k/mcf5206/clock/.cvsignore create mode 100644 c/src/lib/libcpu/m68k/mcf5206/clock/ckinit.c create mode 100644 c/src/lib/libcpu/m68k/mcf5206/configure.ac create mode 100644 c/src/lib/libcpu/m68k/mcf5206/console/.cvsignore create mode 100644 c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c create mode 100644 c/src/lib/libcpu/m68k/mcf5206/include/.cvsignore create mode 100644 c/src/lib/libcpu/m68k/mcf5206/include/mcf5206e.h create mode 100644 c/src/lib/libcpu/m68k/mcf5206/include/mcfmbus.h create mode 100644 c/src/lib/libcpu/m68k/mcf5206/include/mcfuart.h create mode 100644 c/src/lib/libcpu/m68k/mcf5206/mbus/.cvsignore create mode 100644 c/src/lib/libcpu/m68k/mcf5206/mbus/mcfmbus.c create mode 100644 c/src/lib/libcpu/m68k/mcf5206/timer/.cvsignore create mode 100644 c/src/lib/libcpu/m68k/mcf5206/timer/timer.c create mode 100644 c/src/lib/libcpu/m68k/mcf5206/timer/timerisr.S (limited to 'c/src/lib') diff --git a/c/src/lib/libcpu/m68k/mcf5206/.cvsignore b/c/src/lib/libcpu/m68k/mcf5206/.cvsignore new file mode 100644 index 0000000000..d89921897a --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/.cvsignore @@ -0,0 +1 @@ +autom4te.cache diff --git a/c/src/lib/libcpu/m68k/mcf5206/ChangeLog b/c/src/lib/libcpu/m68k/mcf5206/ChangeLog new file mode 100644 index 0000000000..00cc766e6a --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/ChangeLog @@ -0,0 +1,9 @@ +2001-10-26 Victor V. Vengerov + + * New libcpu support for mcf5206e. + * ChangeLog, clock/ckinit.c, clock/.cvsignore, configure.ac, + console/mcfuart.c, console/.cvsignore, include/mcf5206e.h, + include/mcfmbus.h, include/mcfuart.h, include/.cvsignore, + mbus/mcfmbus.c, mbus/.cvsignore, timer/timer.c, timer/timerisr.S, + timer/.cvsignore, .cvsignore: New files. + diff --git a/c/src/lib/libcpu/m68k/mcf5206/clock/.cvsignore b/c/src/lib/libcpu/m68k/mcf5206/clock/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/clock/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libcpu/m68k/mcf5206/clock/ckinit.c b/c/src/lib/libcpu/m68k/mcf5206/clock/ckinit.c new file mode 100644 index 0000000000..b12de753e4 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/clock/ckinit.c @@ -0,0 +1,218 @@ +/* + * Clock Driver for MCF5206eLITE board + * + * This driver initailizes timer1 on the MCF5206E as the + * main system clock + * + * Author: Victor V. Vengerov + * + * Based on work: + * David Fiddes, D.J@fiddes.surfaid.org + * http://www.calm.hw.ac.uk/davidf/coldfire/ + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include "mcf5206/mcf5206e.h" + +/* + * Clock_driver_ticks is a monotonically increasing counter of the + * number of clock ticks since the driver was initialized. + */ +volatile rtems_unsigned32 Clock_driver_ticks; + + +/* + * These are set by clock driver during its init + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + +rtems_isr (*rtems_clock_hook)(rtems_vector_number) = NULL; + +/* Clock_isr -- + * This handles the timer interrupt by clearing the timer's interrupt + * flag and announcing the clock tick to the system. + * + * PARAMETERS: + * vector - timer interrupt vector number + * + * RETURNS: + * none + */ +rtems_isr +Clock_isr (rtems_vector_number vector) +{ + /* Clear pending interrupt... */ + *MCF5206E_TER(MBAR,1) = MCF5206E_TER_REF | MCF5206E_TER_CAP; + + /* Announce the clock tick */ + Clock_driver_ticks++; + rtems_clock_tick(); + if (rtems_clock_hook != NULL) + rtems_clock_hook(vector); +} + + +/* Clock_exit -- + * This shuts down the timer if it was enabled and removes it + * from the MCF5206E interrupt mask. + * + * PARAMETERS: + * none + * + * RETURNS: + * none + */ +void +Clock_exit(void) +{ + if (BSP_Configuration.ticks_per_timeslice) + { + /* disable all timer1 interrupts */ + *MCF5206E_IMR(MBAR) |= MCF5206E_INTR_BIT(MCF5206E_INTR_TIMER_1); + + /* reset timer1 */ + *MCF5206E_TMR(MBAR,1) = MCF5206E_TMR_ICLK_STOP; + + /* clear pending */ + *MCF5206E_TER(MBAR,1) = MCF5206E_TER_REF | MCF5206E_TER_CAP; + } +} + + +/* Install_clock -- + * This initialises timer1 with the BSP timeslice config value + * as a reference and sets up the interrupt handler for clock ticks. + * + * PARAMETERS: + * clock_isr - clock interrupt handler routine + * + * RETURNS: + * none. + */ +static void +Install_clock(rtems_isr_entry clock_isr) +{ + Clock_driver_ticks = 0; + if (BSP_Configuration.ticks_per_timeslice) + { + /* Configure timer1 interrupts */ + *MCF5206E_ICR(MBAR,MCF5206E_INTR_TIMER_1) = + MCF5206E_ICR_AVEC | + ((BSP_INTLVL_TIMER1 << MCF5206E_ICR_IL_S) & MCF5206E_ICR_IL) | + ((BSP_INTPRIO_TIMER1 << MCF5206E_ICR_IP_S) & MCF5206E_ICR_IP); + + /* Register the interrupt handler */ + set_vector(clock_isr, BSP_INTVEC_TIMER1, 1); + + /* Reset timer 1 */ + *MCF5206E_TMR(MBAR, 1) = MCF5206E_TMR_RST; + *MCF5206E_TMR(MBAR, 1) = MCF5206E_TMR_ICLK_STOP; + *MCF5206E_TMR(MBAR, 1) = MCF5206E_TMR_RST; + *MCF5206E_TCN(MBAR, 1) = 0; /* Reset counter */ + *MCF5206E_TER(MBAR, 1) = MCF5206E_TER_REF | MCF5206E_TER_CAP; + + /* Set Timer 1 prescaler so that it counts in microseconds */ + *MCF5206E_TMR(MBAR, 1) = + (((BSP_SYSTEM_FREQUENCY/1000000 - 1) << MCF5206E_TMR_PS_S) & + MCF5206E_TMR_PS) | + MCF5206E_TMR_CE_NONE | MCF5206E_TMR_ORI | MCF5206E_TMR_FRR | + MCF5206E_TMR_RST; + + /* Set the timer timeout value from the BSP config */ + *MCF5206E_TRR(MBAR, 1) = BSP_Configuration.microseconds_per_tick - 1; + + /* Feed system frequency to the timer */ + *MCF5206E_TMR(MBAR, 1) |= MCF5206E_TMR_ICLK_MSCLK; + + /* Enable timer 1 interrupts */ + *MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(MCF5206E_INTR_TIMER_1); + + /* Register the driver exit procedure so we can shutdown */ + atexit(Clock_exit); + } +} + + +/* Clock_initialize -- + * This is called to setup the clock driver. It calls the hardware + * setup function and make the driver major/minor values available + * for other. + * + * PARAMETERS: + * major - clock device major number + * minor - clock device minor number + * pargp - device driver initialization argument (not used) + * + * RETURNS: + * RTEMS status code + */ +rtems_device_driver +Clock_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp) +{ + Install_clock (Clock_isr); + + /* Make major/minor avail to others such as shared memory driver */ + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} + + +/* Clock_control -- + * I/O control (IOCTL) function for Clock driver. At this moment this + * just runs the interrupt handler or re-registers the interrupt handler + * on request. + * + * PARAMETERS: + * major - clock major device number + * minor - clock minor device number + * pargp - pointer to IOCTL arguments + * + * RETURNS: + * RTEMS status code + */ +rtems_device_driver +Clock_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp) +{ + rtems_unsigned32 isrlevel; + rtems_libio_ioctl_args_t *args = pargp; + + if (args) + { + /* + * This is hokey, but until we get a defined interface + * to do this, it will just be this simple... + */ + if (args->command == rtems_build_name('I', 'S', 'R', ' ')) + { + Clock_isr(BSP_INTVEC_TIMER1); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + rtems_interrupt_disable( isrlevel ); + (void) set_vector( args->buffer, BSP_INTVEC_TIMER1, 1 ); + rtems_interrupt_enable( isrlevel ); + } + } + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libcpu/m68k/mcf5206/configure.ac b/c/src/lib/libcpu/m68k/mcf5206/configure.ac new file mode 100644 index 0000000000..437ce6ee61 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/configure.ac @@ -0,0 +1,37 @@ +## Process this file with autoconf to produce a configure script. +## +## $Id$ + +AC_PREREQ(2.52) +AC_INIT +AC_CONFIG_SRCDIR([include]) +RTEMS_TOP(../../../../../..) +AC_CONFIG_AUX_DIR(../../../../../..) + +RTEMS_CANONICAL_TARGET_CPU + +AM_INIT_AUTOMAKE(rtems-c-src-lib-libcpu-m68k-mcf5206,$RTEMS_VERSION,no) +AM_MAINTAINER_MODE + +RTEMS_ENABLE_BARE +RTEMS_ENV_RTEMSBSP + +RTEMS_CHECK_CPU +RTEMS_CANONICAL_HOST + +RTEMS_PROJECT_ROOT + +RTEMS_PROG_CC_FOR_TARGET +RTEMS_CANONICALIZE_TOOLS + +RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP) +RTEMS_CHECK_BSP_CACHE(RTEMS_BSP) + +# Explicitly list all Makefiles here +AC_CONFIG_FILES([Makefile +clock/Makefile +console/Makefile +include/Makefile +mbus/Makefile +timer/Makefile]) +AC_OUTPUT diff --git a/c/src/lib/libcpu/m68k/mcf5206/console/.cvsignore b/c/src/lib/libcpu/m68k/mcf5206/console/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/console/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c b/c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c new file mode 100644 index 0000000000..5758b45afe --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c @@ -0,0 +1,570 @@ +/* + * Generic UART Serial driver for Motorola Coldfire processors + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russian Fed. + * Author: Victor V. Vengerov + * + * COPYRIGHT (c) 1989-2000. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + * + */ + +#include +#include +#include +#include "mcf5206/mcfuart.h" + +/* + * int_driven_uart -- mapping between interrupt vector number and + * UART descriptor structures + */ +static struct { + mcfuart *uart; + int vec; +} int_driven_uart[2]; + +/* Forward function declarations */ +static rtems_isr +mcfuart_interrupt_handler(rtems_vector_number vec); + +/* + * mcfuart_init -- + * This function verifies the input parameters and perform initialization + * of the Motorola Coldfire on-chip UART descriptor structure. + * + * PARAMETERS: + * uart - pointer to the UART channel descriptor structure + * tty - pointer to termios structure + * int_driven - interrupt-driven (1) or polled (0) I/O mode + * chn - channel number (0/1) + * rx_buf - pointer to receive buffer + * rx_buf_len - receive buffer length + * + * RETURNS: + * RTEMS_SUCCESSFUL if all parameters are valid, or error code + */ +rtems_status_code +mcfuart_init(mcfuart *uart, void *tty, rtems_unsigned8 intvec, + rtems_unsigned32 chn) +{ + if (uart == NULL) + return RTEMS_INVALID_ADDRESS; + + if ((chn <= 0) || (chn > MCF5206E_UART_CHANNELS)) + return RTEMS_INVALID_NUMBER; + + uart->chn = chn; + uart->intvec = intvec; + uart->tty = tty; + + return RTEMS_SUCCESSFUL; +} + +/* mcfuart_set_baudrate -- + * Program the UART timer to specified baudrate + * + * PARAMETERS: + * uart - pointer to UART descriptor structure + * baud - termios baud rate (B50, B9600, etc...) + * + * RETURNS: + * none + */ +static void +mcfuart_set_baudrate(mcfuart *uart, speed_t baud) +{ + rtems_unsigned32 div; + rtems_unsigned32 rate; + switch (baud) + { + case B50: rate = 50; break; + case B75: rate = 75; break; + case B110: rate = 110; break; + case B134: rate = 134; break; + case B150: rate = 150; break; + case B200: rate = 200; break; + case B300: rate = 300; break; + case B600: rate = 600; break; + case B1200: rate = 1200; break; + case B2400: rate = 2400; break; + case B4800: rate = 4800; break; + case B9600: rate = 9600; break; + case B19200: rate = 19200; break; + case B38400: rate = 38400; break; + case B57600: rate = 57600; break; +#ifdef B115200 + case B115200: rate = 115200; break; +#endif +#ifdef B230400 + case B230400: rate = 230400; break; +#endif + default: rate = 9600; break; + } + + div = SYSTEM_CLOCK_FREQUENCY / (rate * 32); + + *MCF5206E_UBG1(MBAR,uart->chn) = (rtems_unsigned8)((div >> 8) & 0xff); + *MCF5206E_UBG2(MBAR,uart->chn) = (rtems_unsigned8)(div & 0xff); +} + +/* + * mcfuart_reset -- + * This function perform the hardware initialization of Motorola + * Coldfire processor on-chip UART controller using parameters + * filled by the mcfuart_init function. + * + * PARAMETERS: + * uart - pointer to UART channel descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL if channel is initialized successfully, error + * code in other case + * + * ALGORITHM: + * This function in general follows to algorith described in MCF5206e + * User's Manual, 12.5 UART Module Initialization Sequence + */ +rtems_status_code +mcfuart_reset(mcfuart *uart) +{ + register rtems_unsigned32 chn; + rtems_status_code rc; + + if (uart == NULL) + return RTEMS_INVALID_ADDRESS; + + chn = uart->chn; + + /* Reset the receiver and transmitter */ + *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_RX; + *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_TX; + + /* + * Program the vector number for a UART module interrupt, or + * disable UART interrupts if polled I/O. Enable the desired + * interrupt sources. + */ + if (uart->intvec != 0) + { + int_driven_uart[chn - 1].uart = uart; + int_driven_uart[chn - 1].vec = uart->intvec; + rc = rtems_interrupt_catch(mcfuart_interrupt_handler, uart->intvec, + &uart->old_handler); + if (rc != RTEMS_SUCCESSFUL) + return rc; + *MCF5206E_UIVR(MBAR,chn) = uart->intvec; + *MCF5206E_UIMR(MBAR,chn) = MCF5206E_UIMR_FFULL; + *MCF5206E_UACR(MBAR,chn) = MCF5206E_UACR_IEC; + *MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(uart->chn == 1 ? + MCF5206E_INTR_UART_1 : + MCF5206E_INTR_UART_2); + } + else + { + *MCF5206E_UIMR(MBAR,chn) = 0; + } + + /* Select the receiver and transmitter clock. */ + mcfuart_set_baudrate(uart, B19200); /* dBUG defaults (unfortunately, + it is differ to termios default */ + *MCF5206E_UCSR(MBAR,chn) = + MCF5206E_UCSR_RCS_TIMER | MCF5206E_UCSR_TCS_TIMER; + + /* Mode Registers 1,2 - set termios defaults (8N1) */ + *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_MR; + *MCF5206E_UMR(MBAR,chn) = +/* MCF5206E_UMR1_RXRTS | */ + MCF5206E_UMR1_PM_NO_PARITY | + MCF5206E_UMR1_BC_8; + *MCF5206E_UMR(MBAR,chn) = + MCF5206E_UMR2_CM_NORMAL | +/* MCF5206E_UMR2_TXCTS | */ + MCF5206E_UMR2_SB_1; + + /* Enable Receiver and Transmitter */ + *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_ERR; + *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_TC_ENABLE; + *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_RC_ENABLE; + + return RTEMS_SUCCESSFUL; +} + +/* + * mcfuart_disable -- + * This function disable the operations on Motorola Coldfire UART + * controller + * + * PARAMETERS: + * uart - pointer to UART channel descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL if UART closed successfuly, or error code in + * other case + */ +rtems_status_code +mcfuart_disable(mcfuart *uart) +{ + rtems_status_code rc; + *MCF5206E_UCR(MBAR,uart->chn) = + MCF5206E_UCR_TC_DISABLE | + MCF5206E_UCR_RC_DISABLE; + if (uart->intvec != 0) + { + *MCF5206E_IMR(MBAR) |= MCF5206E_INTR_BIT(uart->chn == 1 ? + MCF5206E_INTR_UART_1 : + MCF5206E_INTR_UART_2); + rc = rtems_interrupt_catch(uart->old_handler, uart->intvec, NULL); + int_driven_uart[uart->chn - 1].uart = NULL; + int_driven_uart[uart->chn - 1].vec = 0; + if (rc != RTEMS_SUCCESSFUL) + return rc; + } + return RTEMS_SUCCESSFUL; +} + +/* + * mcfuart_set_attributes -- + * This function parse the termios attributes structure and perform + * the appropriate settings in hardware. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * t - pointer to termios parameters + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +int +mcfuart_set_attributes(mcfuart *uart, const struct termios *t) +{ + int level; + speed_t baud; + rtems_unsigned8 umr1, umr2; + + baud = cfgetospeed(t); + umr1 = 0; + umr2 = MCF5206E_UMR2_CM_NORMAL; + + /* Set flow control */ + if ((t->c_cflag & CRTSCTS) != 0) + { + umr1 |= MCF5206E_UMR1_RXRTS; + umr2 |= MCF5206E_UMR2_TXCTS; + } + + /* Set character size */ + switch (t->c_cflag & CSIZE) + { + case CS5: umr1 |= MCF5206E_UMR1_BC_5; break; + case CS6: umr1 |= MCF5206E_UMR1_BC_6; break; + case CS7: umr1 |= MCF5206E_UMR1_BC_7; break; + case CS8: umr1 |= MCF5206E_UMR1_BC_8; break; + } + + /* Set number of stop bits */ + if ((t->c_cflag & CSTOPB) != 0) + { + if ((t->c_cflag & CSIZE) == CS5) + { + umr2 |= MCF5206E_UMR2_SB5_2; + } + else + { + umr2 |= MCF5206E_UMR2_SB_2; + } + } + else + { + if ((t->c_cflag & CSIZE) == CS5) + { + umr2 |= MCF5206E_UMR2_SB5_1; + } + else + { + umr2 |= MCF5206E_UMR2_SB_1; + } + } + + /* Set parity mode */ + if ((t->c_cflag & PARENB) != 0) + { + if ((t->c_cflag & PARODD) != 0) + { + umr1 |= MCF5206E_UMR1_PM_ODD; + } + else + { + umr1 |= MCF5206E_UMR1_PM_EVEN; + } + } + else + { + umr1 |= MCF5206E_UMR1_PM_NO_PARITY; + } + + rtems_interrupt_disable(level); + *MCF5206E_UCR(MBAR,uart->chn) = + MCF5206E_UCR_TC_DISABLE | MCF5206E_UCR_RC_DISABLE; + mcfuart_set_baudrate(uart, baud); + *MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_MISC_RESET_MR; + *MCF5206E_UMR(MBAR,uart->chn) = umr1; + *MCF5206E_UMR(MBAR,uart->chn) = umr2; + if ((t->c_cflag & CREAD) != 0) + { + *MCF5206E_UCR(MBAR,uart->chn) = + MCF5206E_UCR_TC_ENABLE | MCF5206E_UCR_RC_ENABLE; + } + else + { + *MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_TC_ENABLE; + } + rtems_interrupt_enable(level); + + return RTEMS_SUCCESSFUL; +} + +/* + * mcfuart_poll_read -- + * This function tried to read character from MCF UART and perform + * error handling. When parity or framing error occured, return + * value dependent on termios input mode flags: + * - received character, if IGNPAR == 1 + * - 0, if IGNPAR == 0 and PARMRK == 0 + * - 0xff and 0x00 on next poll_read invocation, if IGNPAR == 0 and + * PARMRK == 1 + * + * PARAMETERS: + * uart - pointer to UART descriptor structure + * + * RETURNS: + * code of received character or -1 if no characters received. + */ +int +mcfuart_poll_read(mcfuart *uart) +{ + rtems_unsigned8 usr; + int ch; + if (uart->parerr_mark_flag == 1) + { + uart->parerr_mark_flag = 0; + return 0; + } + usr = *MCF5206E_USR(MBAR,uart->chn); + if ((usr & MCF5206E_USR_RXRDY) != 0) + { + if (((usr & (MCF5206E_USR_FE | MCF5206E_USR_PE)) != 0) && + !(uart->c_iflag & IGNPAR)) + { + ch = *MCF5206E_URB(MBAR,uart->chn); /* Clear error bits */ + if (uart->c_iflag & PARMRK) + { + uart->parerr_mark_flag = 1; + ch = 0xff; + } + else + { + ch = 0; + } + } + else + { + ch = *MCF5206E_URB(MBAR,uart->chn); + } + } + else + ch = -1; + return ch; +} + +/* + * mcfuart_poll_write -- + * This function transmit buffer byte-by-byte in polling mode. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * buf - pointer to transmit buffer + * len - transmit buffer length + * + * RETURNS: + * 0 + */ +int +mcfuart_poll_write(mcfuart *uart, const char *buf, int len) +{ + while (len--) + { + while ((*MCF5206E_USR(MBAR, uart->chn) & MCF5206E_USR_TXRDY) == 0); + *MCF5206E_UTB(MBAR, uart->chn) = *buf++; + } + return 0; +} + +/* mcfuart_interrupt_handler -- + * UART interrupt handler routine + * + * PARAMETERS: + * vec - interrupt vector number + * + * RETURNS: + * none + */ +static rtems_isr +mcfuart_interrupt_handler(rtems_vector_number vec) +{ + mcfuart *uart; + register rtems_unsigned8 usr; + register rtems_unsigned8 uisr; + register int chn; + register int bp = 0; + + /* Find UART descriptor from vector number */ + if (int_driven_uart[0].vec == vec) + uart = int_driven_uart[0].uart; + else if (int_driven_uart[1].vec == vec) + uart = int_driven_uart[1].uart; + else + return; + + chn = uart->chn; + + uisr = *MCF5206E_UISR(MBAR, chn); + if (uisr & MCF5206E_UISR_DB) + { + *MCF5206E_UCR(MBAR, chn) = MCF5206E_UCR_MISC_RESET_BRK; + } + + /* Receiving */ + while (1) + { + char buf[32]; + usr = *MCF5206E_USR(MBAR,chn); + if ((bp < sizeof(buf) - 1) && ((usr & MCF5206E_USR_RXRDY) != 0)) + { + /* Receive character and handle frame/parity errors */ + if (((usr & (MCF5206E_USR_FE | MCF5206E_USR_PE)) != 0) && + !(uart->c_iflag & IGNPAR)) + { + if (uart->c_iflag & PARMRK) + { + buf[bp++] = 0xff; + buf[bp++] = 0x00; + } + else + { + buf[bp++] = 0x00; + } + } + else + { + buf[bp++] = *MCF5206E_URB(MBAR, chn); + } + + /* Reset error condition if any errors has been detected */ + if (usr & (MCF5206E_USR_RB | MCF5206E_USR_FE | + MCF5206E_USR_PE | MCF5206E_USR_OE)) + { + *MCF5206E_UCR(MBAR, chn) = MCF5206E_UCR_MISC_RESET_ERR; + } + } + else + { + if (bp != 0) + rtems_termios_enqueue_raw_characters(uart->tty, buf, bp); + break; + } + } + + /* Transmitting */ + while (1) + { + if ((*MCF5206E_USR(MBAR, chn) & MCF5206E_USR_TXRDY) == 0) + break; + if (uart->tx_buf != NULL) + { + if (uart->tx_ptr >= uart->tx_buf_len) + { + register int dequeue = uart->tx_buf_len; + *MCF5206E_UIMR(MBAR, uart->chn) = MCF5206E_UIMR_FFULL; + uart->tx_buf = NULL; + uart->tx_ptr = uart->tx_buf_len = 0; + rtems_termios_dequeue_characters(uart->tty, dequeue); + } + else + { + *MCF5206E_UTB(MBAR, chn) = uart->tx_buf[uart->tx_ptr++]; + } + } + else + break; + } +} + +/* mcfuart_interrupt_write -- + * This function initiate transmitting of the buffer in interrupt mode. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * buf - pointer to transmit buffer + * len - transmit buffer length + * + * RETURNS: + * 0 + */ +int +mcfuart_interrupt_write(mcfuart *uart, const char *buf, int len) +{ + int level; + rtems_interrupt_disable(level); + uart->tx_buf = buf; + uart->tx_buf_len = len; + uart->tx_ptr = 0; + *MCF5206E_UIMR(MBAR, uart->chn) = + MCF5206E_UIMR_FFULL | MCF5206E_UIMR_TXRDY; + while (((*MCF5206E_USR(MBAR,uart->chn) & MCF5206E_USR_TXRDY) != 0) && + (uart->tx_ptr < uart->tx_buf_len)) + { + *MCF5206E_UTB(MBAR,uart->chn) = uart->tx_buf[uart->tx_ptr++]; + } + rtems_interrupt_enable(level); + return 0; +} + +/* mcfuart_stop_remote_tx -- + * This function stop data flow from remote device. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +int +mcfuart_stop_remote_tx(mcfuart *uart) +{ + *MCF5206E_UOP0(MBAR, uart->chn) = 1; + return RTEMS_SUCCESSFUL; +} + +/* mcfuart_start_remote_tx -- + * This function resume data flow from remote device. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +int +mcfuart_start_remote_tx(mcfuart *uart) +{ + *MCF5206E_UOP1(MBAR, uart->chn) = 1; + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libcpu/m68k/mcf5206/include/.cvsignore b/c/src/lib/libcpu/m68k/mcf5206/include/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/include/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libcpu/m68k/mcf5206/include/mcf5206e.h b/c/src/lib/libcpu/m68k/mcf5206/include/mcf5206e.h new file mode 100644 index 0000000000..e51b648987 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/include/mcf5206e.h @@ -0,0 +1,613 @@ +/* + * Coldfire MCF5206e on-chip peripherial definitions. + * Contents of this file based on information provided in + * Motorola MCF5206e User's Manual + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * @(#) $Id$ + */ + +#ifndef __MCF5206E_H__ +#define __MCF5206E_H__ + +#ifdef ASM +#define MCF5206E_REG8(base,ofs) (ofs+base) +#define MCF5206E_REG16(base,ofs) (ofs+base) +#define MCF5206E_REG32(base,ofs) (ofs+base) +#else +#define MCF5206E_REG8(base,ofs) \ + (volatile rtems_unsigned8 *)((rtems_unsigned8 *)(base) + (ofs)) +#define MCF5206E_REG16(base,ofs) \ + (volatile rtems_unsigned16 *)((rtems_unsigned8 *)(base) + (ofs)) +#define MCF5206E_REG32(base,ofs) \ + (volatile rtems_unsigned32 *)((rtems_unsigned8 *)(base) + (ofs)) +#endif + +/*** Instruction Cache -- MCF5206e User's Manual, Chapter 4 ***/ + +/* CACR - Cache Control Register */ +#define MCF5206E_CACR_CENB (0x80000000) /* Cache Enable */ +#define MCF5206E_CACR_CPDI (0x10000000) /* Disable CPUSHL Invalidation */ +#define MCF5206E_CACR_CFRZ (0x08000000) /* Cache Freeze */ +#define MCF5206E_CACR_CINV (0x01000000) /* Cache Invalidate */ +#define MCF5206E_CACR_CEIB (0x00000400) /* Cache Enable Noncacheable + instruction bursting */ +#define MCF5206E_CACR_DCM (0x00000200) /* Default cache mode - noncacheable*/ +#define MCF5206E_CACR_DBWE (0x00000100) /* Default Buffered Write Enable */ +#define MCF5206E_CACR_DWP (0x00000020) /* Default Write Protection */ +#define MCF5206E_CACR_CLNF (0x00000003) /* Cache Line Fill */ + +/* ACR0, ACR1 - Access Control Registers */ +#define MCF5206E_ACR_AB (0xff000000) /* Address Base */ +#define MCF5206E_ACR_AB_S (24) +#define MCF5206E_ACR_AM (0x00ff0000) /* Address Mask */ +#define MCF5206E_ACR_AM_S (16) +#define MCF5206E_ACR_EN (0x00008000) /* Enable ACR */ +#define MCF5206E_ACR_SM (0x00006000) /* Supervisor Mode */ +#define MCF5206E_ACR_SM_USR (0x00000000) /* Match if user mode */ +#define MCF5206E_ACR_SM_SVR (0x00002000) /* Match if supervisor mode */ +#define MCF5206E_ACR_SM_ANY (0x00004000) /* Match Always */ +#define MCF5206E_ACR_CM (0x00000040) /* Cache Mode (1 - noncacheable) */ +#define MCF5206E_ACR_BUFW (0x00000020) /* Buffered Write Enable */ +#define MCF5206E_ACR_WP (0x00000004) /* Write Protect */ +#define MCF5206E_ACR_BASE(base) ((base) & MCF5206E_ACR_AB) +#define MCF5206E_ACR_MASK(mask) (((mask) >> 8) & MCF5206E_ACR_AM) + +/*** SRAM -- MCF5206e User's Manual, Chapter 5 ***/ + +/* RAMBAR - SRAM Base Address Register */ +#define MCF5206E_RAMBAR_BA (0xffffe000) /* SRAM Base Address */ +#define MCF5206E_RAMBAR_WP (0x00000100) /* Write Protect */ +#define MCF5206E_RAMBAR_CI (0x00000020) /* CPU Space mask */ +#define MCF5206E_RAMBAR_SC (0x00000010) /* Supervisor Code Space Mask */ +#define MCF5206E_RAMBAR_SD (0x00000008) /* Supervisor Data Space Mask */ +#define MCF5206E_RAMBAR_UC (0x00000004) /* User Code Space Mask */ +#define MCF5206E_RAMBAR_UD (0x00000002) /* User Data Space Mask */ +#define MCF5206E_RAMBAR_V (0x00000001) /* Contents of RAMBAR are valid */ + +/*** DMA Controller Module -- MCF5206e User's Manual, Chapter 7 ***/ + +/* DMA Source Address Register */ +#define MCF5206E_SAR(mbar,chn) MCF5206E_REG32(mbar,0x200 + ((chn) * 0x40)) + +/* DMA Destination Address Register */ +#define MCF5206E_DAR(mbar,chn) MCF5206E_REG32(mbar,0x204 + ((chn) * 0x40)) + +/* DMA Byte Count Register */ +#define MCF5206E_BCR(mbar,chn) MCF5206E_REG16(mbar,0x20C + ((chn) * 0x40)) + +/* DMA Control Register */ +#define MCF5206E_DCR(mbar,chn) MCF5206E_REG16(mbar,0x208 + ((chn) * 0x40)) +#define MCF5206E_DCR_INT (0x8000) /* Interrupt on completion of transfer */ +#define MCF5206E_DCR_EEXT (0x4000) /* Enable External DMA Request */ +#define MCF5206E_DCR_CS (0x2000) /* Cycle Steal */ +#define MCF5206E_DCR_AA (0x1000) /* Auto Align */ +#define MCF5206E_DCR_BWC (0x0E00) /* Bandwidth Control: */ +#define MCF5206E_DCR_BWC_DISABLE (0x0000) /* Bandwidth Control Disabled */ +#define MCF5206E_DCR_BWC_512 (0x0200) /* 512 bytes */ +#define MCF5206E_DCR_BWC_1024 (0x0400) /* 1024 bytes */ +#define MCF5206E_DCR_BWC_2048 (0x0600) /* 2048 bytes */ +#define MCF5206E_DCR_BWC_4096 (0x0800) /* 4096 bytes */ +#define MCF5206E_DCR_BWC_8192 (0x0A00) /* 8192 bytes */ +#define MCF5206E_DCR_BWC_16384 (0x0C00) /* 16384 bytes */ +#define MCF5206E_DCR_BWC_32768 (0x0E00) /* 32768 bytes */ +#define MCF5206E_DCR_SAA (0x0100) /* Single Address Access */ +#define MCF5206E_DCR_S_RW (0x0080) /* Single Address Access Read/Write Val */ +#define MCF5206E_DCR_SINC (0x0040) /* Source Increment */ +#define MCF5206E_DCR_SSIZE (0x0030) /* Source Size: */ +#define MCF5206E_DCR_SSIZE_LONG (0x0000) /* Longword (4 bytes) */ +#define MCF5206E_DCR_SSIZE_BYTE (0x0010) /* Byte */ +#define MCF5206E_DCR_SSIZE_WORD (0x0020) /* Word (2 bytes) */ +#define MCF5206E_DCR_SSIZE_LINE (0x0030) /* Line (16 bytes) */ +#define MCF5206E_DCR_DINC (0x0008) /* Destination Increment */ +#define MCF5206E_DCR_DSIZE (0x0006) /* Destination Size: */ +#define MCF5206E_DCR_DSIZE_LONG (0x0000) /* Longword (4 bytes) */ +#define MCF5206E_DCR_DSIZE_BYTE (0x0002) /* Byte */ +#define MCF5206E_DCR_DSIZE_WORD (0x0004) /* Word (2 bytes) */ +#define MCF5206E_DCR_DSIZE_LINE (0x0006) /* Line (16 bytes) */ +#define MCF5206E_DCR_START (0x0001) /* Start Transfer */ + +/* DMA Status Register */ +#define MCF5206E_DSR(mbar,chn) MCF5206E_REG8(mbar,0x210 + ((chn) * 0x40)) +#define MCF5206E_DSR_CE (0x40) /* Configuration Error has occured */ +#define MCF5206E_DSR_BES (0x20) /* Bus Error on Source */ +#define MCF5206E_DSR_BED (0x10) /* Bus Error on Destination */ +#define MCF5206E_DSR_REQ (0x04) /* Request */ +#define MCF5206E_DSR_BSY (0x02) /* Busy */ +#define MCF5206E_DSR_DONE (0x01) /* Transaction Done */ + +/* DMA Interrupt Vector Register */ +#define MCF5206E_DIVR(mbar,chn) MCF5206E_REG8(mbar,0x214 + ((chn) * 0x40)) + + +/*** System Integration Module -- MCF5206e User's Manual, Chapter 8 ***/ + +/* MBAR - Module Base Address Register */ +#define MCF5206E_MBAR_BA (0xFFFFFC00) /* Base Address */ +#define MCF5206E_MBAR_SC (0x00000010) /* Supervisor Code Space Mask */ +#define MCF5206E_MBAR_SD (0x00000008) /* Supervisor Data Space Mask */ +#define MCF5206E_MBAR_UC (0x00000004) /* User Code Space Mask */ +#define MCF5206E_MBAR_UD (0x00000002) /* User Data Space Mask */ +#define MCF5206E_MBAR_V (0x00000001) /* Contents of MBAR are valid */ + +/* SIM Configuration Register */ +#define MCF5206E_SIMR(mbar) MCF5206E_REG8(mbar,0x003) +#define MCF5206E_SIMR_FRZ1 (0x80) /* Disable Soft Wdog Timer when FREEZE */ +#define MCF5206E_SIMR_FRZ0 (0x40) /* Disable Bus Timeout monitor when FREEZE*/ +#define MCF5206E_SIMR_BL (0x01) /* Bus Lock Enable */ + +/* Interrupt numbers assignment */ +#define MCF5206E_INTR_EXT_IRQ1 (1) /* External IRQ1 */ +#define MCF5206E_INTR_EXT_IPL1 (1) /* External IPL1 */ +#define MCF5206E_INTR_EXT_IPL2 (2) /* External IPL2 */ +#define MCF5206E_INTR_EXT_IPL3 (3) /* External IPL3 */ +#define MCF5206E_INTR_EXT_IRQ4 (4) /* External IRQ4 */ +#define MCF5206E_INTR_EXT_IPL4 (4) /* External IPL4 */ +#define MCF5206E_INTR_EXT_IPL5 (5) /* External IPL5 */ +#define MCF5206E_INTR_EXT_IPL6 (6) /* External IPL6 */ +#define MCF5206E_INTR_EXT_IRQ7 (7) /* External IRQ7 */ +#define MCF5206E_INTR_EXT_IPL7 (7) /* External IPL7 */ +#define MCF5206E_INTR_SWT (8) /* Software Watchdog Timer */ +#define MCF5206E_INTR_TIMER_1 (9) /* Timer 1 interrupt */ +#define MCF5206E_INTR_TIMER_2 (10) /* Timer 2 interrupt */ +#define MCF5206E_INTR_MBUS (11) /* MBUS interrupt */ +#define MCF5206E_INTR_UART_1 (12) /* UART 1 interrupt */ +#define MCF5206E_INTR_UART_2 (13) /* UART 2 interrupt */ +#define MCF5206E_INTR_DMA_0 (14) /* DMA channel 0 interrupt */ +#define MCF5206E_INTR_DMA_1 (15) /* DMA channel 1 interrupt */ + +#define MCF5206E_INTR_BIT(n) (1 << (n)) + +/* Interrupt Control Registers (ICR1 - ICR15) */ +#define MCF5206E_ICR(mbar,n) MCF5206E_REG8(mbar,0x014 + (n) - 1) + +#define MCF5206E_ICR_AVEC (0x80) /* Autovector Enable */ +#define MCF5206E_ICR_IL (0x1c) /* Interrupt Level */ +#define MCF5206E_ICR_IL_S (2) +#define MCF5206E_ICR_IP (0x03) /* Interrupt Priority */ +#define MCF5206E_ICR_IP_S (0) + +/* Interrupt Mask Register */ +#define MCF5206E_IMR(mbar) MCF5206E_REG16(mbar,0x036) + +/* Interrupt Pending Register */ +#define MCF5206E_IPR(mbar) MCF5206E_REG16(mbar,0x03a) + +/* Reset Status Register */ +#define MCF5206E_RSR(mbar) MCF5206E_REG8(mbar,0x040) +#define MCF5206E_RSR_HRST (0x80) /* Hard Reset or System Reset */ +#define MCF5206E_RSR_SWTR (0x20) /* Software Watchdog Timer Reset */ + +/* System Protection Control Register */ +#define MCF5206E_SYPCR(mbar) MCF5206E_REG8(mbar,0x041) +#define MCF5206E_SYPCR_SWE (0x80) /* Software Watchdog Enable */ +#define MCF5206E_SYPCR_SWRI (0x40) /* Software Watchdog Reset/Interrupt Sel.*/ +#define MCF5206E_SYPCR_SWP (0x20) /* Software Watchdog Prescaler */ +#define MCF5206E_SYPCR_SWT (0x18) /* Software Watchdog Timing: */ +#define MCF5206E_SYPCR_SWT_S (3) +#define MCF5206E_SYPCR_SWT_9 (0x00) /* timeout = (1<<9)/sysfreq */ +#define MCF5206E_SYPCR_SWT_11 (0x08) /* timeout = (1<<11)/sysfreq */ +#define MCF5206E_SYPCR_SWT_13 (0x10) /* timeout = (1<<13)/sysfreq */ +#define MCF5206E_SYPCR_SWT_15 (0x18) /* timeout = (1<<15)/sysfreq */ +#define MCF5206E_SYPCR_SWT_18 (0x20) /* timeout = (1<<18)/sysfreq */ +#define MCF5206E_SYPCR_SWT_20 (0x28) /* timeout = (1<<20)/sysfreq */ +#define MCF5206E_SYPCR_SWT_22 (0x30) /* timeout = (1<<22)/sysfreq */ +#define MCF5206E_SYPCR_SWT_24 (0x38) /* timeout = (1<<24)/sysfreq */ +#define MCF5206E_SYPCR_BME (0x04) /* Bus Timeout Monitor Enable */ +#define MCF5206E_SYPCR_BMT (0x03) /* Bus Monitor Timing: */ +#define MCF5206E_SYPCR_BMT_1024 (0x00) /* timeout 1024 system clocks */ +#define MCF5206E_SYPCR_BMT_512 (0x01) /* timeout 512 system clocks */ +#define MCF5206E_SYPCR_BMT_256 (0x02) /* timeout 256 system clocks */ +#define MCF5206E_SYPCR_BMT_128 (0x03) /* timeout 128 system clocks */ + +/* Software Watchdog Interrupt Vector Register */ +#define MCF5206E_SWIVR(mbar) MCF5206E_REG8(mbar,0x042) + +/* Software Watchdog Service Register */ +#define MCF5206E_SWSR(mbar) MCF5206E_REG8(mbar,0x043) +#define MCF5206E_SWSR_KEY1 (0x55) +#define MCF5206E_SWSR_KEY2 (0xAA) + +/* Pin Assignment Register */ +#define MCF5206E_PAR(mbar) MCF5206E_REG16(mbar,0x0CA) +#define MCF5206E_PAR_PAR9 (0x200) +#define MCF5206E_PAR_PAR9_TOUT (0x000) /* Timer 0 output */ +#define MCF5206E_PAR_PAR9_DREQ1 (0x200) /* DMA channel 1 request */ +#define MCF5206E_PAR_PAR8 (0x100) +#define MCF5206E_PAR_PAR8_TIN0 (0x000) /* Timer 1 input */ +#define MCF5206E_PAR_PAR8_DREQ0 (0x100) /* DMA channel 0 request */ +#define MCF5206E_PAR_PAR7 (0x080) +#define MCF5206E_PAR_PAR7_RSTO (0x000) /* Reset output */ +#define MCF5206E_PAR_PAR7_UART2 (0x080) /* UART 2 RTS output */ +#define MCF5206E_PAR_PAR6 (0x040) +#define MCF5206E_PAR_PAR6_IRQ (0x000) /* IRQ7, IRQ4, IRQ1 */ +#define MCF5206E_PAR_PAR6_IPL (0x040) /* IPL2, IPL1, IPL0 */ +#define MCF5206E_PAR_PAR5 (0x020) +#define MCF5206E_PAR_PAR5_GPIO (0x000) /* General purpose I/O PP7-PP4 */ +#define MCF5206E_PAR_PAR5_PST (0x020) /* BDM signals PST3-PST0 */ +#define MCF5206E_PAR_PAR4 (0x010) +#define MCF5206E_PAR_PAR4_GPIO (0x000) /* General purpose I/O PP3-PP0 */ +#define MCF5206E_PAR_PAR4_DDATA (0x010) /* BDM signals DDATA3-DDATA0 */ +#define MCF5206E_PAR_PAR3 (0x008) +#define MCF5206E_PAR_PAR2 (0x004) +#define MCF5206E_PAR_PAR1 (0x002) +#define MCF5206E_PAR_PAR0 (0x001) +#define MCF5206E_PAR_WE0_WE1_WE2_WE3 (0x000) +#define MCF5206E_PAR_WE0_WE1_CS5_CS4 (0x001) +#define MCF5206E_PAR_WE0_WE1_CS5_A24 (0x002) +#define MCF5206E_PAR_WE0_WE1_A25_A24 (0x003) +#define MCF5206E_PAR_WE0_CS6_CS5_CS4 (0x004) +#define MCF5206E_PAR_WE0_CS6_CS5_A24 (0x005) +#define MCF5206E_PAR_WE0_CS6_A25_A24 (0x006) +#define MCF5206E_PAR_WE0_A26_A25_A24 (0x007) +#define MCF5206E_PAR_CS7_CS6_CS5_CS4 (0x008) +#define MCF5206E_PAR_CS7_CS6_CS4_A24 (0x009) +#define MCF5206E_PAR_CS7_CS6_A25_A24 (0x00A) +#define MCF5206E_PAR_CS7_A26_A25_A24 (0x00B) +#define MCF5206E_PAR_A27_A26_A25_A24 (0x00C) + +/* Bus Master Arbitration Control */ +#define MCF5206E_MARB(mbar) MCF5206E_REG8(mbar,0x007) +#define MCF5206E_MARB_NOARB (0x08) /* Arbiter operation disable */ +#define MCF5206E_MARB_ARBCTRL (0x04) /* Arb. order: Internal DMA, Coldfire */ + +/*** Chip Select Module -- MCF5206e User's Manual, Chapter 9 ***/ + +/* Chip Select Address Register */ +#define MCF5206E_CSAR(mbar,bank) MCF5206E_REG16(mbar,0x064 + ((bank) * 12)) + +/* Chip Select Mask Register */ +#define MCF5206E_CSMR(mbar,bank) MCF5206E_REG32(mbar,0x068 + ((bank) * 12)) +#define MCF5206E_CSMR_BAM (0xffff0000) /* Base Address Mask */ +#define MCF5206E_CSMR_BAM_S (16) +#define MCF5206E_CSMR_MASK_256M (0x0FFF0000) +#define MCF5206E_CSMR_MASK_128M (0x07FF0000) +#define MCF5206E_CSMR_MASK_64M (0x03FF0000) +#define MCF5206E_CSMR_MASK_32M (0x01FF0000) +#define MCF5206E_CSMR_MASK_16M (0x00FF0000) +#define MCF5206E_CSMR_MASK_8M (0x007F0000) +#define MCF5206E_CSMR_MASK_4M (0x003F0000) +#define MCF5206E_CSMR_MASK_2M (0x001F0000) +#define MCF5206E_CSMR_MASK_1M (0x000F0000) +#define MCF5206E_CSMR_MASK_1024K (0x000F0000) +#define MCF5206E_CSMR_MASK_512K (0x00070000) +#define MCF5206E_CSMR_MASK_256K (0x00030000) +#define MCF5206E_CSMR_MASK_128K (0x00010000) +#define MCF5206E_CSMR_MASK_64K (0x00000000) +#define MCF5206E_CSMR_CI (0x00000020) /* CPU Space Mask (CSMR1 only) */ +#define MCF5206E_CSMR_SC (0x00000010) /* Supervisor Code Space Mask */ +#define MCF5206E_CSMR_SD (0x00000008) /* Supervisor Data Space Mask */ +#define MCF5206E_CSMR_UC (0x00000004) /* User Code Space Mask */ +#define MCF5206E_CSMR_UD (0x00000002) /* User Data Space Mask */ + +/* Chip Select Control Register */ +#define MCF5206E_CSCR(mbar,bank) MCF5206E_REG16(mbar,0x6E + ((bank) * 12)) +#define MCF5206E_CSCR_WS (0x3c00) /* Wait States */ +#define MCF5206E_CSCR_WS_S (10) +#define MCF5206E_CSCR_WS0 (0x0000) /* 0 Wait States */ +#define MCF5206E_CSCR_WS1 (0x0400) /* 1 Wait States */ +#define MCF5206E_CSCR_WS2 (0x0800) /* 2 Wait States */ +#define MCF5206E_CSCR_WS3 (0x0C00) /* 3 Wait States */ +#define MCF5206E_CSCR_WS4 (0x1000) /* 4 Wait States */ +#define MCF5206E_CSCR_WS5 (0x1400) /* 5 Wait States */ +#define MCF5206E_CSCR_WS6 (0x1800) /* 6 Wait States */ +#define MCF5206E_CSCR_WS7 (0x1C00) /* 7 Wait States */ +#define MCF5206E_CSCR_WS8 (0x2000) /* 8 Wait States */ +#define MCF5206E_CSCR_WS9 (0x2400) /* 9 Wait States */ +#define MCF5206E_CSCR_WS10 (0x2800) /* 10 Wait States */ +#define MCF5206E_CSCR_WS11 (0x2C00) /* 11 Wait States */ +#define MCF5206E_CSCR_WS12 (0x3000) /* 12 Wait States */ +#define MCF5206E_CSCR_WS13 (0x3400) /* 13 Wait States */ +#define MCF5206E_CSCR_WS14 (0x3800) /* 14 Wait States */ +#define MCF5206E_CSCR_WS15 (0x3C00) /* 15 Wait States */ +#define MCF5206E_CSCR_BRST (0x0200) /* Burst Enable */ +#define MCF5206E_CSCR_AA (0x0100) /* Coldfire Core Auto Acknowledge + Enable */ +#define MCF5206E_CSCR_PS (0x00C0) /* Port Size */ +#define MCF5206E_CSCR_PS_S (6) +#define MCF5206E_CSCR_PS_32 (0x0000) /* Port Size = 32 bits */ +#define MCF5206E_CSCR_PS_8 (0x0040) /* Port Size = 8 bits */ +#define MCF5206E_CSCR_PS_16 (0x0080) /* Port Size = 16 bits */ +#define MCF5206E_CSCR_EMAA (0x0020) /* External Master Automatic Acknowledge + Enable */ +#define MCF5206E_CSCR_ASET (0x0010) /* Address Setup Enable */ +#define MCF5206E_CSCR_WRAH (0x0008) /* Write Address Hold Enable */ +#define MCF5206E_CSCR_RDAH (0x0004) /* Read Address Hold Enable */ +#define MCF5206E_CSCR_WR (0x0002) /* Write Enable */ +#define MCF5206E_CSCR_RD (0x0001) /* Read Enable */ + +/* Default Memory Control Register */ +#define MCF5206E_DMCR(mbar) MCF5206E_REG16(mbar, 0x0C6) + +/*** Parallel Port (GPIO) Module -- MCF5206e User's Manual, Chapter 10 ***/ + +/* Port A Data Direction Register */ +#define MCF5206E_PPDDR(mbar) MCF5206E_REG8(mbar,0x1C5) + +/* Port A Data Register */ +#define MCF5206E_PPDAT(mbar) MCF5206E_REG8(mbar,0x1C9) + +#define MCF5206E_PP_DAT0 (0x01) +#define MCF5206E_PP_DAT1 (0x02) +#define MCF5206E_PP_DAT2 (0x04) +#define MCF5206E_PP_DAT3 (0x08) +#define MCF5206E_PP_DAT4 (0x10) +#define MCF5206E_PP_DAT5 (0x20) +#define MCF5206E_PP_DAT6 (0x40) +#define MCF5206E_PP_DAT7 (0x80) + +/*** DRAM Controller -- MCF5206e User's Manual, Chapter 11 ***/ + +/* DRAM Controller Refresh Register */ +#define MCF5206E_DCRR(mbar) MCF5206E_REG16(mbar,0x046) + +/* DRAM Controller Timing Register */ +#define MCF5206E_DCTR(mbar) MCF5206E_REG16(mbar,0x04A) +#define MCF5206E_DCTR_DAEM (0x8000) /* Drive Multiplexed Address During + External Master DRAM Transfers */ +#define MCF5206E_DCTR_EDO (0x4000) /* Extended Data-Out Enable */ +#define MCF5206E_DCTR_RCD (0x1000) /* RAS-to-CAS Delay Time */ +#define MCF5206E_DCTR_RSH (0x0600) /* RAS Hold Time */ +#define MCF5206E_DCTR_RSH_0 (0x0000) /* See User's Manual for details */ +#define MCF5206E_DCTR_RSH_1 (0x0200) +#define MCF5206E_DCTR_RSH_2 (0x0400) +#define MCF5206E_DCTR_RP (0x0060) /* RAS Precharge Time */ +#define MCF5206E_DCTR_RP_15 (0x0000) /* RAS Precharges for 1.5 system clks */ +#define MCF5206E_DCTR_RP_25 (0x0020) /* RAS Precharges for 2.5 system clks */ +#define MCF5206E_DCTR_RP_35 (0x0040) /* RAS Precharges for 3.5 system clks */ +#define MCF5206E_DCTR_CAS (0x0008) /* Column Address Strobe Time */ +#define MCF5206E_DCTR_CP (0x0002) /* CAS Precharge Time */ +#define MCF5206E_DCTR_CSR (0x0001) /* CAS Setup Time for CAS before RAS + refresh */ + +/* DRAM Controller Address Registers */ +#define MCF5206E_DCAR(mbar,bank) MCF5206E_REG16(mbar,0x4C + ((bank) * 12)) + +/* DRAM Controller Mask Registers */ +#define MCF5206E_DCMR(mbar,bank) MCF5206E_REG32(mbar,0x50 + ((bank) * 12)) +#define MCF5206E_DCMR_BAM (0xffff0000) /* Base Address Mask */ +#define MCF5206E_DCMR_BAM_S (16) +#define MCF5206E_DCMR_MASK_256M (0x0FFE0000) +#define MCF5206E_DCMR_MASK_128M (0x07FE0000) +#define MCF5206E_DCMR_MASK_64M (0x03FE0000) +#define MCF5206E_DCMR_MASK_32M (0x01FE0000) +#define MCF5206E_DCMR_MASK_16M (0x00FE0000) +#define MCF5206E_DCMR_MASK_8M (0x007E0000) +#define MCF5206E_DCMR_MASK_4M (0x003E0000) +#define MCF5206E_DCMR_MASK_2M (0x001E0000) +#define MCF5206E_DCMR_MASK_1M (0x000E0000) +#define MCF5206E_DCMR_MASK_1024K (0x000E0000) +#define MCF5206E_DCMR_MASK_512K (0x00060000) +#define MCF5206E_DCMR_MASK_256K (0x00020000) +#define MCF5206E_DCMR_MASK_128K (0x00000000) +#define MCF5206E_DCMR_SC (0x00000010) /* Supervisor Code Space Mask */ +#define MCF5206E_DCMR_SD (0x00000008) /* Supervisor Data Space Mask */ +#define MCF5206E_DCMR_UC (0x00000004) /* User Code Space Mask */ +#define MCF5206E_DCMR_UD (0x00000002) /* User Data Space Mask */ + +/* DRAM Controller Control Register */ +#define MCF5206E_DCCR(mbar,bank) MCF5206E_REG8(mbar, 0x57 + ((bank) * 12)) +#define MCF5206E_DCCR_PS (0xC0) /* Port Size */ +#define MCF5206E_DCCR_PS_32 (0x00) /* 32 bit Port Size */ +#define MCF5206E_DCCR_PS_8 (0x40) /* 8 bit Port Size */ +#define MCF5206E_DCCR_PS_16 (0x80) /* 16 bit Port Size */ +#define MCF5206E_DCCR_BPS (0x30) /* Bank Page Size */ +#define MCF5206E_DCCR_BPS_512 (0x00) /* 512 Byte Page Size */ +#define MCF5206E_DCCR_BPS_1K (0x10) /* 1 KByte Page Size */ +#define MCF5206E_DCCR_BPS_2K (0x20) /* 2 KByte Page Size */ +#define MCF5206E_DCCR_PM (0x0C) /* Page Mode Select */ +#define MCF5206E_DCCR_PM_NORMAL (0x00) /* Normal Mode */ +#define MCF5206E_DCCR_PM_BURSTP (0x04) /* Burst Page Mode */ +#define MCF5206E_DCCR_PM_FASTP (0x0C) /* Fast Page Mode */ +#define MCF5206E_DCCR_WR (0x02) /* Write Enable */ +#define MCF5206E_DCCR_RD (0x01) /* Read Enable */ + +/*** UART Module -- MCF5206e User's Manual, Chapter 12 ***/ + +#define MCF5206E_UART_CHANNELS (2) +/* UART Mode Register */ +#define MCF5206E_UMR(mbar,n) MCF5206E_REG8(mbar,0x140 + (((n)-1) * 0x40)) +#define MCF5206E_UMR1_RXRTS (0x80) /* Receiver Request-to-Send + Control */ +#define MCF5206E_UMR1_RXIRQ (0x40) /* Receiver Interrupt Select */ +#define MCF5206E_UMR1_ERR (0x20) /* Error Mode */ +#define MCF5206E_UMR1_PM (0x1C) /* Parity Mode, Parity Type */ +#define MCF5206E_UMR1_PM_EVEN (0x00) /* Even Parity */ +#define MCF5206E_UMR1_PM_ODD (0x04) /* Odd Parity */ +#define MCF5206E_UMR1_PM_FORCE_LOW (0x08) /* Force parity low */ +#define MCF5206E_UMR1_PM_FORCE_HIGH (0x0C) /* Force parity high */ +#define MCF5206E_UMR1_PM_NO_PARITY (0x10) /* No Parity */ +#define MCF5206E_UMR1_PM_MULTI_DATA (0x18) /* Multidrop mode - data char */ +#define MCF5206E_UMR1_PM_MULTI_ADDR (0x1C) /* Multidrop mode - addr char */ +#define MCF5206E_UMR1_BC (0x03) /* Bits per Character */ +#define MCF5206E_UMR1_BC_5 (0x00) /* 5 bits per character */ +#define MCF5206E_UMR1_BC_6 (0x01) /* 6 bits per character */ +#define MCF5206E_UMR1_BC_7 (0x02) /* 7 bits per character */ +#define MCF5206E_UMR1_BC_8 (0x03) /* 8 bits per character */ + +#define MCF5206E_UMR2_CM (0xC0) /* Channel Mode */ +#define MCF5206E_UMR2_CM_NORMAL (0x00) /* Normal Mode */ +#define MCF5206E_UMR2_CM_AUTO_ECHO (0x40) /* Automatic Echo Mode */ +#define MCF5206E_UMR2_CM_LOCAL_LOOP (0x80) /* Local Loopback Mode */ +#define MCF5206E_UMR2_CM_REMOTE_LOOP (0xC0) /* Remote Loopback Modde */ +#define MCF5206E_UMR2_TXRTS (0x20) /* Transmitter Ready-to-Send op */ +#define MCF5206E_UMR2_TXCTS (0x10) /* Transmitter Clear-to-Send op */ +#define MCF5206E_UMR2_SB (0x0F) /* Stop Bit Length */ +#define MCF5206E_UMR2_SB_1 (0x07) /* 1 Stop Bit for 6-8 bits char */ +#define MCF5206E_UMR2_SB_15 (0x08) /* 1.5 Stop Bits for 6-8 bits chr*/ +#define MCF5206E_UMR2_SB_2 (0x0F) /* 2 Stop Bits for 6-8 bits char */ +#define MCF5206E_UMR2_SB5_1 (0x00) /* 1 Stop Bits for 5 bit char */ +#define MCF5206E_UMR2_SB5_15 (0x07) /* 1.5 Stop Bits for 5 bit char */ +#define MCF5206E_UMR2_SB5_2 (0x0F) /* 2 Stop Bits for 5 bit char */ + +/* UART Status Register (read only) */ +#define MCF5206E_USR(mbar,n) MCF5206E_REG8(mbar,0x144 + (((n)-1) * 0x40)) +#define MCF5206E_USR_RB (0x80) /* Received Break */ +#define MCF5206E_USR_FE (0x40) /* Framing Error */ +#define MCF5206E_USR_PE (0x20) /* Parity Error */ +#define MCF5206E_USR_OE (0x10) /* Overrun Error */ +#define MCF5206E_USR_TXEMP (0x08) /* Transmitter Empty */ +#define MCF5206E_USR_TXRDY (0x04) /* Transmitter Ready */ +#define MCF5206E_USR_FFULL (0x02) /* FIFO Full */ +#define MCF5206E_USR_RXRDY (0x01) /* Receiver Ready */ + +/* UART Clock Select Register (write only) */ +#define MCF5206E_UCSR(mbar,n) MCF5206E_REG8(mbar,0x144 + (((n)-1) * 0x40)) +#define MCF5206E_UCSR_RCS (0xF0) /* Receiver Clock Select */ +#define MCF5206E_UCSR_RCS_TIMER (0xD0) /* Timer */ +#define MCF5206E_UCSR_RCS_EXT16 (0xE0) /* External clk x16 */ +#define MCF5206E_UCSR_RCS_EXT (0xF0) /* External clk x1 */ +#define MCF5206E_UCSR_TCS (0x0F) /* Transmitter Clock Select */ +#define MCF5206E_UCSR_TCS_TIMER (0x0D) /* Timer */ +#define MCF5206E_UCSR_TCS_EXT16 (0x0E) /* External clk x16 */ +#define MCF5206E_UCSR_TCS_EXT (0x0F) /* External clk x1 */ + +/* UART Command Register (write only) */ +#define MCF5206E_UCR(mbar,n) MCF5206E_REG8(mbar,0x148 + (((n)-1) * 0x40)) +#define MCF5206E_UCR_MISC (0x70) /* Miscellaneous Commands: */ +#define MCF5206E_UCR_MISC_NOP (0x00) /* No Command */ +#define MCF5206E_UCR_MISC_RESET_MR (0x10) /* Reset Mode Register Ptr */ +#define MCF5206E_UCR_MISC_RESET_RX (0x20) /* Reset Receiver */ +#define MCF5206E_UCR_MISC_RESET_TX (0x30) /* Reset Transmitter */ +#define MCF5206E_UCR_MISC_RESET_ERR (0x40) /* Reset Error Status */ +#define MCF5206E_UCR_MISC_RESET_BRK (0x50) /* Reset Break-Change Interrupt */ +#define MCF5206E_UCR_MISC_START_BRK (0x60) /* Start Break */ +#define MCF5206E_UCR_MISC_STOP_BRK (0x70) /* Stop Break */ +#define MCF5206E_UCR_TC (0x0C) /* Transmitter Commands: */ +#define MCF5206E_UCR_TC_NOP (0x00) /* No Action Taken */ +#define MCF5206E_UCR_TC_ENABLE (0x04) /* Transmitter Enable */ +#define MCF5206E_UCR_TC_DISABLE (0x08) /* Transmitter Disable */ +#define MCF5206E_UCR_RC (0x03) /* Receiver Commands: */ +#define MCF5206E_UCR_RC_NOP (0x00) /* No Action Taken */ +#define MCF5206E_UCR_RC_ENABLE (0x01) /* Receiver Enable */ +#define MCF5206E_UCR_RC_DISABLE (0x02) /* Receiver Disable */ + +/* UART Receive Buffer (read only) */ +#define MCF5206E_URB(mbar,n) MCF5206E_REG8(mbar,0x14C + (((n)-1) * 0x40)) + +/* UART Transmit Buffer (write only) */ +#define MCF5206E_UTB(mbar,n) MCF5206E_REG8(mbar,0x14C + (((n)-1) * 0x40)) + +/* UART Input Port Change Register (read only) */ +#define MCF5206E_UIPCR(mbar,n) MCF5206E_REG8(mbar,0x150 + (((n)-1) * 0x40)) +#define MCF5206E_UIPCR_COS (0x10) /* Change of State at CTS input */ +#define MCF5206E_UIPCR_CTS (0x01) /* Current State of CTS */ + +/* UART Auxiliary Control Register (write only) */ +#define MCF5206E_UACR(mbar,n) MCF5206E_REG8(mbar,0x150 + (((n)-1) * 0x40)) +#define MCF5206E_UACR_IEC (0x01) /* Input Enable Control - generate interrupt + on CTS change */ + +/* UART Interrupt Status Register (read only) */ +#define MCF5206E_UISR(mbar,n) MCF5206E_REG8(mbar,0x154 + (((n)-1) * 0x40)) +#define MCF5206E_UISR_COS (0x80) /* Change of State has occured at CTS */ +#define MCF5206E_UISR_DB (0x04) /* Delta Break */ +#define MCF5206E_UISR_RXRDY (0x02) /* Receiver Ready or FIFO Full */ +#define MCF5206E_UISR_TXRDY (0x01) /* Transmitter Ready */ + +/* UART Interrupt Mask Register (write only) */ +#define MCF5206E_UIMR(mbar,n) MCF5206E_REG8(mbar,0x154 + (((n)-1) * 0x40)) +#define MCF5206E_UIMR_COS (0x80) /* Change of State interrupt enable */ +#define MCF5206E_UIMR_DB (0x04) /* Delta Break interrupt enable */ +#define MCF5206E_UIMR_FFULL (0x02) /* FIFO Full interrupt enable */ +#define MCF5206E_UIMR_TXRDY (0x01) /* Transmitter Ready Interrupt enable */ + +/* UART Baud Rate Generator Prescale MSB Register */ +#define MCF5206E_UBG1(mbar,n) MCF5206E_REG8(mbar,0x158 + (((n)-1) * 0x40)) + +/* UART Baud Rate Generator Prescale LSB Register */ +#define MCF5206E_UBG2(mbar,n) MCF5206E_REG8(mbar,0x15C + (((n)-1) * 0x40)) + +/* UART Interrupt Vector Register */ +#define MCF5206E_UIVR(mbar,n) MCF5206E_REG8(mbar,0x170 + (((n)-1) * 0x40)) + +/* UART Input Port Register (read only) */ +#define MCF5206E_UIP(mbar,n) MCF5206E_REG8(mbar,0x174 + (((n)-1) * 0x40)) +#define MCF5206E_UIP_CTS (0x01) /* Current state of CTS input */ + +/* UART Output Port Bit Set Command (address-triggered command, write) */ +#define MCF5206E_UOP1(mbar,n) MCF5206E_REG8(mbar,0x178 + (((n)-1) * 0x40)) + +/* UART Output Port Bit Reset Command (address-triggered command, write */ +#define MCF5206E_UOP0(mbar,n) MCF5206E_REG8(mbar,0x17C + (((n)-1) * 0x40)) + +/*** M-BUS (I2C) Module -- MCF5206e User's Manual, Chapter 13 ***/ + +/* M-Bus Address Register */ +#define MCF5206E_MADR(mbar) MCF5206E_REG8(mbar, 0x1E0) + +/* M-Bus Frequency Divider Register */ +#define MCF5206E_MFDR(mbar) MCF5206E_REG8(mbar, 0x1E4) + +/* M-Bus Control Register */ +#define MCF5206E_MBCR(mbar) MCF5206E_REG8(mbar, 0x1E8) +#define MCF5206E_MBCR_MEN (0x80) /* M-Bus Enable */ +#define MCF5206E_MBCR_MIEN (0x40) /* M-Bus Interrupt Enable */ +#define MCF5206E_MBCR_MSTA (0x20) /* Master Mode Selection */ +#define MCF5206E_MBCR_MTX (0x10) /* Transmit Mode Selection */ +#define MCF5206E_MBCR_TXAK (0x08) /* Transmit Acknowledge Enable */ +#define MCF5206E_MBCR_RSTA (0x04) /* Repeat Start */ + +/* M-Bus Status Register */ +#define MCF5206E_MBSR(mbar) MCF5206E_REG8(mbar, 0x1EC) +#define MCF5206E_MBSR_MCF (0x80) /* Data Transferring Bit */ +#define MCF5206E_MBSR_MAAS (0x40) /* Addressed as a Slave Bit */ +#define MCF5206E_MBSR_MBB (0x20) /* Bus Busy Bit */ +#define MCF5206E_MBSR_MAL (0x10) /* Arbitration Lost */ +#define MCF5206E_MBSR_SRW (0x04) /* Slave Read/Write */ +#define MCF5206E_MBSR_MIF (0x02) /* MBus Interrupt pending */ +#define MCF5206E_MBSR_RXAK (0x01) /* Received Acknowledge */ + +/* M-Bus Data I/O Register */ +#define MCF5206E_MBDR(mbar) MCF5206E_REG8(mbar, 0x1F0) + +/*** Timer Module -- MCF5206e User's Manual, Chapter 14 ***/ + +/* Timer Mode Register */ +#define MCF5206E_TMR(mbar,n) MCF5206E_REG16(mbar, 0x100 + (((n)-1)*0x20)) +#define MCF5206E_TMR_PS (0xFF00) /* Prescaler Value */ +#define MCF5206E_TMR_PS_S (8) +#define MCF5206E_TMR_CE (0x00C0) /* Capture Edge and Enable + Interrupt */ +#define MCF5206E_TMR_CE_ANY (0x00C0) /* Capture on any edge */ +#define MCF5206E_TMR_CE_FALL (0x0080) /* Capture on falling edge only */ +#define MCF5206E_TMR_CE_RISE (0x0040) /* Capture on rising edge only */ +#define MCF5206E_TMR_CE_NONE (0x0000) /* Disable Interrupt on capture + event */ +#define MCF5206E_TMR_OM (0x0020) /* Output Mode - Toggle output */ +#define MCF5206E_TMR_ORI (0x0010) /* Output Reference Interrupt + Enable */ +#define MCF5206E_TMR_FRR (0x0008) /* Free Run/Restart */ +#define MCF5206E_TMR_ICLK (0x0006) /* Input Clock Source */ +#define MCF5206E_TMR_ICLK_TIN (0x0006) /* TIN pin (falling edge) */ +#define MCF5206E_TMR_ICLK_DIV16 (0x0004) /* Master system clock divided + by 16 */ +#define MCF5206E_TMR_ICLK_MSCLK (0x0002) /* Master System Clock */ +#define MCF5206E_TMR_ICLK_STOP (0x0000) /* Stops counter */ +#define MCF5206E_TMR_RST (0x0001) /* Reset/Enable Timer */ + +/* Timer Reference Register */ +#define MCF5206E_TRR(mbar,n) MCF5206E_REG16(mbar, 0x104 + (((n)-1)*0x20)) + +/* Timer Capture Register */ +#define MCF5206E_TCR(mbar,n) MCF5206E_REG16(mbar, 0x108 + (((n)-1)*0x20)) + +/* Timer Counter Register */ +#define MCF5206E_TCN(mbar,n) MCF5206E_REG16(mbar, 0x10C + (((n)-1)*0x20)) + +/* Timer Event Register */ +#define MCF5206E_TER(mbar,n) MCF5206E_REG8(mbar, 0x111 + (((n)-1)*0x20)) +#define MCF5206E_TER_REF (0x02) /* Output Reference Event */ +#define MCF5206E_TER_CAP (0x01) /* Capture Event */ + + + +#endif + \ No newline at end of file diff --git a/c/src/lib/libcpu/m68k/mcf5206/include/mcfmbus.h b/c/src/lib/libcpu/m68k/mcf5206/include/mcfmbus.h new file mode 100644 index 0000000000..59f38e3945 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/include/mcfmbus.h @@ -0,0 +1,131 @@ +/* MCF5206e MBUS module (I2C bus) driver header file + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * @(#) $Id$ + */ + +#ifndef __MCFBSP_MCFMBUS_H__ +#define __MCFBSP_MCFMBUS_H__ + +#include "mcf5206e.h" +#include "i2c.h" + +/* States of I2C machine */ +typedef enum mcfmbus_i2c_state { + STATE_IDLE, + STATE_ADDR_7, + STATE_ADDR_1_W, + STATE_ADDR_1_R, + STATE_SENDING, + STATE_RECEIVING +} mcfmbus_i2c_state; + +typedef struct mcfmbus { + rtems_unsigned32 base; /* ColdFire internal peripherial base + address */ + enum mcfmbus_i2c_state state;/* State of I2C machine */ + i2c_message *msg; /* Pointer to the first message in transfer */ + int nmsg; /* Number of messages in transfer */ + i2c_message *cmsg; /* Current message */ + int byte; /* Byte number in current message */ + rtems_isr_entry oldisr; /* Old interrupt handler */ + rtems_id sema; /* MBUS semaphore */ + i2c_transfer_done done; /* Transfer done function */ + rtems_unsigned32 done_arg; /* Done function argument */ +} mcfmbus; + +/* mcfmbus_initialize -- + * Initialize ColdFire MBUS I2C bus controller. + * + * PARAMETERS: + * i2c_bus - pointer to the bus descriptor structure + * base - ColdFire internal peripherial base address + * + * RETURNS: + * RTEMS_SUCCESSFUL, or RTEMS error code when initialization failed. + */ +rtems_status_code +mcfmbus_initialize(mcfmbus *i2c_bus, rtems_unsigned32 base); + +/* mcfmbus_select_clock_divider -- + * Select divider for system clock which is used for I2C bus clock + * generation. Not each divider can be selected for I2C bus; this + * function select nearest larger or equal divider, or maximum + * possible divider, if passed value greater. + * + * PARAMETERS: + * i2c_bus - pointer to the bus descriptor structure + * divider - system frequency divider for I2C serial clock. + * + * RETURNS: + * RTEMS_SUCCESSFUL, if operation performed successfully, or + * RTEMS error code when failed. + */ +rtems_status_code +mcfmbus_select_clock_divider(mcfmbus *i2c_bus, int divider); + +/* mcfmbus_i2c_transfer -- + * Initiate multiple-messages transfer over I2C bus via ColdFire MBUS + * controller. + * + * PARAMETERS: + * bus - pointer to MBUS controller descriptor + * nmsg - number of messages + * msg - pointer to messages array + * done - function which is called when transfer is finished + * done_arg - arbitrary argument passed to done funciton + * + * RETURNS: + * RTEMS_SUCCESSFUL if transfer initiated successfully, or error + * code when failed. + */ +rtems_status_code +mcfmbus_i2c_transfer(mcfmbus *bus, int nmsg, i2c_message *msg, + i2c_transfer_done done, rtems_unsigned32 done_arg); + +/* mcfmbus_i2c_done -- + * Close ColdFire MBUS I2C bus controller and release all resources. + * + * PARAMETERS: + * bus - pointer to MBUS controller descriptor + * + * RETURNS: + * RTEMS_SUCCESSFUL, if transfer initiated successfully, or error + * code when failed. + */ +rtems_status_code +mcfmbus_i2c_done(mcfmbus *i2c_bus); + +/* mcfmbus_i2c_interrupt_handler -- + * ColdFire MBUS I2C bus controller interrupt handler. This function + * called from real interrupt handler, and pointer to MBUS descriptor + * structure passed to this function. + * + * PARAMETERS: + * bus - pointert to the bus descriptor structure + * + * RETURNS: + * none + */ +void mcfmbus_i2c_interrupt_handler(mcfmbus *bus); + +/* mcfmbus_poll -- + * MBUS module poll routine; used to poll events when I2C driver + * operates in poll-driven mode. + * + * PARAMETERS: + * none + * + * RETURNS: + * none + */ +void mcfmbus_poll(mcfmbus *bus); + +#endif /* __MCFBSP_MCFMBUS_H__ */ diff --git a/c/src/lib/libcpu/m68k/mcf5206/include/mcfuart.h b/c/src/lib/libcpu/m68k/mcf5206/include/mcfuart.h new file mode 100644 index 0000000000..8c4a94b70c --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/include/mcfuart.h @@ -0,0 +1,113 @@ +/* + * Generic UART Serial driver for Motorola Coldfire processors definitions + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russian Fed. + * Author: Victor V. Vengerov + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * @(#) $Id$ + * + */ + +#ifndef __MCFUART_H__ +#define __MCFUART_H__ + +#include +#include "bsp.h" +#include "mcf5206e.h" + +/* + * The MCF5206e System Clock Frequency; 54MHz default + */ +#ifndef SYSTEM_CLOCK_FREQUENCY +#define SYSTEM_CLOCK_FREQUENCY BSP_SYSTEM_FREQUENCY +#endif + +/* + * The following structure is a descriptor of single UART channel. + * It contains the initialization information about channel and + * current operating values + */ +typedef struct mcfuart { + rtems_unsigned32 chn; /* UART channel number */ + rtems_unsigned8 intvec; /* UART interrupt vector number, or + 0 if polled I/O */ + void *tty; /* termios channel descriptor */ + + volatile const char *tx_buf; /* Transmit buffer from termios */ + volatile rtems_unsigned32 tx_buf_len;/* Transmit buffer length */ + volatile rtems_unsigned32 tx_ptr; /* Index of next char to transmit*/ + rtems_isr_entry old_handler;/* Saved interrupt handler */ + + tcflag_t c_iflag; /* termios input mode flags */ + rtems_boolean parerr_mark_flag; /* Parity error processing + state */ +} mcfuart; + +/* mcfuart_init -- + * This function verifies the input parameters and perform initialization + * of the Motorola Coldfire on-chip UART descriptor structure. + * + */ +rtems_status_code +mcfuart_init(mcfuart *uart, void *tty, rtems_unsigned8 intvec, + rtems_unsigned32 chn); + +/* mcfuart_reset -- + * This function perform the hardware initialization of Motorola + * Coldfire processor on-chip UART controller using parameters + * filled by the mcfuart_init function. + */ +rtems_status_code +mcfuart_reset(mcfuart *uart); + +/* mcfuart_disable -- + * This function disable the operations on Motorola Coldfire UART + * controller + */ +rtems_status_code +mcfuart_disable(mcfuart *uart); + +/* mcfuart_set_attributes -- + * This function parse the termios attributes structure and perform + * the appropriate settings in hardware. + */ +int +mcfuart_set_attributes(mcfuart *mcf, const struct termios *t); + +/* mcfuart_poll_read -- + * This function tried to read character from MCF UART and perform + * error handling. + */ +int +mcfuart_poll_read(mcfuart *uart); + +/* mcfuart_interrupt_write -- + * This function initiate transmitting of the buffer in interrupt mode. + */ +int +mcfuart_interrupt_write(mcfuart *uart, const char *buf, int len); + +/* mcfuart_poll_write -- + * This function transmit buffer byte-by-byte in polling mode. + */ +int +mcfuart_poll_write(mcfuart *uart, const char *buf, int len); + +/* mcfuart_stop_remote_tx -- + * This function stop data flow from remote device. + */ +int +mcfuart_stop_remote_tx(mcfuart *uart); + +/* mcfuart_start_remote_tx -- + * This function resume data flow from remote device. + */ +int +mcfuart_start_remote_tx(mcfuart *uart); + +#endif diff --git a/c/src/lib/libcpu/m68k/mcf5206/mbus/.cvsignore b/c/src/lib/libcpu/m68k/mcf5206/mbus/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/mbus/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libcpu/m68k/mcf5206/mbus/mcfmbus.c b/c/src/lib/libcpu/m68k/mcf5206/mbus/mcfmbus.c new file mode 100644 index 0000000000..00b9a63285 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/mbus/mcfmbus.c @@ -0,0 +1,615 @@ +/* MCF5206e MBUS module (I2C bus) driver + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * @(#) $Id$ + */ + +#include "mcf5206/mcfmbus.h" +#include "mcf5206/mcf5206e.h" +#include "i2c.h" + +/* Events of I2C machine */ +typedef enum i2c_event { + EVENT_NONE, /* Spurious event */ + EVENT_TRANSFER, /* Start new transfer */ + EVENT_NEXTMSG, /* Start processing of next message in transfer */ + EVENT_ACK, /* Sending finished with ACK */ + EVENT_NACK, /* Sending finished with NACK */ + EVENT_TIMEOUT, /* Timeout occured */ + EVENT_DATA_RECV, /* Data received */ + EVENT_ARB_LOST, /* Arbitration lost */ + EVENT_SLAVE /* Addressed as a slave */ +} i2c_event; + +static mcfmbus *mbus; + +/*** Auxillary primitives ***/ + +/* Change state of finite state machine */ +#define next_state(bus,new_state) \ + do { \ + (bus)->state = (new_state); \ + } while (0) + +/* Initiate start condition on the I2C bus */ +#define mcfmbus_start(bus) \ + do { \ + *MCF5206E_MBCR((bus)->base) |= MCF5206E_MBCR_MSTA; \ + } while (0) + +/* Initiate stop condition on the I2C bus */ +#define mcfmbus_stop(bus) \ + do { \ + *MCF5206E_MBCR((bus)->base) &= ~MCF5206E_MBCR_MSTA; \ + } while (0) + +/* Initiate repeat start condition on the I2C bus */ +#define mcfmbus_rstart(bus) \ + do { \ + *MCF5206E_MBCR((bus)->base) |= MCF5206E_MBCR_RSTA; \ + } while (0) + +/* Send byte to the bus */ +#define mcfmbus_send(bus,byte) \ + do { \ + *MCF5206E_MBDR((bus)->base) = (byte); \ + } while (0) + +/* Set transmit mode */ +#define mcfmbus_tx_mode(bus) \ + do { \ + *MCF5206E_MBCR((bus)->base) |= MCF5206E_MBCR_MTX; \ + } while (0) + +/* Set receive mode */ +#define mcfmbus_rx_mode(bus) \ + do { \ + *MCF5206E_MBCR((bus)->base) &= ~MCF5206E_MBCR_MTX; \ + (void)*MCF5206E_MBDR((bus)->base); \ + } while (0) + + +/* Transmit acknowledge when byte received */ +#define mcfmbus_send_ack(bus) \ + do { \ + *MCF5206E_MBCR((bus)->base) &= ~MCF5206E_MBCR_TXAK; \ + } while (0) + +/* DO NOT transmit acknowledge when byte received */ +#define mcfmbus_send_nack(bus) \ + do { \ + *MCF5206E_MBCR((bus)->base) |= MCF5206E_MBCR_TXAK; \ + } while (0) + +#define mcfmbus_error(bus,err_status) \ + do { \ + do { \ + (bus)->cmsg->status = (err_status); \ + (bus)->cmsg++; \ + } while (((bus)->cmsg - (bus)->msg < (bus)->nmsg) && \ + ((bus)->cmsg->flags & I2C_MSG_ERRSKIP)); \ + bus->cmsg--; \ + } while (0) + +/* mcfmbus_get_event -- + * Read MBUS module status register, determine interrupt reason and + * return appropriate event. + * + * PARAMETERS: + * bus - pointer to MBUS module descriptor structure + * + * RETURNS: + * event code + */ +static i2c_event +mcfmbus_get_event(mcfmbus *bus) +{ + i2c_event event; + rtems_unsigned8 status, control; + rtems_interrupt_level level; + rtems_interrupt_disable(level); + status = *MCF5206E_MBSR(bus->base); + control = *MCF5206E_MBCR(bus->base); + if (status & MCF5206E_MBSR_MIF) /* Interrupt occured */ + { + if (status & MCF5206E_MBSR_MAAS) + { + event = EVENT_SLAVE; + *MCF5206E_MBCR(bus->base) = control; /* To clear Addressed As Slave + condition */ + } + else if (status & MCF5206E_MBSR_MAL) /* Arbitration lost */ + { + *MCF5206E_MBSR(bus->base) = status & ~MCF5206E_MBSR_MAL; + event = EVENT_ARB_LOST; + } + else if (control & MCF5206E_MBCR_MTX) /* Trasmit mode */ + { + if (status & MCF5206E_MBSR_RXAK) + event = EVENT_NACK; + else + event = EVENT_ACK; + } + else /* Received */ + { + event = EVENT_DATA_RECV; + } + + /* Clear interrupt condition */ + *MCF5206E_MBSR(bus->base) &= ~MCF5206E_MBSR_MIF; + } + else + { + event = EVENT_NONE; + } + rtems_interrupt_enable(level); + return event; +} + +static void +mcfmbus_machine_error(mcfmbus *bus, i2c_event event) +{ + return; +} + +/* mcfmbus_machine -- + * finite state machine for I2C bus protocol + * + * PARAMETERS: + * bus - pointer to ColdFire MBUS descriptor structure + * event - I2C event + * + * RETURNS: + * none + */ +static void +mcfmbus_machine(mcfmbus *bus, i2c_event event) +{ + rtems_unsigned8 b; + switch (bus->state) + { + case STATE_IDLE: + switch (event) + { + case EVENT_NEXTMSG: /* Start new message processing */ + bus->cmsg++; + /* FALLTHRU */ + + case EVENT_TRANSFER: /* Initiate new transfer */ + if (bus->cmsg - bus->msg >= bus->nmsg) + { + mcfmbus_stop(bus); + next_state(bus, STATE_IDLE); + bus->msg = bus->cmsg = NULL; + bus->nmsg = bus->byte = 0; + bus->done(bus->done_arg); + break; + } + + /* Initiate START or REPEATED START condition on the bus */ + if (event == EVENT_TRANSFER) + { + mcfmbus_start(bus); + } + else /* (event == EVENT_NEXTMSG) */ + { + mcfmbus_rstart(bus); + } + + bus->byte = 0; + mcfmbus_tx_mode(bus); + + /* Initiate slave address sending */ + if (bus->cmsg->flags & I2C_MSG_ADDR_10) + { + i2c_address a = bus->cmsg->addr; + b = 0xf0 | (((a >> 8) & 0x03) << 1); + if (bus->cmsg->flags & I2C_MSG_WR) + { + mcfmbus_send(bus, b); + next_state(bus, STATE_ADDR_1_W); + } + else + { + mcfmbus_send(bus, b | 1); + next_state(bus, STATE_ADDR_1_R); + } + } + else + { + b = (bus->cmsg->addr & ~0x01); + if (!(bus->cmsg->flags & I2C_MSG_WR)) + { + b |= 1; + } + mcfmbus_send(bus, b); + + if (bus->cmsg->flags & I2C_MSG_WR) + { + next_state(bus, STATE_SENDING); + } + else + { + next_state(bus, STATE_ADDR_7); + } + } + break; + + default: + mcfmbus_machine_error(bus, event); + break; + } + break; + + case STATE_ADDR_7: + switch (event) + { + case EVENT_ACK: + mcfmbus_rx_mode(bus); + if (bus->cmsg->len <= 1) + mcfmbus_send_nack(bus); + else + mcfmbus_send_ack(bus); + next_state(bus, STATE_RECEIVING); + break; + + case EVENT_NACK: + mcfmbus_error(bus, I2C_NO_DEVICE); + next_state(bus, STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + break; + + case EVENT_ARB_LOST: + mcfmbus_error(bus, I2C_ARBITRATION_LOST); + next_state(bus, STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + break; + + default: + mcfmbus_machine_error(bus, event); + break; + } + break; + + case STATE_ADDR_1_R: + case STATE_ADDR_1_W: + switch (event) + { + case EVENT_ACK: + { + rtems_unsigned8 b = (bus->cmsg->addr & 0xff); + mcfmbus_send(bus, b); + if (bus->state == STATE_ADDR_1_W) + { + next_state(bus, STATE_SENDING); + } + else + { + i2c_address a; + mcfmbus_rstart(bus); + mcfmbus_tx_mode(bus); + a = bus->cmsg->addr; + b = 0xf0 | (((a >> 8) & 0x03) << 1) | 1; + mcfmbus_send(bus, b); + next_state(bus, STATE_ADDR_7); + } + break; + } + + case EVENT_NACK: + mcfmbus_error(bus, I2C_NO_DEVICE); + next_state(bus, STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + break; + + case EVENT_ARB_LOST: + mcfmbus_error(bus, I2C_ARBITRATION_LOST); + next_state(bus, STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + break; + + default: + mcfmbus_machine_error(bus, event); + break; + } + break; + + case STATE_SENDING: + switch (event) + { + case EVENT_ACK: + if (bus->byte == bus->cmsg->len) + { + next_state(bus, STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + } + else + { + mcfmbus_send(bus, bus->cmsg->buf[bus->byte++]); + next_state(bus, STATE_SENDING); + } + break; + + case EVENT_NACK: + if (bus->byte == 0) + { + mcfmbus_error(bus, I2C_NO_DEVICE); + } + else + { + mcfmbus_error(bus, I2C_NO_ACKNOWLEDGE); + } + next_state(bus, STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + break; + + case EVENT_ARB_LOST: + mcfmbus_error(bus, I2C_ARBITRATION_LOST); + next_state(bus, STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + break; + + default: + mcfmbus_machine_error(bus, event); + break; + + } + break; + + case STATE_RECEIVING: + switch (event) + { + case EVENT_DATA_RECV: + if (bus->cmsg->len - bus->byte <= 2) + { + mcfmbus_send_nack(bus); + if (bus->cmsg->len - bus->byte <= 1) + { + if (bus->cmsg - bus->msg + 1 == bus->nmsg) + mcfmbus_stop(bus); + else + mcfmbus_rstart(bus); + } + } + else + { + mcfmbus_send_ack(bus); + } + bus->cmsg->buf[bus->byte++] = *MCF5206E_MBDR(bus->base); + if (bus->cmsg->len == bus->byte) + { + next_state(bus,STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + } + else + { + next_state(bus,STATE_RECEIVING); + } + break; + + case EVENT_ARB_LOST: + mcfmbus_error(bus, I2C_ARBITRATION_LOST); + next_state(bus, STATE_IDLE); + mcfmbus_machine(bus, EVENT_NEXTMSG); + break; + + default: + mcfmbus_machine_error(bus, event); + break; + } + break; + } +} + +/* mcfmbus_interrupt_handler -- + * MBUS module interrupt handler routine + * + * PARAMETERS: + * vector - interrupt vector number (not used) + * + * RETURNS: + * none + */ +rtems_isr +mcfmbus_interrupt_handler(rtems_vector_number vector) +{ + i2c_event event; + event = mcfmbus_get_event(mbus); + mcfmbus_machine(mbus, event); +} + +/* mcfmbus_poll -- + * MBUS module poll routine; used to poll events when I2C driver + * operates in poll-driven mode. + * + * PARAMETERS: + * none + * + * RETURNS: + * none + */ +void +mcfmbus_poll(mcfmbus *bus) +{ + i2c_event event; + event = mcfmbus_get_event(bus); + if (event != EVENT_NONE) + mcfmbus_machine(bus, event); +} + +/* mcfmbus_select_clock_divider -- + * Select divider for system clock which is used for I2C bus clock + * generation. Not each divider can be selected for I2C bus; this + * function select nearest larger or equal divider. + * + * PARAMETERS: + * i2c_bus - pointer to the bus descriptor structure + * divider - system frequency divider for I2C serial clock. + * RETURNS: + * RTEMS_SUCCESSFUL, if operation performed successfully, or + * RTEMS error code when failed. + */ +rtems_status_code +mcfmbus_select_clock_divider(mcfmbus *i2c_bus, int divider) +{ + int i; + int mbc; + struct { + int divider; + int mbc; + } dividers[] ={ + { 20, 0x20 }, { 22, 0x21 }, { 24, 0x22 }, { 26, 0x23 }, + { 28, 0x00 }, { 30, 0x01 }, { 32, 0x25 }, { 34, 0x02 }, + { 36, 0x26 }, { 40, 0x03 }, { 44, 0x04 }, { 48, 0x05 }, + { 56, 0x06 }, { 64, 0x2a }, { 68, 0x07 }, { 72, 0x2B }, + { 80, 0x08 }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A }, + { 112, 0x2E }, { 128, 0x0B }, { 144, 0x0C }, { 160, 0x0D }, + { 192, 0x0E }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 }, + { 288, 0x10 }, { 320, 0x11 }, { 384, 0x12 }, { 448, 0x36 }, + { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x15 }, + { 768, 0x16 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B }, + { 1152, 0x18 }, { 1280, 0x19 }, { 1536, 0x1A }, { 1792, 0x3E }, + { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D }, + { 3072, 0x1E }, { 3840, 0x1F } + }; + + if (i2c_bus == NULL) + return RTEMS_INVALID_ADDRESS; + + for (i = 0, mbc = -1; i < sizeof(dividers)/sizeof(dividers[0]); i++) + { + mbc = dividers[i].mbc; + if (dividers[i].divider >= divider) + { + break; + } + } + *MCF5206E_MFDR(i2c_bus->base) = mbc; + return RTEMS_SUCCESSFUL; +} + +/* mcfmbus_initialize -- + * Initialize ColdFire MBUS I2C bus controller. + * + * PARAMETERS: + * i2c_bus - pointer to the bus descriptor structure + * base - ColdFire internal peripherial base address + * + * RETURNS: + * RTEMS_SUCCESSFUL, or RTEMS error code when initialization failed. + */ +rtems_status_code +mcfmbus_initialize(mcfmbus *i2c_bus, rtems_unsigned32 base) +{ + rtems_interrupt_level level; + rtems_status_code sc; + + if (mbus != NULL) /* Check if already initialized */ + return RTEMS_RESOURCE_IN_USE; + + if (i2c_bus == NULL) + return RTEMS_INVALID_ADDRESS; + + + i2c_bus->base = base; + i2c_bus->state = STATE_IDLE; + i2c_bus->msg = NULL; + i2c_bus->cmsg = NULL; + i2c_bus->nmsg = 0; + i2c_bus->byte = 0; + + sc = rtems_interrupt_catch( + mcfmbus_interrupt_handler, + 24 + ((*MCF5206E_ICR(base, MCF5206E_INTR_MBUS) & MCF5206E_ICR_IL) >> + MCF5206E_ICR_IL_S), + &i2c_bus->oldisr + ); + if (sc != RTEMS_SUCCESSFUL) + return sc; + + mbus = i2c_bus; + rtems_interrupt_disable(level); + *MCF5206E_IMR(base) &= ~MCF5206E_INTR_BIT(MCF5206E_INTR_MBUS); + *MCF5206E_MBCR(base) = 0; + *MCF5206E_MBSR(base) = 0; + *MCF5206E_MBDR(base) = 0x1F; /* Maximum possible divider is 3840 */ + *MCF5206E_MBCR(base) = MCF5206E_MBCR_MEN | MCF5206E_MBCR_MIEN; + rtems_interrupt_enable(level); + + return RTEMS_SUCCESSFUL; +} + +/* mcfmbus_i2c_transfer -- + * Initiate multiple-messages transfer over I2C bus via ColdFire MBUS + * controller. + * + * PARAMETERS: + * bus - pointer to MBUS controller descriptor + * nmsg - number of messages + * msg - pointer to messages array + * done - function which is called when transfer is finished + * done_arg - arbitrary argument passed to done funciton + * + * RETURNS: + * RTEMS_SUCCESSFUL if transfer initiated successfully, or error + * code when failed. + */ +rtems_status_code +mcfmbus_i2c_transfer(mcfmbus *bus, int nmsg, i2c_message *msg, + i2c_transfer_done done, rtems_unsigned32 done_arg) +{ + if (bus != mbus) + return RTEMS_NOT_CONFIGURED; + + bus->done = done; + bus->done_arg = done_arg; + bus->cmsg = bus->msg = msg; + bus->nmsg = nmsg; + bus->byte = 0; + bus->state = STATE_IDLE; + mcfmbus_machine(bus, EVENT_TRANSFER); + return RTEMS_SUCCESSFUL; +} + + +/* mcfmbus_i2c_done -- + * Close ColdFire MBUS I2C bus controller and release all resources. + * + * PARAMETERS: + * bus - pointer to MBUS controller descriptor + * + * RETURNS: + * RTEMS_SUCCESSFUL, if transfer initiated successfully, or error + * code when failed. + */ +rtems_status_code +mcfmbus_i2c_done(mcfmbus *i2c_bus) +{ + rtems_status_code sc; + rtems_unsigned32 base; + if (mbus == NULL) + return RTEMS_NOT_CONFIGURED; + + if (mbus != i2c_bus) + return RTEMS_INVALID_ADDRESS; + + base = i2c_bus->base; + + *MCF5206E_IMR(base) |= MCF5206E_INTR_BIT(MCF5206E_INTR_MBUS); + *MCF5206E_MBCR(base) = 0; + + sc = rtems_interrupt_catch( + i2c_bus->oldisr, + 24 + ((*MCF5206E_ICR(base, MCF5206E_INTR_MBUS) & MCF5206E_ICR_IL) >> + MCF5206E_ICR_IL_S), + NULL + ); + return sc; +} diff --git a/c/src/lib/libcpu/m68k/mcf5206/timer/.cvsignore b/c/src/lib/libcpu/m68k/mcf5206/timer/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/timer/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libcpu/m68k/mcf5206/timer/timer.c b/c/src/lib/libcpu/m68k/mcf5206/timer/timer.c new file mode 100644 index 0000000000..82464753be --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/timer/timer.c @@ -0,0 +1,175 @@ +/* + * Timer Init + * + * This module initializes TIMER 2 for on the MCF5206E for benchmarks. + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov + * + * Based on work: + * Author: + * David Fiddes, D.J@fiddes.surfaid.org + * http://www.calm.hw.ac.uk/davidf/coldfire/ + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include "mcf5206/mcf5206e.h" + +#define TRR2_VAL 65530 + +rtems_unsigned32 Timer_interrupts; + +rtems_boolean Timer_driver_Find_average_overhead; + +/* External assembler interrupt handler routine */ +extern rtems_isr timerisr(rtems_vector_number vector); + + +/* Timer_initialize -- + * Initialize timer 2 for accurate time measurement. + * + * PARAMETERS: + * none + * + * RETURNS: + * none + */ +void +Timer_initialize(void) +{ + /* Catch timer2 interrupts */ + set_vector(timerisr, BSP_INTVEC_TIMER2, 0); + + /* Initialize interrupts for timer2 */ + *MCF5206E_ICR(MBAR, MCF5206E_INTR_TIMER_2) = + MCF5206E_ICR_AVEC | + ((BSP_INTLVL_TIMER2 << MCF5206E_ICR_IL_S) & MCF5206E_ICR_IL) | + ((BSP_INTPRIO_TIMER2 << MCF5206E_ICR_IP_S) & MCF5206E_ICR_IP); + + /* Enable interrupts from timer2 */ + *MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(MCF5206E_INTR_TIMER_2); + + /* Reset Timer */ + *MCF5206E_TMR(MBAR, 2) = MCF5206E_TMR_RST; + *MCF5206E_TMR(MBAR, 2) = MCF5206E_TMR_ICLK_STOP; + *MCF5206E_TMR(MBAR, 2) = MCF5206E_TMR_RST; + *MCF5206E_TCN(MBAR, 2) = 0; /* Zero timer counter */ + Timer_interrupts = 0; /* Clear timer ISR counter */ + *MCF5206E_TER(MBAR, 2) = MCF5206E_TER_REF | MCF5206E_TER_CAP; /*clr pend*/ + *MCF5206E_TRR(MBAR, 2) = TRR2_VAL - 1; + *MCF5206E_TMR(MBAR, 2) = + (((BSP_SYSTEM_FREQUENCY / 1000000) << MCF5206E_TMR_PS_S) & + MCF5206E_TMR_PS) | + MCF5206E_TMR_CE_NONE | MCF5206E_TMR_ORI | MCF5206E_TMR_FRR | + MCF5206E_TMR_RST; + *MCF5206E_TMR(MBAR, 2) |= MCF5206E_TMR_ICLK_MSCLK; +} + +/* + * The following controls the behavior of Read_timer(). + * + * FIND_AVG_OVERHEAD * instructs the routine to return the "raw" count. + * + * AVG_OVEREHAD is the overhead for starting and stopping the timer. It + * is usually deducted from the number returned. + * + * LEAST_VALID is the lowest number this routine should trust. Numbers + * below this are "noise" and zero is returned. + */ + +#define AVG_OVERHEAD 0 /* It typically takes 2.0 microseconds */ + /* (Y countdowns) to start/stop the timer. */ + /* This value is in microseconds. */ +#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */ + +/* Read_timer -- + * Read timer value in microsecond units since timer start. + * + * PARAMETERS: + * none + * + * RETURNS: + * number of microseconds since timer has been started + */ +int +Read_timer( void ) +{ + rtems_unsigned16 clicks; + rtems_unsigned32 total; + + /* + * Read the timer and see how many clicks it has been since counter + * rolled over. + */ + clicks = *MCF5206E_TCN(MBAR, 2); + + /* Stop Timer... */ + *MCF5206E_TMR(MBAR, 2) = MCF5206E_TMR_ICLK_STOP | + MCF5206E_TMR_RST; + + /* + * Total is calculated by taking into account the number of timer + * overflow interrupts since the timer was initialized and clicks + * since the last interrupts. + */ + + total = (Timer_interrupts * TRR2_VAL) + clicks; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in XXX microsecond units */ + + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + + /* + * Return the count in microseconds + */ + return (total - AVG_OVERHEAD); +} + + +/* Empty_function -- + * Empty function call used in loops to measure basic cost of looping + * in Timing Test Suite. + * + * PARAMETERS: + * none + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +rtems_status_code +Empty_function(void) +{ + return RTEMS_SUCCESSFUL; +} + +/* Set_find_average_overhead -- + * This routine is invoked by the "Check Timer" (tmck) test in the + * RTEMS Timing Test Suite. It makes the Read_timer routine not + * subtract the overhead required to initialize and read the benchmark + * timer. + * + * PARAMETERS: + * find_flag - boolean flag, TRUE if overhead must not be subtracted. + * + * RETURNS: + * none + */ +void +Set_find_average_overhead(rtems_boolean find_flag) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libcpu/m68k/mcf5206/timer/timerisr.S b/c/src/lib/libcpu/m68k/mcf5206/timer/timerisr.S new file mode 100644 index 0000000000..e1a10d19bc --- /dev/null +++ b/c/src/lib/libcpu/m68k/mcf5206/timer/timerisr.S @@ -0,0 +1,49 @@ +/* + * Handle MCF5206 TIMER2 interrupts. + * + * All code in this routine is pure overhead which can perturb the + * accuracy of RTEMS' timing test suite. + * + * See also: Read_timer() + * + * To reduce overhead this is best to be the "rawest" hardware interupt + * handler you can write. This should be the only interrupt which can + * occur during the measured time period. + * + * An external counter, Timer_interrupts, is incremented. + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov + * + * This file based on work: + * Author: + * David Fiddes, D.J@fiddes.surfaid.org + * http://www.calm.hw.ac.uk/davidf/coldfire/ + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include "asm.h" +#include "bsp.h" +#include "mcf5206/mcf5206e.h" + +BEGIN_CODE + PUBLIC(timerisr) +SYM(timerisr): + move.l a0, a7@- + move.l #MCF5206E_TER(BSP_MEM_ADDR_IMM, 2), a0 + move.b # (MCF5206E_TER_REF + MCF5206E_TER_CAP), (a0) + addq.l #1,SYM(Timer_interrupts) | increment timer value + move.l a7@+, a0 + rte +END_CODE +END -- cgit v1.2.3